diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml index b47b73150..c4307fadf 100644 --- a/.github/workflows/integrate.yaml +++ b/.github/workflows/integrate.yaml @@ -9,6 +9,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - run: ./scripts/generate-locale-config.sh + - run: git diff --exit-code - run: cat .github/workflows/versions.env >> $GITHUB_ENV - uses: subosito/flutter-action@v2 with: @@ -88,7 +90,7 @@ jobs: # Pangea# build_debug_ios: - runs-on: macos-latest + runs-on: macos-15 steps: - uses: actions/checkout@v4 - run: cat .github/workflows/versions.env >> $GITHUB_ENV diff --git a/.github/workflows/versions.env b/.github/workflows/versions.env index d15056774..16765a3a5 100644 --- a/.github/workflows/versions.env +++ b/.github/workflows/versions.env @@ -1,2 +1,2 @@ -FLUTTER_VERSION=3.27.3 +FLUTTER_VERSION=3.27.4 JAVA_VERSION=17 diff --git a/.gitignore b/.gitignore index 288c868bf..fb99f07cd 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,307 @@ scripts/.credentials olm needed-translations.txt -.venv \ No newline at end of file +.venv + +docs/node_modules/.package-lock.json +docs/node_modules/.bin/detect-libc +docs/node_modules/.bin/jiti +docs/node_modules/.bin/tailwindcss +docs/node_modules/@parcel/watcher/binding.gyp +docs/node_modules/@parcel/watcher/index.d.ts +docs/node_modules/@parcel/watcher/index.js +docs/node_modules/@parcel/watcher/index.js.flow +docs/node_modules/@parcel/watcher/LICENSE +docs/node_modules/@parcel/watcher/package.json +docs/node_modules/@parcel/watcher/README.md +docs/node_modules/@parcel/watcher/wrapper.js +docs/node_modules/@parcel/watcher/scripts/build-from-source.js +docs/node_modules/@parcel/watcher/src/Backend.cc +docs/node_modules/@parcel/watcher/src/Backend.hh +docs/node_modules/@parcel/watcher/src/binding.cc +docs/node_modules/@parcel/watcher/src/Debounce.cc +docs/node_modules/@parcel/watcher/src/Debounce.hh +docs/node_modules/@parcel/watcher/src/DirTree.cc +docs/node_modules/@parcel/watcher/src/DirTree.hh +docs/node_modules/@parcel/watcher/src/Event.hh +docs/node_modules/@parcel/watcher/src/Glob.cc +docs/node_modules/@parcel/watcher/src/Glob.hh +docs/node_modules/@parcel/watcher/src/PromiseRunner.hh +docs/node_modules/@parcel/watcher/src/Signal.hh +docs/node_modules/@parcel/watcher/src/Watcher.cc +docs/node_modules/@parcel/watcher/src/Watcher.hh +docs/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc +docs/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh +docs/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc +docs/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh +docs/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc +docs/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh +docs/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc +docs/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh +docs/node_modules/@parcel/watcher/src/unix/fts.cc +docs/node_modules/@parcel/watcher/src/unix/legacy.cc +docs/node_modules/@parcel/watcher/src/wasm/include.h +docs/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc +docs/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh +docs/node_modules/@parcel/watcher/src/watchman/BSER.cc +docs/node_modules/@parcel/watcher/src/watchman/BSER.hh +docs/node_modules/@parcel/watcher/src/watchman/IPC.hh +docs/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc +docs/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh +docs/node_modules/@parcel/watcher/src/windows/win_utils.cc +docs/node_modules/@parcel/watcher/src/windows/win_utils.hh +docs/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc +docs/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh +docs/node_modules/@parcel/watcher-linux-x64-glibc/LICENSE +docs/node_modules/@parcel/watcher-linux-x64-glibc/package.json +docs/node_modules/@parcel/watcher-linux-x64-glibc/README.md +docs/node_modules/@parcel/watcher-linux-x64-glibc/watcher.node +docs/node_modules/@tailwindcss/cli/LICENSE +docs/node_modules/@tailwindcss/cli/package.json +docs/node_modules/@tailwindcss/cli/README.md +docs/node_modules/@tailwindcss/cli/dist/index.mjs +docs/node_modules/@tailwindcss/node/LICENSE +docs/node_modules/@tailwindcss/node/package.json +docs/node_modules/@tailwindcss/node/README.md +docs/node_modules/@tailwindcss/node/dist/esm-cache.loader.d.mts +docs/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs +docs/node_modules/@tailwindcss/node/dist/index.d.mts +docs/node_modules/@tailwindcss/node/dist/index.d.ts +docs/node_modules/@tailwindcss/node/dist/index.js +docs/node_modules/@tailwindcss/node/dist/index.mjs +docs/node_modules/@tailwindcss/node/dist/require-cache.d.ts +docs/node_modules/@tailwindcss/node/dist/require-cache.js +docs/node_modules/@tailwindcss/oxide/index.d.ts +docs/node_modules/@tailwindcss/oxide/index.js +docs/node_modules/@tailwindcss/oxide/LICENSE +docs/node_modules/@tailwindcss/oxide/package.json +docs/node_modules/@tailwindcss/oxide-linux-x64-gnu/LICENSE +docs/node_modules/@tailwindcss/oxide-linux-x64-gnu/package.json +docs/node_modules/@tailwindcss/oxide-linux-x64-gnu/README.md +docs/node_modules/@tailwindcss/oxide-linux-x64-gnu/tailwindcss-oxide.linux-x64-gnu.node +docs/node_modules/braces/index.js +docs/node_modules/braces/LICENSE +docs/node_modules/braces/package.json +docs/node_modules/braces/README.md +docs/node_modules/braces/lib/compile.js +docs/node_modules/braces/lib/constants.js +docs/node_modules/braces/lib/expand.js +docs/node_modules/braces/lib/parse.js +docs/node_modules/braces/lib/stringify.js +docs/node_modules/braces/lib/utils.js +docs/node_modules/detect-libc/.npmignore +docs/node_modules/detect-libc/LICENSE +docs/node_modules/detect-libc/package.json +docs/node_modules/detect-libc/README.md +docs/node_modules/detect-libc/bin/detect-libc.js +docs/node_modules/detect-libc/lib/detect-libc.js +docs/node_modules/enhanced-resolve/LICENSE +docs/node_modules/enhanced-resolve/package.json +docs/node_modules/enhanced-resolve/README.md +docs/node_modules/enhanced-resolve/types.d.ts +docs/node_modules/enhanced-resolve/lib/AliasFieldPlugin.js +docs/node_modules/enhanced-resolve/lib/AliasPlugin.js +docs/node_modules/enhanced-resolve/lib/AppendPlugin.js +docs/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js +docs/node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js +docs/node_modules/enhanced-resolve/lib/ConditionalPlugin.js +docs/node_modules/enhanced-resolve/lib/createInnerContext.js +docs/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js +docs/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js +docs/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js +docs/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js +docs/node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js +docs/node_modules/enhanced-resolve/lib/FileExistsPlugin.js +docs/node_modules/enhanced-resolve/lib/forEachBail.js +docs/node_modules/enhanced-resolve/lib/getInnerRequest.js +docs/node_modules/enhanced-resolve/lib/getPaths.js +docs/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js +docs/node_modules/enhanced-resolve/lib/index.js +docs/node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js +docs/node_modules/enhanced-resolve/lib/JoinRequestPlugin.js +docs/node_modules/enhanced-resolve/lib/LogInfoPlugin.js +docs/node_modules/enhanced-resolve/lib/MainFieldPlugin.js +docs/node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js +docs/node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js +docs/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js +docs/node_modules/enhanced-resolve/lib/NextPlugin.js +docs/node_modules/enhanced-resolve/lib/ParsePlugin.js +docs/node_modules/enhanced-resolve/lib/PnpPlugin.js +docs/node_modules/enhanced-resolve/lib/Resolver.js +docs/node_modules/enhanced-resolve/lib/ResolverFactory.js +docs/node_modules/enhanced-resolve/lib/RestrictionsPlugin.js +docs/node_modules/enhanced-resolve/lib/ResultPlugin.js +docs/node_modules/enhanced-resolve/lib/RootsPlugin.js +docs/node_modules/enhanced-resolve/lib/SelfReferencePlugin.js +docs/node_modules/enhanced-resolve/lib/SymlinkPlugin.js +docs/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js +docs/node_modules/enhanced-resolve/lib/TryNextPlugin.js +docs/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js +docs/node_modules/enhanced-resolve/lib/UseFilePlugin.js +docs/node_modules/enhanced-resolve/lib/util/entrypoints.js +docs/node_modules/enhanced-resolve/lib/util/identifier.js +docs/node_modules/enhanced-resolve/lib/util/module-browser.js +docs/node_modules/enhanced-resolve/lib/util/path.js +docs/node_modules/enhanced-resolve/lib/util/process-browser.js +docs/node_modules/fill-range/index.js +docs/node_modules/fill-range/LICENSE +docs/node_modules/fill-range/package.json +docs/node_modules/fill-range/README.md +docs/node_modules/graceful-fs/clone.js +docs/node_modules/graceful-fs/graceful-fs.js +docs/node_modules/graceful-fs/legacy-streams.js +docs/node_modules/graceful-fs/LICENSE +docs/node_modules/graceful-fs/package.json +docs/node_modules/graceful-fs/polyfills.js +docs/node_modules/graceful-fs/README.md +docs/node_modules/is-extglob/index.js +docs/node_modules/is-extglob/LICENSE +docs/node_modules/is-extglob/package.json +docs/node_modules/is-extglob/README.md +docs/node_modules/is-glob/index.js +docs/node_modules/is-glob/LICENSE +docs/node_modules/is-glob/package.json +docs/node_modules/is-glob/README.md +docs/node_modules/is-number/index.js +docs/node_modules/is-number/LICENSE +docs/node_modules/is-number/package.json +docs/node_modules/is-number/README.md +docs/node_modules/jiti/LICENSE +docs/node_modules/jiti/package.json +docs/node_modules/jiti/README.md +docs/node_modules/jiti/dist/babel.cjs +docs/node_modules/jiti/dist/jiti.cjs +docs/node_modules/jiti/lib/jiti-cli.mjs +docs/node_modules/jiti/lib/jiti-hooks.mjs +docs/node_modules/jiti/lib/jiti-native.mjs +docs/node_modules/jiti/lib/jiti-register.d.mts +docs/node_modules/jiti/lib/jiti-register.mjs +docs/node_modules/jiti/lib/jiti.cjs +docs/node_modules/jiti/lib/jiti.d.cts +docs/node_modules/jiti/lib/jiti.d.mts +docs/node_modules/jiti/lib/jiti.mjs +docs/node_modules/jiti/lib/types.d.ts +docs/node_modules/lightningcss/LICENSE +docs/node_modules/lightningcss/package.json +docs/node_modules/lightningcss/README.md +docs/node_modules/lightningcss/node/ast.d.ts +docs/node_modules/lightningcss/node/ast.js.flow +docs/node_modules/lightningcss/node/browserslistToTargets.js +docs/node_modules/lightningcss/node/composeVisitors.js +docs/node_modules/lightningcss/node/flags.js +docs/node_modules/lightningcss/node/index.d.ts +docs/node_modules/lightningcss/node/index.js +docs/node_modules/lightningcss/node/index.js.flow +docs/node_modules/lightningcss/node/index.mjs +docs/node_modules/lightningcss/node/targets.d.ts +docs/node_modules/lightningcss/node/targets.js.flow +docs/node_modules/lightningcss-linux-x64-gnu/LICENSE +docs/node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node +docs/node_modules/lightningcss-linux-x64-gnu/package.json +docs/node_modules/lightningcss-linux-x64-gnu/README.md +docs/node_modules/micromatch/index.js +docs/node_modules/micromatch/LICENSE +docs/node_modules/micromatch/package.json +docs/node_modules/micromatch/README.md +docs/node_modules/mri/index.d.ts +docs/node_modules/mri/license.md +docs/node_modules/mri/package.json +docs/node_modules/mri/readme.md +docs/node_modules/mri/lib/index.js +docs/node_modules/mri/lib/index.mjs +docs/node_modules/node-addon-api/common.gypi +docs/node_modules/node-addon-api/except.gypi +docs/node_modules/node-addon-api/index.js +docs/node_modules/node-addon-api/LICENSE.md +docs/node_modules/node-addon-api/napi-inl.deprecated.h +docs/node_modules/node-addon-api/napi-inl.h +docs/node_modules/node-addon-api/napi.h +docs/node_modules/node-addon-api/node_addon_api.gyp +docs/node_modules/node-addon-api/node_api.gyp +docs/node_modules/node-addon-api/noexcept.gypi +docs/node_modules/node-addon-api/nothing.c +docs/node_modules/node-addon-api/package-support.json +docs/node_modules/node-addon-api/package.json +docs/node_modules/node-addon-api/README.md +docs/node_modules/node-addon-api/tools/check-napi.js +docs/node_modules/node-addon-api/tools/clang-format.js +docs/node_modules/node-addon-api/tools/conversion.js +docs/node_modules/node-addon-api/tools/eslint-format.js +docs/node_modules/node-addon-api/tools/README.md +docs/node_modules/picocolors/LICENSE +docs/node_modules/picocolors/package.json +docs/node_modules/picocolors/picocolors.browser.js +docs/node_modules/picocolors/picocolors.d.ts +docs/node_modules/picocolors/picocolors.js +docs/node_modules/picocolors/README.md +docs/node_modules/picocolors/types.d.ts +docs/node_modules/picomatch/CHANGELOG.md +docs/node_modules/picomatch/index.js +docs/node_modules/picomatch/LICENSE +docs/node_modules/picomatch/package.json +docs/node_modules/picomatch/README.md +docs/node_modules/picomatch/lib/constants.js +docs/node_modules/picomatch/lib/parse.js +docs/node_modules/picomatch/lib/picomatch.js +docs/node_modules/picomatch/lib/scan.js +docs/node_modules/picomatch/lib/utils.js +docs/node_modules/tailwindcss/index.css +docs/node_modules/tailwindcss/LICENSE +docs/node_modules/tailwindcss/package.json +docs/node_modules/tailwindcss/preflight.css +docs/node_modules/tailwindcss/README.md +docs/node_modules/tailwindcss/theme.css +docs/node_modules/tailwindcss/utilities.css +docs/node_modules/tailwindcss/dist/chunk-AZANAYY2.mjs +docs/node_modules/tailwindcss/dist/chunk-CH45MXZF.mjs +docs/node_modules/tailwindcss/dist/chunk-V2K3XTS4.mjs +docs/node_modules/tailwindcss/dist/colors-b_6i0Oi7.d.ts +docs/node_modules/tailwindcss/dist/colors.d.mts +docs/node_modules/tailwindcss/dist/colors.d.ts +docs/node_modules/tailwindcss/dist/colors.js +docs/node_modules/tailwindcss/dist/colors.mjs +docs/node_modules/tailwindcss/dist/default-theme.d.mts +docs/node_modules/tailwindcss/dist/default-theme.d.ts +docs/node_modules/tailwindcss/dist/default-theme.js +docs/node_modules/tailwindcss/dist/default-theme.mjs +docs/node_modules/tailwindcss/dist/flatten-color-palette.d.mts +docs/node_modules/tailwindcss/dist/flatten-color-palette.d.ts +docs/node_modules/tailwindcss/dist/flatten-color-palette.js +docs/node_modules/tailwindcss/dist/flatten-color-palette.mjs +docs/node_modules/tailwindcss/dist/lib.d.mts +docs/node_modules/tailwindcss/dist/lib.d.ts +docs/node_modules/tailwindcss/dist/lib.js +docs/node_modules/tailwindcss/dist/lib.mjs +docs/node_modules/tailwindcss/dist/plugin.d.mts +docs/node_modules/tailwindcss/dist/plugin.d.ts +docs/node_modules/tailwindcss/dist/plugin.js +docs/node_modules/tailwindcss/dist/plugin.mjs +docs/node_modules/tailwindcss/dist/resolve-config-BIFUA2FY.d.ts +docs/node_modules/tailwindcss/dist/resolve-config-QUZ9b-Gn.d.mts +docs/node_modules/tailwindcss/dist/types-B254mqw1.d.mts +docs/node_modules/tapable/LICENSE +docs/node_modules/tapable/package.json +docs/node_modules/tapable/README.md +docs/node_modules/tapable/tapable.d.ts +docs/node_modules/tapable/lib/AsyncParallelBailHook.js +docs/node_modules/tapable/lib/AsyncParallelHook.js +docs/node_modules/tapable/lib/AsyncSeriesBailHook.js +docs/node_modules/tapable/lib/AsyncSeriesHook.js +docs/node_modules/tapable/lib/AsyncSeriesLoopHook.js +docs/node_modules/tapable/lib/AsyncSeriesWaterfallHook.js +docs/node_modules/tapable/lib/Hook.js +docs/node_modules/tapable/lib/HookCodeFactory.js +docs/node_modules/tapable/lib/HookMap.js +docs/node_modules/tapable/lib/index.js +docs/node_modules/tapable/lib/MultiHook.js +docs/node_modules/tapable/lib/SyncBailHook.js +docs/node_modules/tapable/lib/SyncHook.js +docs/node_modules/tapable/lib/SyncLoopHook.js +docs/node_modules/tapable/lib/SyncWaterfallHook.js +docs/node_modules/tapable/lib/util-browser.js +docs/node_modules/to-regex-range/index.js +docs/node_modules/to-regex-range/LICENSE +docs/node_modules/to-regex-range/package.json +docs/node_modules/to-regex-range/README.md +docs/package.json +docs/package-lock.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ca25bbd2..2cbc85fd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,78 @@ +## v1.25.0 +- feat: Display all push rules and allow to enable disable them (Krille) +- feat: Inspect and delete push rules (Krille) +- feat: Pick share keys with (Krille) +- feat: Select share keys with property in security settings (Krille) +- feat: Use dynamic gradient for chat bubbles (Krille) +- fix: Image search rendering problem (krille-chan) +- build: Add locale config for android (krille-chan) +- build: Add missing permissions (Krille) +- build: Automerge weblate PRs (Krille) +- build: Fix ios debug build (krille-chan) +- build: Follow up auto merge weblate (Krille) +- build: remove weblate auto merge (Krille) +- build: Switch to flutter_shortcuts_new (Krille) +- build: Update dependencies for flutter (Krille) +- build: Update dependencies to remove more flutter android v1 references (Krille) +- build: Update fcm_shared_isolate (Krille) +- build: Update flutter web uild (Krille) +- build: Update flutter_olm to 2.0.0 (Krille) +- build: Update gradle version (Krille) +- build: Update native_imaging (Krille) +- build: Update PAT (Krille) +- build: Update to flutter 3.27.4 (Krille) +- build: Update weblate auto merge (Krille) +- build: Upgrade gradle (Krille) +- chore: Add explanation for PlayStore Safety Standards (Krille) +- chore: Add medium font (Krille) +- chore: Add start to ordered list (Krille) +- chore: Add tooltip to links in html (Krille) +- chore: Adjust button icon colors (Krille) +- chore: Adjust design of adaptive dialogs (krille-chan) +- chore: Adjust navrail design (Krille) +- chore: Adjust share scaffold dialog design (Krille) +- chore: Better connection status indicator (Krille) +- chore: Design adjustments (krille-chan) +- chore: Make login with matrix id more prominent again (krille-chan) +- chore: Message bubble color follow up (krille-chan) +- chore: Remove gradle workaround (Krille) +- chore: Slightly adjust welcome screen (Krille) +- chore: Use UbuntuMono (Krille) +- docs: Fix snap store icon (krille-chan) +- refactor: Display navigationrail in settings page (krille-chan) +- refactor: Follow up fix types in localization files (Krille) +- refactor: Improve sso login UX on web (krille-chan) +- refactor: Migrate to maintained badge package (Krille) +- refactor: Migrate uni_links to app_links (Krille) +- refactor: New html rendering (Krille) +- refactor: Remove broken callkeep implementation (Krille) +- refactor: Remove unused class (krille-chan) +- refactor: Switch to maintained qr code package (Krille) +- refactor: Switch to ubuntu font (krille-chan) +- refactor: Update arb file types (Krille) +- Translated using Weblate (Arabic) (Rex_sa) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Catalan) (fadelkon) +- Translated using Weblate (Chinese (Simplified Han script)) (玖然) +- Translated using Weblate (Chinese (Simplified Han script)) (大王叫我来巡山) +- Translated using Weblate (Chinese (Traditional Han script)) (玖然) +- Translated using Weblate (Croatian) (Milo Ivir) +- Translated using Weblate (Dutch) (Jelv) +- Translated using Weblate (Estonian) (Priit Jõerüüt) +- Translated using Weblate (Galician) (josé m) +- Translated using Weblate (German) (Christian) +- Translated using Weblate (German) (Ettore Atalan) +- Translated using Weblate (German) (Jana) +- Translated using Weblate (Indonesian) (Linerly) +- Translated using Weblate (Irish) (Aindriú Mac Giolla Eoin) +- Translated using Weblate (Italian) (Angelo Schirinzi) +- Translated using Weblate (Korean) (kdh8219) +- Translated using Weblate (Latvian) (Edgars Andersons) +- Translated using Weblate (Slovak) (Anonymous) +- Translated using Weblate (Spanish) (Alfredo Sola) +- Translated using Weblate (Ukrainian) (Bezruchenko Simon) +- Translated using Weblate (Ukrainian) (Ihor Hordiichuk) + ## v1.24.0 - build: Add missing libssl library (krille-chan) - build: Update dart_webrtc package (Krille) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index aea5e1922..50d5b3c94 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ android:requestLegacyExternalStorage="true" android:allowBackup="false" android:fullBackupContent="false" + android:localeConfig="@xml/locale_config" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/build.gradle b/android/build.gradle index 2cc11e9ac..6b092c036 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,30 +7,14 @@ allprojects { rootProject.buildDir = '../build' -// Workaround for building with Flutter 3.24 -// See: https://github.com/flutter/flutter/issues/153281#issuecomment-2292201697 subprojects { - afterEvaluate { project -> - if (project.extensions.findByName("android") != null) { - Integer pluginCompileSdk = project.android.compileSdk - if (pluginCompileSdk != null && pluginCompileSdk < 31) { - project.logger.error( - "Warning: Overriding compileSdk version in Flutter plugin: " - + project.name - + " from " - + pluginCompileSdk - + " to 31 (to work around https://issuetracker.google.com/issues/199180389)." - + "\nIf there is not a new version of " + project.name + ", consider filing an issue against " - + project.name - + " to increase their compileSdk to the latest (otherwise try updating to the latest version)." - ) - project.android { - compileSdk 31 - } - } + beforeEvaluate { project -> + if (project.name == "text_to_speech") { + project.buildscript.dependencies.classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10" } } } + subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(":app") diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index cc5527d78..aeaff6f86 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index eea4c7e1d..c8b30c01b 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -30,8 +30,8 @@ buildscript { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.1.3" apply false - id "org.jetbrains.kotlin.android" version "2.0.21" apply false + id "com.android.application" version "7.3.1" apply false + id "org.jetbrains.kotlin.android" version "2.1.10" apply false // id "com.google.gms.google-services" version "4.3.8" apply false } diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 363501a0d..f62d38097 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3202,6 +3202,10 @@ "crossVerifiedDevicesIfEnabled": "Cross verified devices if enabled", "crossVerifiedDevices": "Cross verified devices", "verifiedDevicesOnly": "Verified devices only", + "takeAPhoto": "Take a photo", + "recordAVideo": "Record a video", + "optionalMessage": "(Optional) message...", + "notSupportedOnThisDevice": "Not supported on this device", "accountInformation": "Account information", "addGroupDescription": "Add a chat description", "addNewFriend": "Add new friend", @@ -4858,4 +4862,4 @@ "downloadGboard": "Download Gboard", "autocorrectNotAvailable": "Unfortunately your platform is not currently supported for this feature. Stay tuned for further development!", "pleaseUpdateApp": "Please update the app to continue." -} \ No newline at end of file +} diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index 84f97078d..b830b98ec 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -5457,4 +5457,4 @@ }, "downloadGboard": "Descargar Gboard", "autocorrectNotAvailable": "Desafortunadamente, tu plataforma no es compatible actualmente con esta función. ¡Mantente atento a futuros desarrollos!" -} \ No newline at end of file +} diff --git a/assets/l10n/intl_et.arb b/assets/l10n/intl_et.arb index c12a98511..278c6069e 100644 --- a/assets/l10n/intl_et.arb +++ b/assets/l10n/intl_et.arb @@ -1306,7 +1306,7 @@ "type": "String", "placeholders": {} }, - "openCamera": "Pildista", + "openCamera": "Ava kaamera", "@openCamera": { "type": "String", "placeholders": {} @@ -3333,5 +3333,13 @@ "crossVerifiedDevices": "Risttunnustatud seadmeid", "@crossVerifiedDevices": {}, "verifiedDevicesOnly": "Vaid verifitseeritud seadmeid", - "@verifiedDevicesOnly": {} + "@verifiedDevicesOnly": {}, + "recordAVideo": "Salvesta video", + "@recordAVideo": {}, + "takeAPhoto": "Pildista", + "@takeAPhoto": {}, + "optionalMessage": "Sõnum (kui soovid lisada)...", + "@optionalMessage": {}, + "notSupportedOnThisDevice": "See pole antud seadmes toetatud", + "@notSupportedOnThisDevice": {} } diff --git a/assets/l10n/intl_ga.arb b/assets/l10n/intl_ga.arb index 4b9fd02e5..d6eaa58a0 100644 --- a/assets/l10n/intl_ga.arb +++ b/assets/l10n/intl_ga.arb @@ -3338,5 +3338,13 @@ "shareKeysWithDescription": "Cad iad na gléasanna ar cheart muinín a chur iontu ionas gur féidir leo do chuid teachtaireachtaí a léamh i gcomhráite criptithe?", "@shareKeysWithDescription": {}, "verifiedDevicesOnly": "Gléasanna fíoraithe amháin", - "@verifiedDevicesOnly": {} + "@verifiedDevicesOnly": {}, + "takeAPhoto": "Glac grianghraf", + "@takeAPhoto": {}, + "recordAVideo": "Taifead físeán", + "@recordAVideo": {}, + "notSupportedOnThisDevice": "Ní thacaítear leis ar an ngléas seo", + "@notSupportedOnThisDevice": {}, + "optionalMessage": "Teachtaireacht (Roghnach)…", + "@optionalMessage": {} } diff --git a/assets/l10n/intl_gl.arb b/assets/l10n/intl_gl.arb index ee638f4d5..1c5fc9533 100644 --- a/assets/l10n/intl_gl.arb +++ b/assets/l10n/intl_gl.arb @@ -3333,5 +3333,13 @@ "type": "String" } } - } + }, + "optionalMessage": "(Optativo) mensaxe…", + "@optionalMessage": {}, + "notSupportedOnThisDevice": "Non compatible co dispositivo", + "@notSupportedOnThisDevice": {}, + "takeAPhoto": "Facer foto", + "@takeAPhoto": {}, + "recordAVideo": "Gravar vídeo", + "@recordAVideo": {} } diff --git a/assets/l10n/intl_pl.arb b/assets/l10n/intl_pl.arb index 68fb59f71..d08857a26 100644 --- a/assets/l10n/intl_pl.arb +++ b/assets/l10n/intl_pl.arb @@ -1376,7 +1376,7 @@ "type": "String", "placeholders": {} }, - "synchronizingPleaseWait": "Synchronizacja… Proszę czekać.", + "synchronizingPleaseWait": "Synchronizowanie… Proszę czekać.", "@synchronizingPleaseWait": { "type": "String", "placeholders": {} @@ -3182,5 +3182,160 @@ } }, "kickUserDescription": "Użytkownik jest wyrzucony z czatu, ale nie zbanowany. Do czatu publicznego może dołączyć ponownie.", - "@kickUserDescription": {} + "@kickUserDescription": {}, + "appWantsToUseForLogin": "Użyj serwera '{server}' do zalogowania się", + "@appWantsToUseForLogin": { + "type": "String", + "placeholders": { + "server": { + "type": "String" + } + } + }, + "appWantsToUseForLoginDescription": "Niniejszym zezwalasz aplikacji i witrynie na udostępnianie informacji o sobie.", + "@appWantsToUseForLoginDescription": {}, + "open": "Otwórz", + "@open": {}, + "contentNotificationSettings": "Ustawienia powiadomień o treści", + "@contentNotificationSettings": {}, + "generalNotificationSettings": "Ogólne ustawienia powiadomień", + "@generalNotificationSettings": {}, + "roomNotificationSettings": "Ustawienia powiadomień w pokoju", + "@roomNotificationSettings": {}, + "userSpecificNotificationSettings": "Ustawienia powiadomień dla użytkownika", + "@userSpecificNotificationSettings": {}, + "otherNotificationSettings": "Inne ustawienia powiadomień", + "@otherNotificationSettings": {}, + "notificationRuleContainsUserName": "Zawiera nazwę użytkownika", + "@notificationRuleContainsUserName": {}, + "notificationRuleContainsUserNameDescription": "Powiadamia użytkownika kiedy wiadomość zawiera jego nazwę.", + "@notificationRuleContainsUserNameDescription": {}, + "notificationRuleMaster": "Wycisz wszystkie powiadomienia", + "@notificationRuleMaster": {}, + "notificationRuleMasterDescription": "Zastępuje wszystkie inne reguły i wyłącza wszystkie powiadomienia.", + "@notificationRuleMasterDescription": {}, + "notificationRuleSuppressNotices": "Stłum automatyczne wiadomości", + "@notificationRuleSuppressNotices": {}, + "notificationRuleSuppressNoticesDescription": "Tłumi powiadomienia z automatycznych klientów, takich jak boty.", + "@notificationRuleSuppressNoticesDescription": {}, + "notificationRuleInviteForMe": "Zaproszenia", + "@notificationRuleInviteForMe": {}, + "notificationRuleInviteForMeDescription": "Powiadamia o zaproszeniach do pokoju.", + "@notificationRuleInviteForMeDescription": {}, + "notificationRuleMemberEvent": "Zdarzenia członków pokoju", + "@notificationRuleMemberEvent": {}, + "notificationRuleMemberEventDescription": "Tłumi powiadomienia o zmianach członkostwa w pokoju.", + "@notificationRuleMemberEventDescription": {}, + "notificationRuleIsUserMention": "Wzmianki", + "@notificationRuleIsUserMention": {}, + "notificationRuleIsUserMentionDescription": "Powiadamia o byciu wzmiankowanym w wiadomości.", + "@notificationRuleIsUserMentionDescription": {}, + "notificationRuleContainsDisplayName": "Zawiera nazwę wyświetlaną", + "@notificationRuleContainsDisplayName": {}, + "notificationRuleContainsDisplayNameDescription": "Powiadamia osobę o wiadomości zawierającej jej nazwę wyświetlaną.", + "@notificationRuleContainsDisplayNameDescription": {}, + "notificationRuleIsRoomMention": "Wzmianki pokoju", + "@notificationRuleIsRoomMention": {}, + "notificationRuleIsRoomMentionDescription": "Powiadamia o wzmiankowaniu całego pokoju.", + "@notificationRuleIsRoomMentionDescription": {}, + "notificationRuleRoomnotif": "Powiadomienia w pokoju", + "@notificationRuleRoomnotif": {}, + "notificationRuleRoomnotifDescription": "Powiadamia o wiadomości zawierającej „@room”.", + "@notificationRuleRoomnotifDescription": {}, + "notificationRuleTombstone": "Nagrobki", + "@notificationRuleTombstone": {}, + "notificationRuleTombstoneDescription": "Powiadamia o komunikatach dezaktywacji pokojów.", + "@notificationRuleTombstoneDescription": {}, + "notificationRuleReaction": "Reakcje", + "@notificationRuleReaction": {}, + "notificationRuleReactionDescription": "Tłumi powiadomienia o reakcjach.", + "@notificationRuleReactionDescription": {}, + "notificationRuleSuppressEdits": "Stłum edycje", + "@notificationRuleSuppressEdits": {}, + "notificationRuleSuppressEditsDescription": "Tłumi powiadomienia o edycjach wiadomości.", + "@notificationRuleSuppressEditsDescription": {}, + "notificationRuleCall": "Połączenia", + "@notificationRuleCall": {}, + "notificationRuleRoomServerAclDescription": "Wyłącza powiadomienia dla list kontroli dostępu (ACL) serwerów pokojów.", + "@notificationRuleRoomServerAclDescription": {}, + "notificationRuleRoomServerAcl": "Listo kontroli dostępu serwerów pokojów", + "@notificationRuleRoomServerAcl": {}, + "notificationRuleEncryptedRoomOneToOne": "Szyfrowane pokoje jeden na jeden", + "@notificationRuleEncryptedRoomOneToOne": {}, + "notificationRuleCallDescription": "Powiadamia o przychodzących połączeniach.", + "@notificationRuleCallDescription": {}, + "notificationRuleRoomOneToOne": "Pokoje jeden na jeden", + "@notificationRuleRoomOneToOne": {}, + "notificationRuleRoomOneToOneDescription": "Powiadamia o wiadomościach w pokojach jeden na jeden (one-to-one).", + "@notificationRuleRoomOneToOneDescription": {}, + "notificationRuleMessage": "Wiadomości", + "@notificationRuleMessage": {}, + "unknownPushRule": "Nieznana reguła: '{rule}'", + "@unknownPushRule": { + "type": "String", + "placeholders": { + "rule": { + "type": "String" + } + } + }, + "notificationRuleEncryptedRoomOneToOneDescription": "Powiadamia o wiadomościach w szyfrowanych pokojach jeden na jeden (one-to-one).", + "@notificationRuleEncryptedRoomOneToOneDescription": {}, + "notificationRuleEncrypted": "Zaszyfrowane pokoje", + "@notificationRuleEncrypted": {}, + "notificationRuleJitsi": "Jitsi", + "@notificationRuleJitsi": {}, + "notificationRuleServerAcl": "Stłum komunikaty o listach kontroli dostępu serwerów pokojów", + "@notificationRuleServerAcl": {}, + "notificationRuleJitsiDescription": "Powiadamia o komunikatach widżetów Jitsi.", + "@notificationRuleJitsiDescription": {}, + "notificationRuleMessageDescription": "Powiadamia o ogólnych wiadomościach.", + "@notificationRuleMessageDescription": {}, + "notificationRuleEncryptedDescription": "Powiadamia o wiadomościach w zaszyfrowanych pokojach.", + "@notificationRuleEncryptedDescription": {}, + "notificationRuleServerAclDescription": "Tłumi powiadomienia o komunikatach o listach kontroli dostępu (ACL) serwerów pokojów.", + "@notificationRuleServerAclDescription": {}, + "newChatRequest": "📩 Nowa prośba o czat", + "@newChatRequest": {}, + "synchronizingPleaseWaitCounter": " Synchronizowanie… ({percentage}%)", + "@synchronizingPleaseWaitCounter": { + "type": "String", + "placeholders": { + "percentage": { + "type": "String" + } + } + }, + "waitingForServer": "Oczekiwanie na serwer...", + "@waitingForServer": {}, + "appIntroduction": "FluffyChat umożliwia czatowanie ze znajomymi za pośrednictwem różnych komunikatorów. Dowiedz się więcej na stronie https://matrix.org lub kliknij na *Kontynuuj*.", + "@appIntroduction": {}, + "previous": "Poprzedni", + "@previous": {}, + "otherPartyNotLoggedIn": "Druga strona nie jest obecnie zalogowana i dlatego nie może odbierać wiadomości!", + "@otherPartyNotLoggedIn": {}, + "deletePushRuleCanNotBeUndone": "Jeśli skasujesz to ustawienie powiadomień, nie będzie się dało tego cofnąć.", + "@deletePushRuleCanNotBeUndone": {}, + "more": "Więcej", + "@more": {}, + "shareKeysWith": "Udostępnij klucze...", + "@shareKeysWith": {}, + "crossVerifiedDevicesIfEnabled": "Urządzenia zweryfikowane krzyżowo, jeśli włączone", + "@crossVerifiedDevicesIfEnabled": {}, + "crossVerifiedDevices": "Urządzenia zweryfikowane krzyżowo", + "@crossVerifiedDevices": {}, + "takeAPhoto": "Zrób zdjęcie", + "@takeAPhoto": {}, + "recordAVideo": "Nagraj film", + "@recordAVideo": {}, + "optionalMessage": "(Opcjonalna) wiadomość...", + "@optionalMessage": {}, + "verifiedDevicesOnly": "Tylko zweryfikowane urządzenia", + "@verifiedDevicesOnly": {}, + "shareKeysWithDescription": "Które urządzenia powinny być zaufane, aby mogły odczytywać Twoje wiadomości w zaszyfrowanych czatach?", + "@shareKeysWithDescription": {}, + "allDevices": "Wszystkie urządzenia", + "@allDevices": {}, + "notSupportedOnThisDevice": "Niewspierane na tym urządzeniu", + "@notSupportedOnThisDevice": {} } diff --git a/assets/l10n/intl_sk.arb b/assets/l10n/intl_sk.arb index bed4ebf5b..946f6a62c 100644 --- a/assets/l10n/intl_sk.arb +++ b/assets/l10n/intl_sk.arb @@ -1,1462 +1,2117 @@ { - "@@locale": "sk", - "@@last_modified": "2021-08-14 12:41:09.879987", - "about": "O aplikácii", - "@about": { - "type": "String", - "placeholders": {} - }, - "accept": "Prijať", - "@accept": { - "type": "String", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} prijali pozvánku", - "@acceptedTheInvitation": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } + "@@locale": "sk", + "@@last_modified": "2021-08-14 12:41:09.879987", + "about": "O aplikácii", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Prijať", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} prijali pozvánku", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Účet", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} aktivovali koncové šifrovanie", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "admin": "Administrátor", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "Ktokoľvek sa môže pripojiť", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "archive": "Archivovať", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Môžu sa pripojiť hostia", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Ste si istí?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Na overenie tejto osoby, prosím zadajte prístupovu frázu k \"bezpečému úložisku\" alebo \"klúč na obnovu\".", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Akcepovať žiadosť o verifikáciu od {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banFromChat": "Zabanovať z chatu", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Zabanovaný", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} zabanoval {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Zakázať zariadenie", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "cancel": "Zrušiť", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} si zmenili svôj avatar", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} zmenili popis chatu na: „{description}“", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} zmenili meno chatu na: „{chatname}“", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} zmenili nastavenie oprávnení chatu", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} si zmenili prezývku na: {displayname}", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} zmenili prístupové práva pre hosťov", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} zmenili prístupové práva pro hosťov na: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} zmenili nastavenie viditelnosti histórie chatu", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} zmenili nastavenie viditelnosti histórie chatu na: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} zmenili nastavenie pravidiel pripojenia", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} zmenili nastavenie pravidiel pripojenia na: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} si zmenili profilový obrázok", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} zmenili nastavenie aliasov chatu", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} zmenili odkaz k pozvánke do miestnosti", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeTheHomeserver": "Zmeniť použitý server", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Zmena štýlu", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Zmeniť názov skupiny", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Šifrovanie bolo poškodené", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Chat", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Podrobnosti o chate", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Vyberte si silné heslo", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "close": "Zavrieť", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Porovnajte a uistite sa, že nasledujúce emotikony sa zhodujú na oboch zariadeniach:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Porovnajte a uistite sa, že nasledujúce čísla sa zhodujú na oboch zariadeniach:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "confirm": "Potvrdiť", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Pripojiť", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontakt bol pozvaný do skupiny", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Skopírované do schránky", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopírovať", + "@copy": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Nebolo možné dešifrovať správu: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} účastníkov", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Vytvoriť", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} založili chat", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "currentlyActive": "Momentálne prítomní", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Tmavá", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}.{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day}.{month}.{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "delete": "Odstrániť", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Odstrániť správu", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "device": "Zariadenie", + "@device": { + "type": "text", + "placeholders": {} + }, + "devices": "Zariadenia", + "@devices": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Prezývka bola zmenená", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Stiahnuť súbor", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Zmeniť prezývku", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Emotikon už existuje!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Nesprávné označenie emotikonu!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Nastavenie emotikonov", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Kód emotikonu", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Musíte zvoliť kód emotikonu a obrázok!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Prázdny chat", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Šifrovanie už nebude možné vypnúť. Ste si tým istí?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encryption": "Šifrovanie", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Šifrovanie nie je aktívne", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Zadajte svoj homeserver", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "fileName": "Názov súboru", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "forward": "Preposlať", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Od pripojenia", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Od pozvania", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "Skupina", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Skupina je verejná", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Skupina s {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Hostia sú zakázaní", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Hostia sa môžu pripojiť", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} vzal späť pozvánku pre {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Pomoc", + "@help": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identita", + "@identity": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Nesprávna prístupová fráza alebo kľúč na obnovenie", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Pozvať kontakt", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Pozvať kontakt do {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Pozvanie", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} pozvali {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Len pozvaní používatelia", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} vás pozval na FluffyChat.\n1. Nainštalujte si FluffyChat: https://fluffychat.im\n2. Zaregistrujte sa alebo sa prihláste\n3. Otvorte odkaz na pozvánku: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "píše…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} sa pripojili do chatu", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "kicked": "{username} vyhodili {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} vyhodili a zabanovali {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Vyhodiť z chatu", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Naposledy prítomní: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "leave": "Opustiť", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Opustili chat", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Licencia", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Svetlá", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Načítať ďalších {count} účastníkov", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Načítava sa… Čakajte prosím.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Načítať viac…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Prihlásiť sa", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Prihlásenie k {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "Odhlásiť sa", + "@logout": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderátor", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Stlmiť chat", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Prosím berte na vedomie, že na koncové šifrovanie zatiaľ potrebujete Pantalaimon.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Nová správa v FluffyChate", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nová žiadosť o verifikáciu!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Nenašli sa žiadne emotikony. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Zdá sa, že nemáte žiadne služby Googlu v telefóne. To je dobré rozhodnutie pre vaše súkromie! Ak chcete dostávať push notifikácie vo FluffyChat, odporúčame používať microG: https://microg.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Žiadne", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Chýba povolenie", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Nenašli sa žiadne miestnosti…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "ok": "ok", + "@ok": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Online záloha kľúčov je zapnutá", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Och! Niečo sa pokazilo…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Na prečítanie správy otvorte aplikáciu", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Otvoriť fotoaparát", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "prístupová fráza alebo kľúč na obnovenie", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Heslo", + "@password": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Vybrať obrázok", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "play": "Prehrať {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseEnterYourPassword": "Prosím zadajte svoje heslo", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Zadajte svoje používateľské meno", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Verejné miestnosti", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "recording": "Nahrávam", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} odstránili udalosť", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "reject": "Odmietnuť", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} odmietli pozvánku", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Vrátiť sa", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Odstrániť", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Odstráňiť všetky ostatné zariadenia", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Odstánené užívateľom {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Odstráňiť zariadenie", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Odblokovať", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Zobraziť formátovaný obsah", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "reply": "Odpovedať", + "@reply": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Vyžiadať si povolenie", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Miestnosť bola upgradeovaná", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Videné užívateľom {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "send": "Odoslať", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Odoslať správu", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Odoslať súbor", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Odoslať obrázok", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} poslali súbor", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} poslali zvukovú nahrávku", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} poslali obrázok", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} poslali nálepku", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} poslali video", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setInvitationLink": "Nastaviť odkaz pre pozvánku", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Nastaviť status", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Nastavenia", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Zdieľať", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} zdieľa lokáciu", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "skip": "Preskočiť", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Zdrojový kód", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Ako sa dnes máte?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Odoslať", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Systémová farba", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Sa nezhodujú", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Zhodujú sa", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Skúsiť znova odoslať", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} odbanovali {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Odblokovať zariadenie", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Neznáme zariadenie", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Neznámy šifrovací algoritmus", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Neznáma udalosť „{type}“", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Zrušiť stlmenie chatu", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, other{{unreadCount} neprečítaných chatov}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} a {count} dalších píšu…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} a {username2} píšu…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} píše…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} opustili chat", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Užívateľské meno", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} poslali udalosť {type}", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verify": "Overiť", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Spustiť verifikáciu", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Verifikácia bola úspešná!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Verifikujem protiľahlý účet", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videohovor", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Viditeľnosť histórie chatu", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Viditeľné pre všetkých účastníkov", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Viditeľné pre každého", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Hlasová správa", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Čaká sa, kým partner prijme požiadavku…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Čaká sa, kým partner prijme emotikon…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Čaká sa na to, kým partner prijme čísla…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Pozadie", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Kto môže vstúpiť do tejto skupiny", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Napísať správu…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Áno", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Vy", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Už sa nezúčastňujete tohto chatu", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Máte zablokovaný prístup k tomuto chatu", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "people": "Ľudia", + "@people": { + "type": "text", + "placeholders": {} + }, + "chats": "Čety", + "@chats": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Zmeniť heslo", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Zmeniť názov zariadenia", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "Domovský server podporuje verzie špecifikácie:\n{serverVersions}\nAle táto aplikácie podporuje iba {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "answeredTheCall": "{senderName} prevzal hovor", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "sendAudio": "Poslať zvuk", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Pridať email", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "appLock": "Uzamknutie aplikácie", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "security": "Bezpečnosť", + "@security": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Nahlásiť správu", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Poslať nálepku", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Verzia miestnosti", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Poslať správy", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Pripojiť sa k miestnosti", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Nastaviť úroveň oprávnení", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "Server podporuje tieto typy prihlásenia:\n{serverVersions}\nAle táto aplikácia podporuje iba:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "chatBackup": "Záloha chatov", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Pridať do priestoru", + "@addToSpace": {}, + "cantOpenUri": "Nemožno otvoriť identifikátor prostriedku {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "yourChatBackupHasBeenSetUp": "Záloha vašich chatov bola nastavená.", + "@yourChatBackupHasBeenSetUp": {}, + "repeatPassword": "Zopakujte heslo", + "@repeatPassword": {}, + "all": "Všetky", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Všetky chaty", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Ste si istí, že sa chcete odhlásiť?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Odoslať pri vstupe", + "@sendOnEnter": {}, + "ignoredUsers": "Ignorovaní užívatelia", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignorovať", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "search": "Hľadať", + "@search": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Poslať ako text", + "@sendAsText": { + "type": "text" + }, + "sendOriginal": "Poslať originál", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Poslať video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "importNow": "Importovať teraz", + "@importNow": {}, + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@jumpToLastReadMessage": {}, + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "@commandHint_cuddle": {}, + "@widgetVideo": {}, + "@dismiss": {}, + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "@reportErrorDescription": {}, + "@directChats": { + "type": "text", + "placeholders": {} + }, + "@addAccount": {}, + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "@chatHasBeenAddedToThisSpace": {}, + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "@unsupportedAndroidVersion": {}, + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "@widgetJitsi": {}, + "@messageType": {}, + "@indexedDbErrorLong": {}, + "@oneClientLoggedOut": {}, + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "@startFirstChat": {}, + "@callingAccount": {}, + "@setColorTheme": {}, + "@nextAccount": {}, + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "@warning": { + "type": "text", + "placeholders": {} + }, + "@allSpaces": {}, + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "@user": {}, + "@youAcceptedTheInvitation": {}, + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "@banUserDescription": {}, + "@widgetEtherpad": {}, + "@removeDevicesDescription": {}, + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "@tryAgain": {}, + "@blocked": { + "type": "text", + "placeholders": {} + }, + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "@unbanUserDescription": {}, + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "@youRejectedTheInvitation": {}, + "@otherCallingPermissions": {}, + "@messagesStyle": {}, + "@link": {}, + "@widgetUrlError": {}, + "@emailOrUsername": {}, + "@newSpaceDescription": {}, + "@chatDescription": {}, + "@callingAccountDetails": {}, + "@next": { + "type": "text", + "placeholders": {} + }, + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "@enterSpace": {}, + "@encryptThisChat": {}, + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "@previousAccount": {}, + "@reopenChat": {}, + "@pleaseEnterRecoveryKey": {}, + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "@no": { + "type": "text", + "placeholders": {} + }, + "@widgetNameError": {}, + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "@unpin": { + "type": "text", + "placeholders": {} + }, + "@addToBundle": {}, + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "@addWidget": {}, + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "@noKeyForThisMessage": {}, + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "@reason": { + "type": "text", + "placeholders": {} + }, + "@commandHint_markasgroup": {}, + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "@hydrateTor": {}, + "@pushNotificationsNotAvailable": {}, + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "@storeInAppleKeyChain": {}, + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "@hydrate": {}, + "@invalidServerName": {}, + "@chatPermissions": {}, + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "@sender": {}, + "@storeInAndroidKeystore": {}, + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "@online": { + "type": "text", + "placeholders": {} + }, + "@signInWithPassword": {}, + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "@offensive": { + "type": "text", + "placeholders": {} + }, + "@makeAdminDescription": {}, + "@edit": { + "type": "text", + "placeholders": {} + }, + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "@saveKeyManuallyDescription": {}, + "@editBundlesForAccount": {}, + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "@whyIsThisMessageEncrypted": {}, + "@setChatDescription": {}, + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "@importFromZipFile": {}, + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "@or": { + "type": "text", + "placeholders": {} + }, + "@dehydrateWarning": {}, + "@noOtherDevicesFound": {}, + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "@videoCallsBetaWarning": {}, + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "@participant": { + "type": "text", + "placeholders": {} + }, + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "@fileIsTooBigForServer": {}, + "@homeserver": {}, + "@verified": { + "type": "text", + "placeholders": {} + }, + "@callingPermissions": {}, + "@readUpToHere": {}, + "@start": {}, + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "@register": { + "type": "text", + "placeholders": {} + }, + "@unlockOldMessages": {}, + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "@optionalRedactReason": {}, + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "@dehydrate": {}, + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "@archiveRoomDescription": {}, + "@exportEmotePack": {}, + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "@commandInvalid": { + "type": "text" + }, + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "@newChat": { + "type": "text", + "placeholders": {} + }, + "@notifications": { + "type": "text", + "placeholders": {} + }, + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "@experimentalVideoCalls": {}, + "@pleaseEnterRecoveryKeyDescription": {}, + "@mention": { + "type": "text", + "placeholders": {} + }, + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "@inviteContactToGroupQuestion": {}, + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "@appearOnTopDetails": {}, + "@enterRoom": {}, + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "@reportUser": {}, + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "@confirmEventUnpin": {}, + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "@redactMessageDescription": {}, + "@recoveryKey": {}, + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "@invalidInput": {}, + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "@dehydrateTorLong": {}, + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "@offline": { + "type": "text", + "placeholders": {} + }, + "@doNotShowAgain": {}, + "@report": {}, + "@status": { + "type": "text", + "placeholders": {} + }, + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "@unverified": {}, + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "@serverRequiresEmail": {}, + "@hideUnimportantStateEvents": {}, + "@screenSharingTitle": {}, + "@widgetCustom": {}, + "@addToSpaceDescription": {}, + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "@addChatDescription": {}, + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "@publish": {}, + "@openLinkInBrowser": {}, + "@clearArchive": {}, + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "@messageInfo": {}, + "@disableEncryptionWarning": {}, + "@directChat": {}, + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "@sendTypingNotifications": {}, + "@inviteGroupChat": {}, + "@appearOnTop": {}, + "@invitePrivateChat": {}, + "@foregroundServiceRunning": {}, + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "@voiceCall": {}, + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "@importEmojis": {}, + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "@noChatDescriptionYet": {}, + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "@removeFromBundle": {}, + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "@confirmMatrixId": {}, + "@learnMore": {}, + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "@notAnImage": {}, + "@users": {}, + "@openGallery": {}, + "@chatDescriptionHasBeenChanged": {}, + "@newGroup": {}, + "@bundleName": {}, + "@dehydrateTor": {}, + "@removeFromSpace": {}, + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "@roomUpgradeDescription": {}, + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "@scanQrCode": {}, + "@pleaseEnterANumber": {}, + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "@profileNotFound": {}, + "@jump": {}, + "@groups": { + "type": "text", + "placeholders": {} + }, + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "@sorryThatsNotPossible": {}, + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "@shareInviteLink": {}, + "@commandHint_markasdm": {}, + "@recoveryKeyLost": {}, + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@messages": { + "type": "text", + "placeholders": {} + }, + "@deviceKeys": {}, + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "@setTheme": {}, + "@youJoinedTheChat": {}, + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "@markAsRead": {}, + "@widgetName": {}, + "@errorAddingWidget": {}, + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "@commandHint_hug": {}, + "@replace": {}, + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "@newSpace": {}, + "@emojis": {}, + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "@commandHint_googly": {}, + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "@createGroup": {}, + "@privacy": { + "type": "text", + "placeholders": {} + }, + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "@hydrateTorLong": {}, + "@time": {}, + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "@custom": {}, + "@noBackupWarning": {}, + "@storeInSecureStorageDescription": {}, + "@openChat": {}, + "@kickUserDescription": {}, + "@pin": { + "type": "text", + "placeholders": {} + }, + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "@pinMessage": {}, + "@invite": {}, + "@enableMultiAccounts": {}, + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "@indexedDbErrorTitle": {}, + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@unsupportedAndroidVersionLong": {}, + "@storeSecurlyOnThisDevice": {}, + "@screenSharingDetail": {}, + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "@placeCall": {}, + "@extremeOffensive": { + "type": "text", + "placeholders": {} } - }, - "account": "Účet", - "@account": { - "type": "String", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} aktivovali koncové šifrovanie", - "@activatedEndToEndEncryption": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "admin": "Administrátor", - "@admin": { - "type": "String", - "placeholders": {} - }, - "alias": "alias", - "@alias": { - "type": "String", - "placeholders": {} - }, - "anyoneCanJoin": "Ktokoľvek sa môže pripojiť", - "@anyoneCanJoin": { - "type": "String", - "placeholders": {} - }, - "archive": "Archivovať", - "@archive": { - "type": "String", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Môžu sa pripojiť hostia", - "@areGuestsAllowedToJoin": { - "type": "String", - "placeholders": {} - }, - "areYouSure": "Ste si istí?", - "@areYouSure": { - "type": "String", - "placeholders": {} - }, - "askSSSSSign": "Na overenie tejto osoby, prosím zadajte prístupovu frázu k \"bezpečému úložisku\" alebo \"klúč na obnovu\".", - "@askSSSSSign": { - "type": "String", - "placeholders": {} - }, - "askVerificationRequest": "Akcepovať žiadosť o verifikáciu od {username}?", - "@askVerificationRequest": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "banFromChat": "Zabanovať z chatu", - "@banFromChat": { - "type": "String", - "placeholders": {} - }, - "banned": "Zabanovaný", - "@banned": { - "type": "String", - "placeholders": {} - }, - "bannedUser": "{username} zabanoval {targetName}", - "@bannedUser": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "blockDevice": "Zakázať zariadenie", - "@blockDevice": { - "type": "String", - "placeholders": {} - }, - "cancel": "Zrušiť", - "@cancel": { - "type": "String", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} si zmenili svôj avatar", - "@changedTheChatAvatar": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheChatDescriptionTo": "{username} zmenili popis chatu na: „{description}“", - "@changedTheChatDescriptionTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "description": { - "type": "String" - } - } - }, - "changedTheChatNameTo": "{username} zmenili meno chatu na: „{chatname}“", - "@changedTheChatNameTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "chatname": { - "type": "String" - } - } - }, - "changedTheChatPermissions": "{username} zmenili nastavenie oprávnení chatu", - "@changedTheChatPermissions": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheDisplaynameTo": "{username} si zmenili prezývku na: {displayname}", - "@changedTheDisplaynameTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "displayname": { - "type": "String" - } - } - }, - "changedTheGuestAccessRules": "{username} zmenili prístupové práva pre hosťov", - "@changedTheGuestAccessRules": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheGuestAccessRulesTo": "{username} zmenili prístupové práva pro hosťov na: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "rules": { - "type": "String" - } - } - }, - "changedTheHistoryVisibility": "{username} zmenili nastavenie viditelnosti histórie chatu", - "@changedTheHistoryVisibility": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheHistoryVisibilityTo": "{username} zmenili nastavenie viditelnosti histórie chatu na: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "rules": { - "type": "String" - } - } - }, - "changedTheJoinRules": "{username} zmenili nastavenie pravidiel pripojenia", - "@changedTheJoinRules": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheJoinRulesTo": "{username} zmenili nastavenie pravidiel pripojenia na: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "joinRules": { - "type": "String" - } - } - }, - "changedTheProfileAvatar": "{username} si zmenili profilový obrázok", - "@changedTheProfileAvatar": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheRoomAliases": "{username} zmenili nastavenie aliasov chatu", - "@changedTheRoomAliases": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changedTheRoomInvitationLink": "{username} zmenili odkaz k pozvánke do miestnosti", - "@changedTheRoomInvitationLink": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "changeTheHomeserver": "Zmeniť použitý server", - "@changeTheHomeserver": { - "type": "String", - "placeholders": {} - }, - "changeTheme": "Zmena štýlu", - "@changeTheme": { - "type": "String", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Zmeniť názov skupiny", - "@changeTheNameOfTheGroup": { - "type": "String", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Šifrovanie bolo poškodené", - "@channelCorruptedDecryptError": { - "type": "String", - "placeholders": {} - }, - "chat": "Chat", - "@chat": { - "type": "String", - "placeholders": {} - }, - "chatDetails": "Podrobnosti o chate", - "@chatDetails": { - "type": "String", - "placeholders": {} - }, - "chooseAStrongPassword": "Vyberte si silné heslo", - "@chooseAStrongPassword": { - "type": "String", - "placeholders": {} - }, - "close": "Zavrieť", - "@close": { - "type": "String", - "placeholders": {} - }, - "compareEmojiMatch": "Porovnajte a uistite sa, že nasledujúce emotikony sa zhodujú na oboch zariadeniach:", - "@compareEmojiMatch": { - "type": "String", - "placeholders": {} - }, - "compareNumbersMatch": "Porovnajte a uistite sa, že nasledujúce čísla sa zhodujú na oboch zariadeniach:", - "@compareNumbersMatch": { - "type": "String", - "placeholders": {} - }, - "confirm": "Potvrdiť", - "@confirm": { - "type": "String", - "placeholders": {} - }, - "connect": "Pripojiť", - "@connect": { - "type": "String", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontakt bol pozvaný do skupiny", - "@contactHasBeenInvitedToTheGroup": { - "type": "String", - "placeholders": {} - }, - "copiedToClipboard": "Skopírované do schránky", - "@copiedToClipboard": { - "type": "String", - "placeholders": {} - }, - "copy": "Kopírovať", - "@copy": { - "type": "String", - "placeholders": {} - }, - "couldNotDecryptMessage": "Nebolo možné dešifrovať správu: {error}", - "@couldNotDecryptMessage": { - "type": "String", - "placeholders": { - "error": { - "type": "String" - } - } - }, - "countParticipants": "{count} účastníkov", - "@countParticipants": { - "type": "String", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "create": "Vytvoriť", - "@create": { - "type": "String", - "placeholders": {} - }, - "createdTheChat": "{username} založili chat", - "@createdTheChat": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "currentlyActive": "Momentálne prítomní", - "@currentlyActive": { - "type": "String", - "placeholders": {} - }, - "darkTheme": "Tmavá", - "@darkTheme": { - "type": "String", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "String", - "placeholders": { - "date": { - "type": "String" - }, - "timeOfDay": { - "type": "String" - } - } - }, - "dateWithoutYear": "{day}.{month}", - "@dateWithoutYear": { - "type": "String", - "placeholders": { - "month": { - "type": "String" - }, - "day": { - "type": "String" - } - } - }, - "dateWithYear": "{day}.{month}.{year}", - "@dateWithYear": { - "type": "String", - "placeholders": { - "year": { - "type": "String" - }, - "month": { - "type": "String" - }, - "day": { - "type": "String" - } - } - }, - "delete": "Odstrániť", - "@delete": { - "type": "String", - "placeholders": {} - }, - "deleteMessage": "Odstrániť správu", - "@deleteMessage": { - "type": "String", - "placeholders": {} - }, - "device": "Zariadenie", - "@device": { - "type": "String", - "placeholders": {} - }, - "devices": "Zariadenia", - "@devices": { - "type": "String", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Prezývka bola zmenená", - "@displaynameHasBeenChanged": { - "type": "String", - "placeholders": {} - }, - "downloadFile": "Stiahnuť súbor", - "@downloadFile": { - "type": "String", - "placeholders": {} - }, - "editDisplayname": "Zmeniť prezývku", - "@editDisplayname": { - "type": "String", - "placeholders": {} - }, - "emoteExists": "Emotikon už existuje!", - "@emoteExists": { - "type": "String", - "placeholders": {} - }, - "emoteInvalid": "Nesprávné označenie emotikonu!", - "@emoteInvalid": { - "type": "String", - "placeholders": {} - }, - "emoteSettings": "Nastavenie emotikonov", - "@emoteSettings": { - "type": "String", - "placeholders": {} - }, - "emoteShortcode": "Kód emotikonu", - "@emoteShortcode": { - "type": "String", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Musíte zvoliť kód emotikonu a obrázok!", - "@emoteWarnNeedToPick": { - "type": "String", - "placeholders": {} - }, - "emptyChat": "Prázdny chat", - "@emptyChat": { - "type": "String", - "placeholders": {} - }, - "enableEncryptionWarning": "Šifrovanie už nebude možné vypnúť. Ste si tým istí?", - "@enableEncryptionWarning": { - "type": "String", - "placeholders": {} - }, - "encryption": "Šifrovanie", - "@encryption": { - "type": "String", - "placeholders": {} - }, - "encryptionNotEnabled": "Šifrovanie nie je aktívne", - "@encryptionNotEnabled": { - "type": "String", - "placeholders": {} - }, - "enterYourHomeserver": "Zadajte svoj homeserver", - "@enterYourHomeserver": { - "type": "String", - "placeholders": {} - }, - "fileName": "Názov súboru", - "@fileName": { - "type": "String", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "String", - "placeholders": {} - }, - "forward": "Preposlať", - "@forward": { - "type": "String", - "placeholders": {} - }, - "fromJoining": "Od pripojenia", - "@fromJoining": { - "type": "String", - "placeholders": {} - }, - "fromTheInvitation": "Od pozvania", - "@fromTheInvitation": { - "type": "String", - "placeholders": {} - }, - "group": "Skupina", - "@group": { - "type": "String", - "placeholders": {} - }, - "groupIsPublic": "Skupina je verejná", - "@groupIsPublic": { - "type": "String", - "placeholders": {} - }, - "groupWith": "Skupina s {displayname}", - "@groupWith": { - "type": "String", - "placeholders": { - "displayname": { - "type": "String" - } - } - }, - "guestsAreForbidden": "Hostia sú zakázaní", - "@guestsAreForbidden": { - "type": "String", - "placeholders": {} - }, - "guestsCanJoin": "Hostia sa môžu pripojiť", - "@guestsCanJoin": { - "type": "String", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} vzal späť pozvánku pre {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "help": "Pomoc", - "@help": { - "type": "String", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "String", - "placeholders": {} - }, - "identity": "Identita", - "@identity": { - "type": "String", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Nesprávna prístupová fráza alebo kľúč na obnovenie", - "@incorrectPassphraseOrKey": { - "type": "String", - "placeholders": {} - }, - "inviteContact": "Pozvať kontakt", - "@inviteContact": { - "type": "String", - "placeholders": {} - }, - "inviteContactToGroup": "Pozvať kontakt do {groupName}", - "@inviteContactToGroup": { - "type": "String", - "placeholders": { - "groupName": { - "type": "String" - } - } - }, - "invited": "Pozvanie", - "@invited": { - "type": "String", - "placeholders": {} - }, - "invitedUser": "{username} pozvali {targetName}", - "@invitedUser": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "invitedUsersOnly": "Len pozvaní používatelia", - "@invitedUsersOnly": { - "type": "String", - "placeholders": {} - }, - "inviteText": "{username} vás pozval na FluffyChat.\n1. Nainštalujte si FluffyChat: https://fluffychat.im\n2. Zaregistrujte sa alebo sa prihláste\n3. Otvorte odkaz na pozvánku: {link}", - "@inviteText": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "link": { - "type": "String" - } - } - }, - "isTyping": "píše…", - "@isTyping": { - "type": "String", - "placeholders": {} - }, - "joinedTheChat": "{username} sa pripojili do chatu", - "@joinedTheChat": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "kicked": "{username} vyhodili {targetName}", - "@kicked": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "kickedAndBanned": "{username} vyhodili a zabanovali {targetName}", - "@kickedAndBanned": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "kickFromChat": "Vyhodiť z chatu", - "@kickFromChat": { - "type": "String", - "placeholders": {} - }, - "lastActiveAgo": "Naposledy prítomní: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "String", - "placeholders": { - "localizedTimeShort": { - "type": "String" - } - } - }, - "leave": "Opustiť", - "@leave": { - "type": "String", - "placeholders": {} - }, - "leftTheChat": "Opustili chat", - "@leftTheChat": { - "type": "String", - "placeholders": {} - }, - "license": "Licencia", - "@license": { - "type": "String", - "placeholders": {} - }, - "lightTheme": "Svetlá", - "@lightTheme": { - "type": "String", - "placeholders": {} - }, - "loadCountMoreParticipants": "Načítať ďalších {count} účastníkov", - "@loadCountMoreParticipants": { - "type": "String", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "loadingPleaseWait": "Načítava sa… Čakajte prosím.", - "@loadingPleaseWait": { - "type": "String", - "placeholders": {} - }, - "loadMore": "Načítať viac…", - "@loadMore": { - "type": "String", - "placeholders": {} - }, - "login": "Prihlásiť sa", - "@login": { - "type": "String", - "placeholders": {} - }, - "logInTo": "Prihlásenie k {homeserver}", - "@logInTo": { - "type": "String", - "placeholders": { - "homeserver": { - "type": "String" - } - } - }, - "logout": "Odhlásiť sa", - "@logout": { - "type": "String", - "placeholders": {} - }, - "moderator": "Moderátor", - "@moderator": { - "type": "String", - "placeholders": {} - }, - "muteChat": "Stlmiť chat", - "@muteChat": { - "type": "String", - "placeholders": {} - }, - "needPantalaimonWarning": "Prosím berte na vedomie, že na koncové šifrovanie zatiaľ potrebujete Pantalaimon.", - "@needPantalaimonWarning": { - "type": "String", - "placeholders": {} - }, - "newMessageInFluffyChat": "Nová správa v FluffyChate", - "@newMessageInFluffyChat": { - "type": "String", - "placeholders": {} - }, - "newVerificationRequest": "Nová žiadosť o verifikáciu!", - "@newVerificationRequest": { - "type": "String", - "placeholders": {} - }, - "noEmotesFound": "Nenašli sa žiadne emotikony. 😕", - "@noEmotesFound": { - "type": "String", - "placeholders": {} - }, - "noGoogleServicesWarning": "Zdá sa, že nemáte žiadne služby Googlu v telefóne. To je dobré rozhodnutie pre vaše súkromie! Ak chcete dostávať push notifikácie vo FluffyChat, odporúčame používať microG: https://microg.org/.", - "@noGoogleServicesWarning": { - "type": "String", - "placeholders": {} - }, - "none": "Žiadne", - "@none": { - "type": "String", - "placeholders": {} - }, - "noPermission": "Chýba povolenie", - "@noPermission": { - "type": "String", - "placeholders": {} - }, - "noRoomsFound": "Nenašli sa žiadne miestnosti…", - "@noRoomsFound": { - "type": "String", - "placeholders": {} - }, - "ok": "ok", - "@ok": { - "type": "String", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Online záloha kľúčov je zapnutá", - "@onlineKeyBackupEnabled": { - "type": "String", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Och! Niečo sa pokazilo…", - "@oopsSomethingWentWrong": { - "type": "String", - "placeholders": {} - }, - "openAppToReadMessages": "Na prečítanie správy otvorte aplikáciu", - "@openAppToReadMessages": { - "type": "String", - "placeholders": {} - }, - "openCamera": "Otvoriť fotoaparát", - "@openCamera": { - "type": "String", - "placeholders": {} - }, - "passphraseOrKey": "prístupová fráza alebo kľúč na obnovenie", - "@passphraseOrKey": { - "type": "String", - "placeholders": {} - }, - "password": "Heslo", - "@password": { - "type": "String", - "placeholders": {} - }, - "pickImage": "Vybrať obrázok", - "@pickImage": { - "type": "String", - "placeholders": {} - }, - "play": "Prehrať {fileName}", - "@play": { - "type": "String", - "placeholders": { - "fileName": { - "type": "String" - } - } - }, - "pleaseEnterYourPassword": "Prosím zadajte svoje heslo", - "@pleaseEnterYourPassword": { - "type": "String", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Zadajte svoje používateľské meno", - "@pleaseEnterYourUsername": { - "type": "String", - "placeholders": {} - }, - "publicRooms": "Verejné miestnosti", - "@publicRooms": { - "type": "String", - "placeholders": {} - }, - "recording": "Nahrávam", - "@recording": { - "type": "String", - "placeholders": {} - }, - "redactedAnEvent": "{username} odstránili udalosť", - "@redactedAnEvent": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "reject": "Odmietnuť", - "@reject": { - "type": "String", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} odmietli pozvánku", - "@rejectedTheInvitation": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "rejoin": "Vrátiť sa", - "@rejoin": { - "type": "String", - "placeholders": {} - }, - "remove": "Odstrániť", - "@remove": { - "type": "String", - "placeholders": {} - }, - "removeAllOtherDevices": "Odstráňiť všetky ostatné zariadenia", - "@removeAllOtherDevices": { - "type": "String", - "placeholders": {} - }, - "removedBy": "Odstánené užívateľom {username}", - "@removedBy": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "removeDevice": "Odstráňiť zariadenie", - "@removeDevice": { - "type": "String", - "placeholders": {} - }, - "unbanFromChat": "Odblokovať", - "@unbanFromChat": { - "type": "String", - "placeholders": {} - }, - "renderRichContent": "Zobraziť formátovaný obsah", - "@renderRichContent": { - "type": "String", - "placeholders": {} - }, - "reply": "Odpovedať", - "@reply": { - "type": "String", - "placeholders": {} - }, - "requestPermission": "Vyžiadať si povolenie", - "@requestPermission": { - "type": "String", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Miestnosť bola upgradeovaná", - "@roomHasBeenUpgraded": { - "type": "String", - "placeholders": {} - }, - "seenByUser": "Videné užívateľom {username}", - "@seenByUser": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "send": "Odoslať", - "@send": { - "type": "String", - "placeholders": {} - }, - "sendAMessage": "Odoslať správu", - "@sendAMessage": { - "type": "String", - "placeholders": {} - }, - "sendFile": "Odoslať súbor", - "@sendFile": { - "type": "String", - "placeholders": {} - }, - "sendImage": "Odoslať obrázok", - "@sendImage": { - "type": "String", - "placeholders": {} - }, - "sentAFile": "{username} poslali súbor", - "@sentAFile": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "sentAnAudio": "{username} poslali zvukovú nahrávku", - "@sentAnAudio": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "sentAPicture": "{username} poslali obrázok", - "@sentAPicture": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "sentASticker": "{username} poslali nálepku", - "@sentASticker": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "sentAVideo": "{username} poslali video", - "@sentAVideo": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "setInvitationLink": "Nastaviť odkaz pre pozvánku", - "@setInvitationLink": { - "type": "String", - "placeholders": {} - }, - "setStatus": "Nastaviť status", - "@setStatus": { - "type": "String", - "placeholders": {} - }, - "settings": "Nastavenia", - "@settings": { - "type": "String", - "placeholders": {} - }, - "share": "Zdieľať", - "@share": { - "type": "String", - "placeholders": {} - }, - "sharedTheLocation": "{username} zdieľa lokáciu", - "@sharedTheLocation": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "skip": "Preskočiť", - "@skip": { - "type": "String", - "placeholders": {} - }, - "sourceCode": "Zdrojový kód", - "@sourceCode": { - "type": "String", - "placeholders": {} - }, - "statusExampleMessage": "Ako sa dnes máte?", - "@statusExampleMessage": { - "type": "String", - "placeholders": {} - }, - "submit": "Odoslať", - "@submit": { - "type": "String", - "placeholders": {} - }, - "systemTheme": "Systémová farba", - "@systemTheme": { - "type": "String", - "placeholders": {} - }, - "theyDontMatch": "Sa nezhodujú", - "@theyDontMatch": { - "type": "String", - "placeholders": {} - }, - "theyMatch": "Zhodujú sa", - "@theyMatch": { - "type": "String", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "String", - "placeholders": {} - }, - "tryToSendAgain": "Skúsiť znova odoslať", - "@tryToSendAgain": { - "type": "String", - "placeholders": {} - }, - "unbannedUser": "{username} odbanovali {targetName}", - "@unbannedUser": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "targetName": { - "type": "String" - } - } - }, - "unblockDevice": "Odblokovať zariadenie", - "@unblockDevice": { - "type": "String", - "placeholders": {} - }, - "unknownDevice": "Neznáme zariadenie", - "@unknownDevice": { - "type": "String", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Neznámy šifrovací algoritmus", - "@unknownEncryptionAlgorithm": { - "type": "String", - "placeholders": {} - }, - "unknownEvent": "Neznáma udalosť „{type}“", - "@unknownEvent": { - "type": "String", - "placeholders": { - "type": { - "type": "String" - } - } - }, - "unmuteChat": "Zrušiť stlmenie chatu", - "@unmuteChat": { - "type": "String", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, other{{unreadCount} neprečítaných chatov}}", - "@unreadChats": { - "type": "String", - "placeholders": { - "unreadCount": { - "type": "int" - } - } - }, - "userAndOthersAreTyping": "{username} a {count} dalších píšu…", - "@userAndOthersAreTyping": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "count": { - "type": "int" - } - } - }, - "userAndUserAreTyping": "{username} a {username2} píšu…", - "@userAndUserAreTyping": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "username2": { - "type": "String" - } - } - }, - "userIsTyping": "{username} píše…", - "@userIsTyping": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "userLeftTheChat": "{username} opustili chat", - "@userLeftTheChat": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - } - } - }, - "username": "Užívateľské meno", - "@username": { - "type": "String", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} poslali udalosť {type}", - "@userSentUnknownEvent": { - "type": "String", - "placeholders": { - "username": { - "type": "String" - }, - "type": { - "type": "String" - } - } - }, - "verify": "Overiť", - "@verify": { - "type": "String", - "placeholders": {} - }, - "verifyStart": "Spustiť verifikáciu", - "@verifyStart": { - "type": "String", - "placeholders": {} - }, - "verifySuccess": "Verifikácia bola úspešná!", - "@verifySuccess": { - "type": "String", - "placeholders": {} - }, - "verifyTitle": "Verifikujem protiľahlý účet", - "@verifyTitle": { - "type": "String", - "placeholders": {} - }, - "videoCall": "Videohovor", - "@videoCall": { - "type": "String", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Viditeľnosť histórie chatu", - "@visibilityOfTheChatHistory": { - "type": "String", - "placeholders": {} - }, - "visibleForAllParticipants": "Viditeľné pre všetkých účastníkov", - "@visibleForAllParticipants": { - "type": "String", - "placeholders": {} - }, - "visibleForEveryone": "Viditeľné pre každého", - "@visibleForEveryone": { - "type": "String", - "placeholders": {} - }, - "voiceMessage": "Hlasová správa", - "@voiceMessage": { - "type": "String", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Čaká sa, kým partner prijme požiadavku…", - "@waitingPartnerAcceptRequest": { - "type": "String", - "placeholders": {} - }, - "waitingPartnerEmoji": "Čaká sa, kým partner prijme emotikon…", - "@waitingPartnerEmoji": { - "type": "String", - "placeholders": {} - }, - "waitingPartnerNumbers": "Čaká sa na to, kým partner prijme čísla…", - "@waitingPartnerNumbers": { - "type": "String", - "placeholders": {} - }, - "wallpaper": "Pozadie", - "@wallpaper": { - "type": "String", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Kto môže vstúpiť do tejto skupiny", - "@whoIsAllowedToJoinThisGroup": { - "type": "String", - "placeholders": {} - }, - "writeAMessage": "Napísať správu…", - "@writeAMessage": { - "type": "String", - "placeholders": {} - }, - "yes": "Áno", - "@yes": { - "type": "String", - "placeholders": {} - }, - "you": "Vy", - "@you": { - "type": "String", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Už sa nezúčastňujete tohto chatu", - "@youAreNoLongerParticipatingInThisChat": { - "type": "String", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Máte zablokovaný prístup k tomuto chatu", - "@youHaveBeenBannedFromThisChat": { - "type": "String", - "placeholders": {} - }, - "people": "Ľudia", - "@people": { - "type": "String", - "placeholders": {} - }, - "chats": "Čety", - "@chats": { - "type": "String", - "placeholders": {} - }, - "changePassword": "Zmeniť heslo", - "@changePassword": { - "type": "String", - "placeholders": {} - }, - "changeDeviceName": "Zmeniť názov zariadenia", - "@changeDeviceName": { - "type": "String", - "placeholders": {} - }, - "badServerVersionsException": "Domovský server podporuje verzie špecifikácie:\n{serverVersions}\nAle táto aplikácie podporuje iba {supportedVersions}", - "@badServerVersionsException": { - "type": "String", - "placeholders": { - "serverVersions": { - "type": "String" - }, - "supportedVersions": { - "type": "String" - } - } - }, - "answeredTheCall": "{senderName} prevzal hovor", - "@answeredTheCall": { - "type": "String", - "placeholders": { - "senderName": { - "type": "String" - } - } - }, - "sendAudio": "Poslať zvuk", - "@sendAudio": { - "type": "String", - "placeholders": {} - }, - "addEmail": "Pridať email", - "@addEmail": { - "type": "String", - "placeholders": {} - }, - "appLock": "Uzamknutie aplikácie", - "@appLock": { - "type": "String", - "placeholders": {} - }, - "security": "Bezpečnosť", - "@security": { - "type": "String", - "placeholders": {} - }, - "reportMessage": "Nahlásiť správu", - "@reportMessage": { - "type": "String", - "placeholders": {} - }, - "sendSticker": "Poslať nálepku", - "@sendSticker": { - "type": "String", - "placeholders": {} - }, - "roomVersion": "Verzia miestnosti", - "@roomVersion": { - "type": "String", - "placeholders": {} - }, - "sendMessages": "Poslať správy", - "@sendMessages": { - "type": "String", - "placeholders": {} - }, - "joinRoom": "Pripojiť sa k miestnosti", - "@joinRoom": { - "type": "String", - "placeholders": {} - }, - "setPermissionsLevel": "Nastaviť úroveň oprávnení", - "@setPermissionsLevel": { - "type": "String", - "placeholders": {} - }, - "badServerLoginTypesException": "Server podporuje tieto typy prihlásenia:\n{serverVersions}\nAle táto aplikácia podporuje iba:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "String", - "placeholders": { - "serverVersions": { - "type": "String" - }, - "supportedVersions": { - "type": "String" - } - } - }, - "chatBackup": "Záloha chatov", - "@chatBackup": { - "type": "String", - "placeholders": {} - }, - "addToSpace": "Pridať do priestoru", - "@addToSpace": {}, - "cantOpenUri": "Nemožno otvoriť identifikátor prostriedku {uri}", - "@cantOpenUri": { - "type": "String", - "placeholders": { - "uri": { - "type": "String" - } - } - }, - "yourChatBackupHasBeenSetUp": "Záloha vašich chatov bola nastavená.", - "@yourChatBackupHasBeenSetUp": {}, - "repeatPassword": "Zopakujte heslo", - "@repeatPassword": {}, - "all": "Všetky", - "@all": { - "type": "String", - "placeholders": {} - }, - "allChats": "Všetky chaty", - "@allChats": { - "type": "String", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Ste si istí, že sa chcete odhlásiť?", - "@areYouSureYouWantToLogout": { - "type": "String", - "placeholders": {} - }, - "sendOnEnter": "Odoslať pri vstupe", - "@sendOnEnter": {}, - "ignoredUsers": "Ignorovaní užívatelia", - "@ignoredUsers": { - "type": "String", - "placeholders": {} - }, - "ignore": "Ignorovať", - "@ignore": { - "type": "String", - "placeholders": {} - }, - "search": "Hľadať", - "@search": { - "type": "String", - "placeholders": {} - }, - "sendAsText": "Poslať ako text", - "@sendAsText": { - "type": "String" - }, - "sendOriginal": "Poslať originál", - "@sendOriginal": { - "type": "String", - "placeholders": {} - }, - "sendVideo": "Poslať video", - "@sendVideo": { - "type": "String", - "placeholders": {} - }, - "importNow": "Importovať teraz", - "@importNow": {} } diff --git a/assets/l10n/intl_vi.arb b/assets/l10n/intl_vi.arb index ac6d47add..c27ba67ad 100644 --- a/assets/l10n/intl_vi.arb +++ b/assets/l10n/intl_vi.arb @@ -3740,4 +3740,4 @@ }, "downloadGboard": "Tải Gboard", "autocorrectNotAvailable": "Rất tiếc, nền tảng của bạn hiện không được hỗ trợ cho tính năng này. Hãy theo dõi để biết thêm thông tin phát triển!" -} \ No newline at end of file +} diff --git a/docs/index.html b/docs/index.html index fef1124fd..22cf4a39f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ - diff --git a/fonts/Ubuntu/Ubuntu-Medium.ttf b/fonts/Ubuntu/Ubuntu-Medium.ttf new file mode 100644 index 000000000..7340a40aa Binary files /dev/null and b/fonts/Ubuntu/Ubuntu-Medium.ttf differ diff --git a/lib/config/routes.dart b/lib/config/routes.dart index b71da7540..a6b25959e 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -169,8 +169,6 @@ abstract class AppRoutes { FluffyThemes.isColumnMode(context) && state.fullPath?.startsWith('/rooms/settings') == false ? TwoColumnLayout( - displayNavigationRail: - state.path?.startsWith('/rooms/settings') != true, mainView: ChatList( activeChat: state.pathParameters['roomid'], displayNavigationRail: @@ -319,9 +317,8 @@ abstract class AppRoutes { state, FluffyThemes.isColumnMode(context) ? TwoColumnLayout( - mainView: const Settings(), + mainView: Settings(key: state.pageKey), sideView: child, - displayNavigationRail: false, ) : child, ), diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index 7c0e50df8..6d30298dd 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -34,4 +34,5 @@ abstract class SettingKeys { 'chat.fluffy.display_chat_details_column'; static const String noEncryptionWarningShown = 'chat.fluffy.no_encryption_warning_shown'; + static const String shareKeysWith = 'chat.fluffy.share_keys_with'; } diff --git a/lib/config/themes.dart b/lib/config/themes.dart index 03ead0109..fc804bede 100644 --- a/lib/config/themes.dart +++ b/lib/config/themes.dart @@ -7,7 +7,7 @@ import 'app_config.dart'; abstract class FluffyThemes { static const double columnWidth = 380.0; - static const double navRailWidth = 64.0; + static const double navRailWidth = 80.0; static bool isColumnModeByWidth(double width) => width > columnWidth * 2 + navRailWidth; @@ -77,7 +77,9 @@ abstract class FluffyThemes { // causes memory leak on iOS // textTheme: fallbackTextTheme, // Pangea# - dividerColor: colorScheme.surfaceContainer, + dividerColor: brightness == Brightness.dark + ? colorScheme.surfaceContainerHighest + : colorScheme.surfaceContainer, popupMenuTheme: PopupMenuThemeData( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppConfig.borderRadius), @@ -154,3 +156,18 @@ extension on Brightness { Brightness get reversed => this == Brightness.dark ? Brightness.light : Brightness.dark; } + +extension BubbleColorTheme on ThemeData { + Color get bubbleColor => brightness == Brightness.light + ? colorScheme.primary + : colorScheme.primaryContainer; + Color get onBubbleColor => brightness == Brightness.light + ? colorScheme.onPrimary + : colorScheme.onPrimaryContainer; + + Color get secondaryBubbleColor => HSLColor.fromColor( + brightness == Brightness.light + ? colorScheme.tertiary + : colorScheme.tertiaryContainer, + ).withSaturation(0.5).toColor(); +} diff --git a/lib/pages/chat/chat_app_bar_title.dart b/lib/pages/chat/chat_app_bar_title.dart index 66027192b..7110febf9 100644 --- a/lib/pages/chat/chat_app_bar_title.dart +++ b/lib/pages/chat/chat_app_bar_title.dart @@ -20,7 +20,12 @@ class ChatAppBarTitle extends StatelessWidget { Widget build(BuildContext context) { final room = controller.room; if (controller.selectedEvents.isNotEmpty) { - return Text(controller.selectedEvents.length.toString()); + return Text( + controller.selectedEvents.length.toString(), + style: TextStyle( + color: Theme.of(context).colorScheme.tertiary, + ), + ); } return InkWell( hoverColor: Colors.transparent, @@ -98,12 +103,17 @@ class ChatAppBarTitle extends StatelessWidget { ) : Row( children: [ - Icon( - status.icon, - size: 12, - color: status.error != null - ? Theme.of(context).colorScheme.error - : null, + SizedBox.square( + dimension: 10, + child: CircularProgressIndicator.adaptive( + strokeWidth: 1, + value: status.progress, + valueColor: status.error != null + ? AlwaysStoppedAnimation( + Theme.of(context).colorScheme.error, + ) + : null, + ), ), const SizedBox(width: 4), Expanded( diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index f849231ca..49bbf1d12 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -37,6 +37,13 @@ class ChatEventList extends StatelessWidget { ); } + final theme = Theme.of(context); + + final colors = [ + theme.secondaryBubbleColor, + theme.bubbleColor, + ]; + final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0; final events = timeline.events.filterByVisibleInGui(); @@ -131,8 +138,6 @@ class ChatEventList extends StatelessWidget { // #Pangea WidgetsBinding.instance .addPostFrameCallback((_) => controller.requestHistory); - // WidgetsBinding.instance - // .addPostFrameCallback(controller.requestHistory); return Column( children: [ const SizedBox(height: AppConfig.toolbarMaxHeight), @@ -144,6 +149,8 @@ class ChatEventList extends StatelessWidget { ), ], ); + // WidgetsBinding.instance + // .addPostFrameCallback(controller.requestHistory); // return Center( // child: IconButton( // onPressed: controller.requestHistory, @@ -161,6 +168,7 @@ class ChatEventList extends StatelessWidget { } i--; + // The message at this index: final event = events[i]; final animateIn = animateInEventIndex != null && timeline.events.length > animateInEventIndex && @@ -227,6 +235,8 @@ class ChatEventList extends StatelessWidget { i + 1 < events.length ? events[i + 1] : null, previousEvent: i > 0 ? events[i - 1] : null, wallpaperMode: hasWallpaper, + scrollController: controller.scrollController, + colors: colors, ), ); }, diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index 0e3de3534..c3cd82e54 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -38,6 +38,10 @@ class ChatInputRow extends StatelessWidget { controller.emojiPickerType == EmojiPickerType.reaction) { return const SizedBox.shrink(); } + // #Pangea + // const height = 48.0; + const height = AppConfig.defaultFooterHeight; + // Pangea# if (!controller.room.otherPartyCanReceiveMessages) { return Center( @@ -53,9 +57,6 @@ class ChatInputRow extends StatelessWidget { } // #Pangea - // const height = 48.0; - const height = AppConfig.defaultFooterHeight; - final activel1 = controller.pangeaController.languageController.activeL1Model(); final activel2 = @@ -109,18 +110,18 @@ class ChatInputRow extends StatelessWidget { ), // #Pangea // else - // SizedBox( - // height: height, - // child: TextButton( - // onPressed: controller.forwardEventsAction, - // child: Row( - // children: [ - // const Icon(Icons.keyboard_arrow_left_outlined), - // Text(L10n.of(context).forward), - // ], - // ), + // SizedBox( + // height: height, + // child: TextButton( + // onPressed: controller.forwardEventsAction, + // child: Row( + // children: [ + // const Icon(Icons.keyboard_arrow_left_outlined), + // Text(L10n.of(context).forward), + // ], // ), // ), + // ), // controller.selectedEvents.length == 1 // ? controller.selectedEvents.first // .getDisplayEvent(controller.timeline!) @@ -374,8 +375,8 @@ class ChatInputRow extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(height), ), - backgroundColor: theme.colorScheme.primary, - foregroundColor: theme.colorScheme.onPrimary, + backgroundColor: theme.bubbleColor, + foregroundColor: theme.onBubbleColor, child: const Icon(Icons.mic_none_outlined), ) // #Pangea diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 1af946cae..c3012a376 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -114,7 +114,8 @@ class ChatView extends StatelessWidget { } // } else if (!controller.room.isArchived) { // return [ - // if (Matrix.of(context).voipPlugin != null && + // if (AppConfig.experimentalVoip && + // Matrix.of(context).voipPlugin != null && // controller.room.isDirectChat) // IconButton( // onPressed: controller.onPhoneButtonTap, @@ -199,28 +200,31 @@ class ChatView extends StatelessWidget { actionsIconTheme: IconThemeData( color: controller.selectedEvents.isEmpty ? null - : theme.colorScheme.primary, + : theme.colorScheme.tertiary, ), + automaticallyImplyLeading: false, leading: controller.selectMode ? IconButton( icon: const Icon(Icons.close), onPressed: controller.clearSelectedEvents, tooltip: L10n.of(context).close, - color: theme.colorScheme.primary, + color: theme.colorScheme.tertiary, ) - : StreamBuilder( - stream: Matrix.of(context) - .client - .onSync - .stream - .where((syncUpdate) => syncUpdate.hasRoomUpdate), - builder: (context, _) => UnreadRoomsBadge( - filter: (r) => r.id != controller.roomId, - badgePosition: BadgePosition.topEnd(end: 8, top: 4), - child: const Center(child: BackButton()), - ), - ), - titleSpacing: 0, + : FluffyThemes.isColumnMode(context) + ? null + : StreamBuilder( + stream: + Matrix.of(context).client.onSync.stream.where( + (syncUpdate) => syncUpdate.hasRoomUpdate, + ), + builder: (context, _) => UnreadRoomsBadge( + filter: (r) => r.id != controller.roomId, + badgePosition: + BadgePosition.topEnd(end: 8, top: 4), + child: const Center(child: BackButton()), + ), + ), + titleSpacing: FluffyThemes.isColumnMode(context) ? 24 : 0, title: ChatAppBarTitle(controller), actions: _appBarActions(context), bottom: PreferredSize( diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index c2c4822a2..8837f3bf7 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -113,21 +113,24 @@ class HtmlMessage extends StatelessWidget { /// We add line breaks before these tags: static const Set blockHtmlTags = { 'p', + 'ul', + 'ol', + 'pre', + 'div', + 'table', + 'details', + 'blockquote', + }; + + /// We add line breaks before these tags: + static const Set fullLineHtmlTag = { 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'ul', - 'ol', 'li', - 'pre', - 'br', - 'div', - 'table', - 'blockquote', - 'details', }; // #Pangea @@ -202,17 +205,24 @@ class HtmlMessage extends StatelessWidget { dom.NodeList nodes, BuildContext context, { int depth = 1, - }) => - [ - for (var i = 0; i < nodes.length; i++) ...[ - if (i > 0 && - nodes[i] is dom.Element && - blockHtmlTags.contains((nodes[i] as dom.Element).localName)) - const TextSpan(text: '\n'), // Add linebreak - // Actually render the node child: - _renderHtml(nodes[i], context, depth: depth + 1), + }) { + final onlyElements = nodes.whereType().toList(); + return [ + for (var i = 0; i < nodes.length; i++) ...[ + // Actually render the node child: + _renderHtml(nodes[i], context, depth: depth + 1), + // Add linebreaks between blocks: + if (nodes[i] is dom.Element && + onlyElements.indexOf(nodes[i] as dom.Element) < + onlyElements.length - 1) ...[ + if (blockHtmlTags.contains((nodes[i] as dom.Element).localName)) + const TextSpan(text: '\n\n'), + if (fullLineHtmlTag.contains((nodes[i] as dom.Element).localName)) + const TextSpan(text: '\n'), ], - ]; + ], + ]; + } /// Transforms a Node to an InlineSpan. InlineSpan _renderHtml( @@ -287,6 +297,8 @@ class HtmlMessage extends StatelessWidget { ).merge(TextStyle(backgroundColor: backgroundColor)), ); // Pangea# + case 'br': + return const TextSpan(text: '\n'); case 'a': final href = node.attributes['href']; if (href == null) continue block; @@ -423,7 +435,10 @@ class HtmlMessage extends StatelessWidget { horizontal: 8, vertical: isInline ? 0 : 8, ), - textStyle: TextStyle(fontSize: fontSize), + textStyle: TextStyle( + fontSize: fontSize, + fontFamily: 'UbuntuMono', + ), ), ), ), diff --git a/lib/pages/chat/events/image_bubble.dart b/lib/pages/chat/events/image_bubble.dart index 6c9a788ac..3fa352d25 100644 --- a/lib/pages/chat/events/image_bubble.dart +++ b/lib/pages/chat/events/image_bubble.dart @@ -14,7 +14,6 @@ class ImageBubble extends StatelessWidget { final Event event; final bool tapToView; final BoxFit fit; - final bool maxSize; final Color? backgroundColor; final Color? textColor; final Color? linkColor; @@ -29,7 +28,6 @@ class ImageBubble extends StatelessWidget { const ImageBubble( this.event, { this.tapToView = true, - this.maxSize = true, this.backgroundColor, this.fit = BoxFit.contain, this.thumbnailOnly = true, diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 912e5146a..2a811cc79 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -1,3 +1,5 @@ +import 'dart:ui' as ui; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -42,12 +44,14 @@ class Message extends StatelessWidget { final bool animateIn; final void Function()? resetAnimateIn; final bool wallpaperMode; + final ScrollController scrollController; // #Pangea final bool immersionMode; final ChatController controller; final MessageOverlayController? overlayController; final bool isButton; // Pangea# + final List colors; const Message( this.event, { @@ -66,12 +70,14 @@ class Message extends StatelessWidget { this.animateIn = false, this.resetAnimateIn, this.wallpaperMode = false, + required this.scrollController, // #Pangea required this.immersionMode, required this.controller, this.overlayController, this.isButton = false, // Pangea# + required this.colors, super.key, }); @@ -155,17 +161,13 @@ class Message extends StatelessWidget { previousEvent!.senderId == event.senderId && previousEvent!.originServerTs.sameEnvironment(event.originServerTs); + // #Pangea + // final textColor = + // ownMessage ? theme.onBubbleColor : theme.colorScheme.onSurface; final textColor = ownMessage - ? - // #Pangea - // theme.brightness == Brightness.light - // ? theme.colorScheme.onPrimary - // : theme.colorScheme.onPrimaryContainer - ThemeData.dark().colorScheme.onPrimary - // Pangea# + ? ThemeData.dark().colorScheme.onPrimary : theme.colorScheme.onSurface; - // #Pangea // final linkColor = ownMessage // ? theme.brightness == Brightness.light // ? theme.colorScheme.primaryFixed @@ -210,12 +212,11 @@ class Message extends StatelessWidget { }.contains(event.messageType); if (ownMessage) { + // #Pangea + // color = + // displayEvent.status.isError ? Colors.redAccent : theme.bubbleColor; color = displayEvent.status.isError ? Colors.redAccent - // #Pangea - // : theme.brightness == Brightness.light - // ? theme.colorScheme.primary - // : theme.colorScheme.primaryContainer; : Color.alphaBlend( Colors.white.withAlpha(180), ThemeData.dark().colorScheme.primary, @@ -439,10 +440,17 @@ class Message extends StatelessWidget { event.eventId, ) .link, + // child: BubbleBackground( + // colors: colors, + // ignore: noBubble || !ownMessage, + // scrollController: scrollController, + // Pangea# child: Container( + // #Pangea key: overlayController != null - ? LayerLinkAndKey('overlay_msg') - .key + ? LayerLinkAndKey( + 'overlay_msg', + ).key : MatrixState.pAnyState .layerLinkAndKey( event.eventId, @@ -580,8 +588,9 @@ class Message extends StatelessWidget { .msgUseType .iconView( context, - textColor - .withAlpha(164), + textColor.withAlpha( + 164, + ), ), const SizedBox( width: 4, @@ -597,7 +606,9 @@ class Message extends StatelessWidget { Icon( Icons.edit_outlined, color: textColor - .withAlpha(164), + .withAlpha( + 164, + ), size: 14, ), Text( @@ -798,3 +809,72 @@ class Message extends StatelessWidget { ); } } + +class BubbleBackground extends StatelessWidget { + const BubbleBackground({ + super.key, + required this.scrollController, + required this.colors, + required this.ignore, + required this.child, + }); + + final ScrollController scrollController; + final List colors; + final bool ignore; + final Widget child; + + @override + Widget build(BuildContext context) { + if (ignore) return child; + return CustomPaint( + painter: BubblePainter( + repaint: scrollController, + colors: colors, + context: context, + ), + child: child, + ); + } +} + +class BubblePainter extends CustomPainter { + BubblePainter({ + required this.context, + required this.colors, + required super.repaint, + }); + + final BuildContext context; + final List colors; + ScrollableState? _scrollable; + + @override + void paint(Canvas canvas, Size size) { + final scrollable = _scrollable ??= Scrollable.of(context); + final scrollableBox = scrollable.context.findRenderObject() as RenderBox; + final scrollableRect = Offset.zero & scrollableBox.size; + final bubbleBox = context.findRenderObject() as RenderBox; + + final origin = + bubbleBox.localToGlobal(Offset.zero, ancestor: scrollableBox); + final paint = Paint() + ..shader = ui.Gradient.linear( + scrollableRect.topCenter, + scrollableRect.bottomCenter, + colors, + [0.0, 1.0], + TileMode.clamp, + Matrix4.translationValues(-origin.dx, -origin.dy, 0.0).storage, + ); + canvas.drawRect(Offset.zero & size, paint); + } + + @override + bool shouldRepaint(BubblePainter oldDelegate) { + final scrollable = Scrollable.of(context); + final oldScrollable = _scrollable; + _scrollable = scrollable; + return scrollable.position != oldScrollable?.position; + } +} diff --git a/lib/pages/chat/input_bar.dart b/lib/pages/chat/input_bar.dart index ccdb27187..5747e2bf6 100644 --- a/lib/pages/chat/input_bar.dart +++ b/lib/pages/chat/input_bar.dart @@ -245,7 +245,7 @@ class InputBar extends StatelessWidget { children: [ Text( commandExample(command), - style: const TextStyle(fontFamily: 'monospace'), + style: const TextStyle(fontFamily: 'UbuntuMono'), ), Text( hint, @@ -265,7 +265,7 @@ class InputBar extends StatelessWidget { waitDuration: const Duration(days: 1), // don't show on hover child: Container( padding: padding, - child: Text(label, style: const TextStyle(fontFamily: 'monospace')), + child: Text(label, style: const TextStyle(fontFamily: 'UbuntuMono')), ), ); } diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart index aea3c4e59..2e522e44a 100644 --- a/lib/pages/chat/send_file_dialog.dart +++ b/lib/pages/chat/send_file_dialog.dart @@ -161,8 +161,9 @@ class SendFileDialogState extends State { final theme = Theme.of(context); var sendStr = L10n.of(context).sendFile; - final uniqueMimeType = widget.files + final uniqueFileType = widget.files .map((file) => file.mimeType ?? lookupMimeType(file.name)) + .map((mimeType) => mimeType?.split('/').first) .toSet() .singleOrNull; @@ -175,15 +176,15 @@ class SendFileDialogState extends State { .join(', ') .toUpperCase(); - if (uniqueMimeType?.startsWith('image') ?? false) { + if (uniqueFileType == 'image') { if (widget.files.length == 1) { sendStr = L10n.of(context).sendImage; } else { sendStr = L10n.of(context).sendImages(widget.files.length); } - } else if (uniqueMimeType?.startsWith('audio') ?? false) { + } else if (uniqueFileType == 'audio') { sendStr = L10n.of(context).sendAudio; - } else if (uniqueMimeType?.startsWith('video') ?? false) { + } else if (uniqueFileType == 'video') { sendStr = L10n.of(context).sendVideo; } @@ -201,7 +202,7 @@ class SendFileDialogState extends State { mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 12), - if (uniqueMimeType?.startsWith('image') ?? false) + if (uniqueFileType == 'image') Padding( padding: const EdgeInsets.only(bottom: 16.0), child: SizedBox( @@ -233,17 +234,17 @@ class SendFileDialogState extends State { ), ), ), - if (uniqueMimeType?.startsWith('image') != true) + if (uniqueFileType != 'image') Padding( padding: const EdgeInsets.only(bottom: 16.0), child: Row( children: [ Icon( - uniqueMimeType == null + uniqueFileType == null ? Icons.description_outlined - : uniqueMimeType.startsWith('video') + : uniqueFileType == 'video' ? Icons.video_file_outlined - : uniqueMimeType.startsWith('audio') + : uniqueFileType == 'audio' ? Icons.audio_file_outlined : Icons.description_outlined, size: 32, @@ -272,9 +273,7 @@ class SendFileDialogState extends State { ), ), // Workaround for SwitchListTile.adaptive crashes in CupertinoDialog - if (uniqueMimeType != null && - (uniqueMimeType.startsWith('image') || - uniqueMimeType.startsWith('video'))) + if ({'image', 'video'}.contains(uniqueFileType)) Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -282,7 +281,7 @@ class SendFileDialogState extends State { .contains(theme.platform)) CupertinoSwitch( value: compress, - onChanged: uniqueMimeType.startsWith('video') && + onChanged: uniqueFileType == 'video' && !PlatformInfos.isMobile ? null : (v) => setState(() => compress = v), @@ -290,7 +289,7 @@ class SendFileDialogState extends State { else Switch.adaptive( value: compress, - onChanged: uniqueMimeType.startsWith('video') && + onChanged: uniqueFileType == 'video' && !PlatformInfos.isMobile ? null : (v) => setState(() => compress = v), diff --git a/lib/pages/chat_details/participant_list_item.dart b/lib/pages/chat_details/participant_list_item.dart index 4b4f27357..a7807f403 100644 --- a/lib/pages/chat_details/participant_list_item.dart +++ b/lib/pages/chat_details/participant_list_item.dart @@ -94,7 +94,11 @@ class ParticipantListItem extends StatelessWidget { ), ], ), - subtitle: Text(user.id), + subtitle: Text( + user.id, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), leading: Avatar( mxContent: user.avatarUrl, name: user.calcDisplayname(), diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index 3d40de448..ef5ef89dc 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -169,6 +169,7 @@ class ChatListController extends State void onChatTap(Room room) async { if (room.membership == Membership.invite) { + // #Pangea await showInviteDialog(room); return; // final joinResult = await showFutureLoadingDialog( @@ -184,6 +185,7 @@ class ChatListController extends State // exceptionContext: ExceptionContext.joinRoom, // ); // if (joinResult.error != null) return; + // Pangea# } if (room.membership == Membership.ban) { diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart index d0486c9b3..aac2ed307 100644 --- a/lib/pages/chat_list/chat_list_body.dart +++ b/lib/pages/chat_list/chat_list_body.dart @@ -251,7 +251,7 @@ class ChatListViewBody extends StatelessWidget { style: TextStyle( fontWeight: filter == controller.activeFilter - ? FontWeight.bold + ? FontWeight.w500 : FontWeight.normal, color: filter == controller.activeFilter @@ -320,15 +320,6 @@ class ChatListViewBody extends StatelessWidget { ), ], ), - // Padding( - // padding: const EdgeInsets.all(32.0), - // child: Icon( - // CupertinoIcons.chat_bubble_2, - // size: 128, - // color: theme.colorScheme.secondary, - // ), - // ), - // Pangea# ], ], ), diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index 354fe1bb6..93d5a4da6 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -7,7 +7,7 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/client_chooser_button.dart'; import 'package:fluffychat/utils/sync_status_localization.dart'; -import 'package:fluffychat/widgets/matrix.dart'; +import '../../widgets/matrix.dart'; class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { final ChatListController controller; @@ -79,12 +79,21 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { color: theme.colorScheme.onPrimaryContainer, ), ) - : Icon( - status.icon, - color: status.error != null - ? theme.colorScheme.error - : theme.colorScheme.onPrimaryContainer, - size: 18, + : Container( + margin: const EdgeInsets.all(12), + width: 8, + height: 8, + child: Center( + child: CircularProgressIndicator.adaptive( + strokeWidth: 2, + value: status.progress, + valueColor: status.error != null + ? AlwaysStoppedAnimation( + theme.colorScheme.error, + ) + : null, + ), + ), ), suffixIcon: controller.isSearchMode && globalSearch ? controller.isSearching @@ -115,14 +124,16 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { maxLines: 2, ), ) + // #Pangea + // : SizedBox( + // width: 0, + // child: ClientChooserButton(controller), + // ), : const SizedBox( width: 0, - child: ClientChooserButton( - // #Pangea - // controller, - // Pangea# - ), + child: ClientChooserButton(), ), + // Pangea# ), ); }, diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 260468e79..6a78b294f 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -47,7 +47,6 @@ class ChatListItem extends StatelessWidget { return forgetResult.isValue; } final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, context: context, title: L10n.of(context).areYouSure, okLabel: L10n.of(context).leave, @@ -236,9 +235,11 @@ class ChatListItem extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, softWrap: false, - style: unread || room.hasNewMessages - ? const TextStyle(fontWeight: FontWeight.bold) - : null, + style: TextStyle( + fontWeight: unread || room.hasNewMessages + ? FontWeight.w500 + : null, + ), ), ), if (isMuted) @@ -249,8 +250,7 @@ class ChatListItem extends StatelessWidget { size: 16, ), ), - if (room.isFavourite || - room.membership == Membership.invite) + if (room.isFavourite) Padding( padding: EdgeInsets.only( right: hasNotifications ? 4.0 : 0.0, @@ -269,16 +269,15 @@ class ChatListItem extends StatelessWidget { child: Text( lastEvent.originServerTs.localizedTimeShort(context), style: TextStyle( - fontSize: 13, - color: unread - ? theme.colorScheme.secondary - : theme.textTheme.bodyMedium!.color, + fontSize: 12, + color: theme.colorScheme.outline, ), ), ), ], ), subtitle: Row( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ if (typingText.isEmpty && @@ -315,6 +314,8 @@ class ChatListItem extends StatelessWidget { // Pangea# (room.summary.mJoinedMemberCount ?? 1), ), + style: + TextStyle(color: theme.colorScheme.outline), ) : typingText.isNotEmpty ? Text( @@ -370,12 +371,21 @@ class ChatListItem extends StatelessWidget { ), builder: (context, snapshot) => Text( room.membership == Membership.invite - ? isDirectChat - ? L10n.of(context) - .invitePrivateChat - // #Pangea - // : L10n.of(context).inviteGroupChat - : L10n.of(context).inviteChat + ? room + .getState( + EventTypes.RoomMember, + room.client.userID!, + ) + ?.content + .tryGet('reason') ?? + (isDirectChat + ? L10n.of(context) + .newChatRequest + // #Pangea + // : L10n.of(context) + // .inviteGroupChat) + : L10n.of(context) + .inviteChat) // Pangea# : snapshot.data ?? L10n.of(context).emptyChat, @@ -384,12 +394,9 @@ class ChatListItem extends StatelessWidget { room.notificationCount >= 1 ? 2 : 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontWeight: - unread || room.hasNewMessages - ? FontWeight.bold - : null, - color: theme - .colorScheme.onSurfaceVariant, + color: unread || room.hasNewMessages + ? theme.colorScheme.onSurface + : theme.colorScheme.outline, decoration: room.lastEvent?.redacted == true ? TextDecoration.lineThrough @@ -402,6 +409,7 @@ class ChatListItem extends StatelessWidget { AnimatedContainer( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, + alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 7), height: unreadBubbleSize, width: @@ -413,29 +421,28 @@ class ChatListItem extends StatelessWidget { decoration: BoxDecoration( color: room.highlightCount > 0 || room.membership == Membership.invite - ? Colors.red + ? theme.colorScheme.onError : hasNotifications || room.markedUnread ? theme.colorScheme.primary : theme.colorScheme.primaryContainer, - borderRadius: - BorderRadius.circular(AppConfig.borderRadius), - ), - child: Center( - child: hasNotifications - ? Text( - room.notificationCount.toString(), - style: TextStyle( - color: room.highlightCount > 0 - ? Colors.white - : hasNotifications - ? theme.colorScheme.onPrimary - : theme - .colorScheme.onPrimaryContainer, - fontSize: 13, - ), - ) - : const SizedBox.shrink(), + borderRadius: BorderRadius.circular(7), ), + child: hasNotifications + ? Text( + room.notificationCount.toString(), + style: TextStyle( + color: room.highlightCount > 0 || + room.membership == Membership.invite + ? theme.colorScheme.onError + : hasNotifications + ? theme.colorScheme.onPrimary + : theme.colorScheme.onPrimaryContainer, + fontSize: 13, + fontWeight: FontWeight.w500, + ), + textAlign: TextAlign.center, + ) + : const SizedBox.shrink(), ), ], ), diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index 599d936f5..aad875091 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -2,17 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; -import 'package:fluffychat/pages/chat_list/navi_rail_item.dart'; import 'package:fluffychat/pangea/chat_list/widgets/chat_list_view_body_wrapper.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; -import 'package:fluffychat/utils/stream_extension.dart'; -import 'package:fluffychat/widgets/avatar.dart'; -import '../../widgets/matrix.dart'; +import 'package:fluffychat/widgets/navigation_rail.dart'; class ChatListView extends StatelessWidget { final ChatListController controller; @@ -21,7 +15,6 @@ class ChatListView extends StatelessWidget { @override Widget build(BuildContext context) { - final client = Matrix.of(context).client; return PopScope( canPop: !controller.isSearchMode && controller.activeSpaceId == null, onPopInvokedWithResult: (pop, _) { @@ -39,81 +32,10 @@ class ChatListView extends StatelessWidget { children: [ if (FluffyThemes.isColumnMode(context) && controller.widget.displayNavigationRail) ...[ - StreamBuilder( - key: ValueKey( - client.userID.toString(), - ), - stream: client.onSync.stream - .where((s) => s.hasRoomUpdate) - .rateLimit(const Duration(seconds: 1)), - builder: (context, _) { - final allSpaces = Matrix.of(context) - .client - .rooms - .where((room) => room.isSpace); - final rootSpaces = allSpaces - .where( - (space) => !allSpaces.any( - (parentSpace) => parentSpace.spaceChildren - .any((child) => child.roomId == space.id), - ), - ) - .toList(); - - return SizedBox( - width: FluffyThemes.navRailWidth, - child: ListView.builder( - scrollDirection: Axis.vertical, - itemCount: rootSpaces.length + 2, - itemBuilder: (context, i) { - if (i == 0) { - return NaviRailItem( - isSelected: controller.activeSpaceId == null, - onTap: controller.clearActiveSpace, - icon: const Icon(Icons.forum_outlined), - selectedIcon: const Icon(Icons.forum), - toolTip: L10n.of(context).chats, - unreadBadgeFilter: (room) => true, - ); - } - i--; - if (i == rootSpaces.length) { - return NaviRailItem( - isSelected: false, - onTap: () => context.go('/rooms/newspace'), - icon: const Icon(Icons.add), - toolTip: L10n.of(context).createNewSpace, - ); - } - final space = rootSpaces[i]; - final displayname = rootSpaces[i].getLocalizedDisplayname( - MatrixLocals(L10n.of(context)), - ); - final spaceChildrenIds = - space.spaceChildren.map((c) => c.roomId).toSet(); - return NaviRailItem( - toolTip: displayname, - isSelected: controller.activeSpaceId == space.id, - onTap: () => - controller.setActiveSpace(rootSpaces[i].id), - unreadBadgeFilter: (room) => - spaceChildrenIds.contains(room.id), - icon: Avatar( - mxContent: rootSpaces[i].avatar, - name: displayname, - // #Pangea - presenceUserId: space.directChatMatrixID, - // Pangea# - size: 32, - borderRadius: BorderRadius.circular( - AppConfig.borderRadius / 4, - ), - ), - ); - }, - ), - ); - }, + SpacesNavigationRail( + activeSpaceId: controller.activeSpaceId, + onGoToChats: controller.clearActiveSpace, + onGoToSpaceId: controller.setActiveSpace, ), Container( color: Theme.of(context).dividerColor, diff --git a/lib/pages/chat_list/navi_rail_item.dart b/lib/pages/chat_list/navi_rail_item.dart index 77837bfef..0e844e05d 100644 --- a/lib/pages/chat_list/navi_rail_item.dart +++ b/lib/pages/chat_list/navi_rail_item.dart @@ -35,16 +35,16 @@ class NaviRailItem extends StatelessWidget { return HoverBuilder( builder: (context, hovered) { return SizedBox( - height: FluffyThemes.navRailWidth, + height: 72, width: FluffyThemes.navRailWidth, child: Stack( children: [ Positioned( - top: 16, - bottom: 16, + top: 8, + bottom: 8, left: 0, child: AnimatedContainer( - width: isSelected ? 4 : 0, + width: isSelected ? 8 : 0, duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, decoration: BoxDecoration( @@ -58,35 +58,29 @@ class NaviRailItem extends StatelessWidget { ), Center( child: AnimatedScale( - scale: hovered ? 1.2 : 1.0, + scale: hovered ? 1.1 : 1.0, duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, child: Material( borderRadius: borderRadius, color: isSelected ? theme.colorScheme.primaryContainer - : theme.colorScheme.surface, + : theme.colorScheme.surfaceContainerHigh, child: Tooltip( message: toolTip, child: InkWell( borderRadius: borderRadius, onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8.0, - vertical: 8.0, - ), - child: unreadBadgeFilter == null - ? icon - : UnreadRoomsBadge( - filter: unreadBadgeFilter, - badgePosition: BadgePosition.topEnd( - top: -12, - end: -8, - ), - child: icon, + child: unreadBadgeFilter == null + ? icon + : UnreadRoomsBadge( + filter: unreadBadgeFilter, + badgePosition: BadgePosition.topEnd( + top: -12, + end: -8, ), - ), + child: icon, + ), ), ), ), diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 5023558eb..b9ced7595 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -9,6 +9,7 @@ import 'package:matrix/matrix.dart' as sdk; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; @@ -295,15 +296,14 @@ class _SpaceViewState extends State { break; case SpaceActions.leave: final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, context: context, title: L10n.of(context).areYouSure, - okLabel: L10n.of(context).ok, - cancelLabel: L10n.of(context).cancel, // #Pangea // message: L10n.of(context).archiveRoomDescription, message: L10n.of(context).leaveSpaceDescription, // Pangea# + okLabel: L10n.of(context).leave, + cancelLabel: L10n.of(context).cancel, isDestructive: true, ); if (!mounted) return; @@ -510,12 +510,15 @@ class _SpaceViewState extends State { room?.getLocalizedDisplayname() ?? L10n.of(context).nothingFound; return Scaffold( appBar: AppBar( - leading: Center( - child: CloseButton( - onPressed: widget.onBack, - ), - ), - titleSpacing: 0, + leading: FluffyThemes.isColumnMode(context) + ? null + : Center( + child: CloseButton( + onPressed: widget.onBack, + ), + ), + automaticallyImplyLeading: false, + titleSpacing: FluffyThemes.isColumnMode(context) ? null : 0, title: ListTile( contentPadding: EdgeInsets.zero, leading: Avatar( @@ -524,6 +527,7 @@ class _SpaceViewState extends State { // #Pangea presenceUserId: room?.directChatMatrixID, // Pangea# + border: BorderSide(width: 1, color: theme.dividerColor), borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), title: Text( diff --git a/lib/pages/chat_search/chat_search_images_tab.dart b/lib/pages/chat_search/chat_search_images_tab.dart index a930ed02d..e2465a6d9 100644 --- a/lib/pages/chat_search/chat_search_images_tab.dart +++ b/lib/pages/chat_search/chat_search_images_tab.dart @@ -4,9 +4,11 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:intl/intl.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pages/chat/events/image_bubble.dart'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/chat/events/video_player.dart'; +import 'package:fluffychat/pages/image_viewer/image_viewer.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/widgets/mxc_image.dart'; class ChatSearchImagesTab extends StatelessWidget { final Room room; @@ -25,6 +27,7 @@ class ChatSearchImagesTab extends StatelessWidget { @override Widget build(BuildContext context) { + final borderRadius = BorderRadius.circular(AppConfig.borderRadius / 2); return StreamBuilder( stream: searchStream, builder: (context, snapshot) { @@ -144,16 +147,39 @@ class ChatSearchImagesTab extends StatelessWidget { shrinkWrap: true, mainAxisSpacing: padding, crossAxisSpacing: padding, + clipBehavior: Clip.hardEdge, padding: const EdgeInsets.all(padding), crossAxisCount: 3, children: monthEvents.map( (event) { if (event.messageType == MessageTypes.Video) { - return EventVideoPlayer(event); + return Material( + clipBehavior: Clip.hardEdge, + borderRadius: borderRadius, + child: EventVideoPlayer(event), + ); } - return ImageBubble( - event, - fit: BoxFit.cover, + return InkWell( + onTap: () => showDialog( + context: context, + builder: (_) => ImageViewer( + event, + outerContext: context, + ), + ), + borderRadius: borderRadius, + child: Material( + clipBehavior: Clip.hardEdge, + borderRadius: borderRadius, + child: MxcImage( + event: event, + width: 128, + height: 128, + fit: BoxFit.cover, + animated: true, + isThumbnail: true, + ), + ), ); }, ).toList(), diff --git a/lib/pages/chat_search/chat_search_view.dart b/lib/pages/chat_search/chat_search_view.dart index 1f458ca98..422479ccf 100644 --- a/lib/pages/chat_search/chat_search_view.dart +++ b/lib/pages/chat_search/chat_search_view.dart @@ -59,7 +59,7 @@ class ChatSearchView extends StatelessWidget { enabled: controller.tabController.index == 0, decoration: InputDecoration( hintText: L10n.of(context).search, - suffixIcon: const Icon(Icons.search_outlined), + prefixIcon: const Icon(Icons.search_outlined), filled: true, fillColor: theme.colorScheme.secondaryContainer, border: OutlineInputBorder( diff --git a/lib/pages/device_settings/device_settings_view.dart b/lib/pages/device_settings/device_settings_view.dart index 57fb87cad..4e9dab79c 100644 --- a/lib/pages/device_settings/device_settings_view.dart +++ b/lib/pages/device_settings/device_settings_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/device_settings/device_settings.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'user_device_list_item.dart'; @@ -15,7 +16,8 @@ class DevicesSettingsView extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - leading: const Center(child: BackButton()), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), title: Text(L10n.of(context).devices), ), body: MaxWidthBody( diff --git a/lib/pages/homeserver_picker/homeserver_picker.dart b/lib/pages/homeserver_picker/homeserver_picker.dart index d8c584a98..b0a5b0a5d 100644 --- a/lib/pages/homeserver_picker/homeserver_picker.dart +++ b/lib/pages/homeserver_picker/homeserver_picker.dart @@ -218,8 +218,8 @@ class HomeserverPickerController extends State { void onMoreAction(MoreLoginActions action) { switch (action) { - case MoreLoginActions.passwordLogin: - checkHomeserverAction(legacyPasswordLogin: true); + case MoreLoginActions.importBackup: + restoreBackup(); case MoreLoginActions.privacy: launchUrlString(AppConfig.privacyUrl); case MoreLoginActions.about: @@ -228,7 +228,7 @@ class HomeserverPickerController extends State { } } -enum MoreLoginActions { passwordLogin, privacy, about } +enum MoreLoginActions { importBackup, privacy, about } class IdentityProvider { final String? id; diff --git a/lib/pages/homeserver_picker/homeserver_picker_view.dart b/lib/pages/homeserver_picker/homeserver_picker_view.dart index 8ae67077c..e4782b35f 100644 --- a/lib/pages/homeserver_picker/homeserver_picker_view.dart +++ b/lib/pages/homeserver_picker/homeserver_picker_view.dart @@ -38,13 +38,13 @@ class HomeserverPickerView extends StatelessWidget { onSelected: controller.onMoreAction, itemBuilder: (_) => [ PopupMenuItem( - value: MoreLoginActions.passwordLogin, + value: MoreLoginActions.importBackup, child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Icon(Icons.login_outlined), + const Icon(Icons.import_export_outlined), const SizedBox(width: 12), - Text(L10n.of(context).loginWithMatrixId), + Text(L10n.of(context).hydrate), ], ), ), @@ -122,10 +122,6 @@ class HomeserverPickerView extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 32.0), child: SelectableLinkify( text: L10n.of(context).appIntroduction, - style: TextStyle( - color: theme.colorScheme.onSecondaryContainer, - fontWeight: FontWeight.w500, - ), textAlign: TextAlign.center, linkStyle: TextStyle( color: theme.colorScheme.secondary, @@ -216,8 +212,10 @@ class HomeserverPickerView extends StatelessWidget { ), onPressed: controller.isLoading ? null - : controller.restoreBackup, - child: Text(L10n.of(context).hydrate), + : () => controller.checkHomeserverAction( + legacyPasswordLogin: true, + ), + child: Text(L10n.of(context).loginWithMatrixId), ), ], ), diff --git a/lib/pages/image_viewer/image_viewer.dart b/lib/pages/image_viewer/image_viewer.dart index 2b2b315e0..80f9b371d 100644 --- a/lib/pages/image_viewer/image_viewer.dart +++ b/lib/pages/image_viewer/image_viewer.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:matrix/matrix.dart'; @@ -26,6 +27,8 @@ class ImageViewer extends StatefulWidget { } class ImageViewerController extends State { + final FocusNode focusNode = FocusNode(); + @override void initState() { super.initState(); @@ -45,6 +48,17 @@ class ImageViewerController extends State { late final List allEvents; + void onKeyEvent(KeyEvent event) { + switch (event.logicalKey) { + case LogicalKeyboardKey.arrowLeft: + if (canGoBack) prevImage(); + break; + case LogicalKeyboardKey.arrowRight: + if (canGoNext) nextImage(); + break; + } + } + void prevImage() async { await pageController.previousPage( duration: FluffyThemes.animationDuration, diff --git a/lib/pages/key_verification/key_verification_dialog.dart b/lib/pages/key_verification/key_verification_dialog.dart index 3dfa75be6..9d3fb47ef 100644 --- a/lib/pages/key_verification/key_verification_dialog.dart +++ b/lib/pages/key_verification/key_verification_dialog.dart @@ -185,20 +185,20 @@ class KeyVerificationPageState extends State { ], ); buttons.add( - TextButton.icon( - icon: const Icon(Icons.close), - style: TextButton.styleFrom(foregroundColor: Colors.red), - label: Text(L10n.of(context).reject), + AdaptiveDialogAction( onPressed: () => widget.request .rejectVerification() .then((_) => Navigator.of(context, rootNavigator: false).pop()), + child: Text( + L10n.of(context).reject, + style: TextStyle(color: theme.colorScheme.error), + ), ), ); buttons.add( - TextButton.icon( - icon: const Icon(Icons.check), - label: Text(L10n.of(context).accept), + AdaptiveDialogAction( onPressed: () => widget.request.acceptVerification(), + child: Text(L10n.of(context).accept), ), ); break; @@ -207,6 +207,7 @@ class KeyVerificationPageState extends State { body = Center( child: Column( children: [ + const SizedBox(height: 16), Stack( alignment: Alignment.center, children: [ @@ -230,10 +231,9 @@ class KeyVerificationPageState extends State { ), ); buttons.add( - TextButton.icon( - icon: const Icon(Icons.close), - label: Text(L10n.of(context).cancel), + AdaptiveDialogAction( onPressed: () => widget.request.cancel(), + child: Text(L10n.of(context).cancel), ), ); @@ -271,20 +271,18 @@ class KeyVerificationPageState extends State { ], ); buttons.add( - TextButton.icon( - icon: const Icon(Icons.close), - style: TextButton.styleFrom( - foregroundColor: Colors.red, - ), - label: Text(L10n.of(context).theyDontMatch), + AdaptiveDialogAction( onPressed: () => widget.request.rejectSas(), + child: Text( + L10n.of(context).theyDontMatch, + style: TextStyle(color: theme.colorScheme.error), + ), ), ); buttons.add( - TextButton.icon( - icon: const Icon(Icons.check_outlined), - label: Text(L10n.of(context).theyMatch), + AdaptiveDialogAction( onPressed: () => widget.request.acceptSas(), + child: Text(L10n.of(context).theyMatch), ), ); break; @@ -295,8 +293,9 @@ class KeyVerificationPageState extends State { body = Column( mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 16), const CircularProgressIndicator.adaptive(strokeWidth: 2), - const SizedBox(height: 10), + const SizedBox(height: 16), Text( acceptText, textAlign: TextAlign.center, @@ -305,20 +304,14 @@ class KeyVerificationPageState extends State { ); break; case KeyVerificationState.done: - body = Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Icons.check_circle_outlined, - color: Colors.green, - size: 128.0, - ), - const SizedBox(height: 10), - Text( - L10n.of(context).verifySuccess, - textAlign: TextAlign.center, - ), - ], + title = Text(L10n.of(context).verifySuccess); + body = const Padding( + padding: EdgeInsets.all(16.0), + child: Icon( + Icons.verified_outlined, + color: Colors.green, + size: 128.0, + ), ); buttons.add( AdaptiveDialogAction( @@ -334,7 +327,8 @@ class KeyVerificationPageState extends State { body = Column( mainAxisSize: MainAxisSize.min, children: [ - const Icon(Icons.cancel, color: Colors.red, size: 128.0), + const SizedBox(height: 16), + Icon(Icons.cancel, color: theme.colorScheme.error, size: 64.0), const SizedBox(height: 16), // TODO: Add better error UI to user Text( diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index d3676ddc5..00acd3f38 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -207,14 +207,6 @@ class SettingsController extends State { // Pangea# } - Future getOidcAccountManageUrl() async { - final client = Matrix.of(context).client; - final wellKnown = client.wellKnown ?? await client.getWellknown(); - return wellKnown.additionalProperties - .tryGetMap('org.matrix.msc2965.authentication') - ?.tryGet('account'); - } - @override Widget build(BuildContext context) { final client = Matrix.of(context).client; diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 9b4478520..e5c678ff2 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -8,11 +8,13 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/common/config/environment.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:fluffychat/widgets/navigation_rail.dart'; import 'settings.dart'; class SettingsView extends StatelessWidget { @@ -26,279 +28,330 @@ class SettingsView extends StatelessWidget { // #Pangea // final showChatBackupBanner = controller.showChatBackupBanner; // Pangea# - return Scaffold( - appBar: AppBar( - leading: Center( - child: CloseButton( - onPressed: () => context.go('/rooms'), + final activeRoute = + GoRouter.of(context).routeInformationProvider.value.uri.path; + // #Pangea + // final accountManageUrl = Matrix.of(context) + // .client + // .wellKnown + // ?.additionalProperties + // .tryGetMap('org.matrix.msc2965.authentication') + // ?.tryGet('account'); + // Pangea# + return Row( + children: [ + if (FluffyThemes.isColumnMode(context)) ...[ + SpacesNavigationRail( + activeSpaceId: null, + onGoToChats: () => context.go('/rooms'), + onGoToSpaceId: (spaceId) => context.go('/rooms?spaceId=$spaceId'), + ), + Container( + color: Theme.of(context).dividerColor, + width: 1, + ), + ], + Expanded( + child: Scaffold( + appBar: FluffyThemes.isColumnMode(context) + ? null + : AppBar( + title: Text(L10n.of(context).settings), + leading: Center( + child: BackButton( + onPressed: () => context.go('/rooms'), + ), + ), + ), + body: ListTileTheme( + iconColor: theme.colorScheme.onSurface, + child: ListView( + key: const Key('SettingsListViewContent'), + children: [ + FutureBuilder( + future: controller.profileFuture, + builder: (context, snapshot) { + final profile = snapshot.data; + final mxid = Matrix.of(context).client.userID ?? + L10n.of(context).user; + final displayname = + profile?.displayName ?? mxid.localpart ?? mxid; + return Row( + children: [ + Padding( + padding: const EdgeInsets.all(32.0), + child: Stack( + children: [ + Avatar( + mxContent: profile?.avatarUrl, + name: displayname, + // #Pangea + presenceUserId: profile?.userId, + // Pangea# + size: Avatar.defaultSize * 2.5, + ), + if (profile != null) + Positioned( + bottom: 0, + right: 0, + child: FloatingActionButton.small( + elevation: 2, + onPressed: controller.setAvatarAction, + heroTag: null, + child: const Icon( + Icons.camera_alt_outlined, + ), + ), + ), + ], + ), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextButton.icon( + onPressed: controller.setDisplaynameAction, + icon: const Icon( + Icons.edit_outlined, + size: 16, + ), + style: TextButton.styleFrom( + foregroundColor: + theme.colorScheme.onSurface, + iconColor: theme.colorScheme.onSurface, + ), + label: Text( + displayname, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 18, + ), + ), + ), + TextButton.icon( + onPressed: () => + FluffyShare.share(mxid, context), + icon: const Icon( + Icons.copy_outlined, + size: 14, + ), + style: TextButton.styleFrom( + foregroundColor: + theme.colorScheme.secondary, + iconColor: theme.colorScheme.secondary, + ), + label: Text( + mxid, + maxLines: 1, + overflow: TextOverflow.ellipsis, + // style: const TextStyle(fontSize: 12), + ), + ), + ], + ), + ), + ], + ); + }, + ), + // #Pangea + // if (accountManageUrl != null) + // ListTile( + // leading: const Icon(Icons.account_circle_outlined), + // title: Text(L10n.of(context).manageAccount), + // trailing: const Icon(Icons.open_in_new_outlined), + // onTap: () => launchUrlString( + // accountManageUrl, + // mode: LaunchMode.inAppBrowserView, + // ), + // ), + // Divider(color: theme.dividerColor), + // if (showChatBackupBanner == null) + // ListTile( + // leading: const Icon(Icons.backup_outlined), + // title: Text(L10n.of(context).chatBackup), + // trailing: const CircularProgressIndicator.adaptive(), + // ) + // else + // SwitchListTile.adaptive( + // controlAffinity: ListTileControlAffinity.trailing, + // value: controller.showChatBackupBanner == false, + // secondary: const Icon(Icons.backup_outlined), + // title: Text(L10n.of(context).chatBackup), + // onChanged: controller.firstRunBootstrapAction, + // ), + // Divider( + // color: theme.dividerColor, + // ), + // Pangea# + ListTile( + leading: const Icon(Icons.format_paint_outlined), + title: Text(L10n.of(context).changeTheme), + tileColor: activeRoute.startsWith('/rooms/settings/style') + ? theme.colorScheme.surfaceContainerHigh + : null, + onTap: () => context.go('/rooms/settings/style'), + ), + ListTile( + leading: const Icon(Icons.notifications_outlined), + title: Text(L10n.of(context).notifications), + tileColor: + activeRoute.startsWith('/rooms/settings/notifications') + ? theme.colorScheme.surfaceContainerHigh + : null, + onTap: () => context.go('/rooms/settings/notifications'), + ), + ListTile( + leading: const Icon(Icons.devices_outlined), + title: Text(L10n.of(context).devices), + onTap: () => context.go('/rooms/settings/devices'), + tileColor: activeRoute.startsWith('/rooms/settings/devices') + ? theme.colorScheme.surfaceContainerHigh + : null, + ), + ListTile( + leading: const Icon(Icons.forum_outlined), + title: Text(L10n.of(context).chat), + onTap: () => context.go('/rooms/settings/chat'), + tileColor: activeRoute.startsWith('/rooms/settings/chat') + ? theme.colorScheme.surfaceContainerHigh + : null, + ), + // #Pangea + ListTile( + leading: const Icon(Icons.account_circle_outlined), + title: Text(L10n.of(context).subscriptionManagement), + onTap: () => context.go('/rooms/settings/subscription'), + tileColor: + activeRoute.startsWith('/rooms/settings/subscription') + ? theme.colorScheme.surfaceContainerHigh + : null, + ), + // Pangea# + ListTile( + leading: const Icon(Icons.shield_outlined), + title: Text(L10n.of(context).security), + onTap: () => context.go('/rooms/settings/security'), + tileColor: + activeRoute.startsWith('/rooms/settings/security') + ? theme.colorScheme.surfaceContainerHigh + : null, + ), + Divider(color: theme.dividerColor), + // #Pangea + ListTile( + leading: const Icon(Icons.help_outline_outlined), + title: Text(L10n.of(context).help), + onTap: () async { + await showFutureLoadingDialog( + context: context, + future: () async { + final roomId = + await Matrix.of(context).client.startDirectChat( + Environment.supportUserId, + enableEncryption: false, + ); + context.go('/rooms/$roomId'); + }, + ); + }, + ), + ListTile( + leading: const Icon(Icons.shield_outlined), + title: Text(L10n.of(context).termsAndConditions), + onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), + trailing: const Icon(Icons.open_in_new_outlined), + ), + FutureBuilder( + future: PackageInfo.fromPlatform(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return ListTile( + leading: const Icon(Icons.info_outline), + trailing: const Icon(Icons.copy_outlined), + onTap: () async { + if (snapshot.data == null) return; + await Clipboard.setData( + ClipboardData( + text: + "${snapshot.data!.version}+${snapshot.data!.buildNumber}", + ), + ); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: + Text(L10n.of(context).copiedToClipboard), + ), + ); + }, + title: Text( + snapshot.data != null + ? L10n.of(context).versionText( + snapshot.data!.version, + snapshot.data!.buildNumber, + ) + : L10n.of(context).versionNotFound, + ), + ); + } else if (snapshot.hasError) { + return ListTile( + leading: const Icon(Icons.error_outline), + title: Text(L10n.of(context).versionFetchError), + ); + } else { + return ListTile( + leading: const CircularProgressIndicator(), + title: Text(L10n.of(context).fetchingVersion), + ); + } + }, + ), + // Conditional ListTile based on the environment (staging or not) + if (Environment.isStaging) + ListTile( + leading: const Icon(Icons.bug_report_outlined), + title: Text(L10n.of(context).connectedToStaging), + ), + // ListTile( + // leading: const Icon(Icons.dns_outlined), + // title: Text( + // L10n.of(context).aboutHomeserver( + // Matrix.of(context).client.userID?.domain ?? + // 'homeserver', + // ), + // ), + // onTap: () => context.go('/rooms/settings/homeserver'), + // tileColor: + // activeRoute.startsWith('/rooms/settings/homeserver') + // ? theme.colorScheme.surfaceContainerHigh + // : null, + // ), + // ListTile( + // leading: const Icon(Icons.privacy_tip_outlined), + // title: Text(L10n.of(context).privacy), + // onTap: () => launchUrlString(AppConfig.privacyUrl), + // ), + // ListTile( + // leading: const Icon(Icons.info_outline_rounded), + // title: Text(L10n.of(context).about), + // onTap: () => PlatformInfos.showDialog(context), + // ), + // Pangea# + Divider(color: theme.dividerColor), + ListTile( + leading: const Icon(Icons.logout_outlined), + title: Text(L10n.of(context).logout), + onTap: controller.logoutAction, + ), + ], + ), + ), ), ), - title: Text(L10n.of(context).settings), - ), - body: ListTileTheme( - iconColor: theme.colorScheme.onSurface, - child: FutureBuilder( - future: controller.getOidcAccountManageUrl(), - builder: (context, snapshot) { - // #Pangea - // final accountManageUrl = snapshot.data; - // Pangea# - return ListView( - key: const Key('SettingsListViewContent'), - children: [ - FutureBuilder( - future: controller.profileFuture, - builder: (context, snapshot) { - final profile = snapshot.data; - final mxid = Matrix.of(context).client.userID ?? - L10n.of(context).user; - final displayname = - profile?.displayName ?? mxid.localpart ?? mxid; - return Row( - children: [ - Padding( - padding: const EdgeInsets.all(32.0), - child: Stack( - children: [ - Avatar( - mxContent: profile?.avatarUrl, - name: displayname, - // #Pangea - presenceUserId: profile?.userId, - // Pangea# - size: Avatar.defaultSize * 2.5, - ), - if (profile != null) - Positioned( - bottom: 0, - right: 0, - child: FloatingActionButton.small( - elevation: 2, - onPressed: controller.setAvatarAction, - heroTag: null, - child: - const Icon(Icons.camera_alt_outlined), - ), - ), - ], - ), - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextButton.icon( - onPressed: controller.setDisplaynameAction, - icon: const Icon( - Icons.edit_outlined, - size: 16, - ), - style: TextButton.styleFrom( - foregroundColor: theme.colorScheme.onSurface, - iconColor: theme.colorScheme.onSurface, - ), - label: Text( - displayname, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 18, - ), - ), - ), - TextButton.icon( - onPressed: () => - FluffyShare.share(mxid, context), - icon: const Icon( - Icons.copy_outlined, - size: 14, - ), - style: TextButton.styleFrom( - foregroundColor: theme.colorScheme.secondary, - iconColor: theme.colorScheme.secondary, - ), - label: Text( - mxid, - maxLines: 1, - overflow: TextOverflow.ellipsis, - // style: const TextStyle(fontSize: 12), - ), - ), - ], - ), - ), - ], - ); - }, - ), - // #Pangea - // if (accountManageUrl != null) - // ListTile( - // leading: const Icon(Icons.account_circle_outlined), - // title: Text(L10n.of(context).manageAccount), - // trailing: const Icon(Icons.open_in_new_outlined), - // onTap: () => launchUrlString( - // accountManageUrl, - // mode: LaunchMode.inAppBrowserView, - // ), - // ), - // Divider(color: theme.dividerColor), - // if (showChatBackupBanner == null) - // ListTile( - // leading: const Icon(Icons.backup_outlined), - // title: Text(L10n.of(context).chatBackup), - // trailing: const CircularProgressIndicator.adaptive(), - // ) - // else - // SwitchListTile.adaptive( - // controlAffinity: ListTileControlAffinity.trailing, - // value: controller.showChatBackupBanner == false, - // secondary: const Icon(Icons.backup_outlined), - // title: Text(L10n.of(context).chatBackup), - // onChanged: controller.firstRunBootstrapAction, - // ), - // Divider( - // color: theme.dividerColor, - // ), - // Pangea# - ListTile( - leading: const Icon(Icons.format_paint_outlined), - title: Text(L10n.of(context).changeTheme), - onTap: () => context.go('/rooms/settings/style'), - ), - ListTile( - leading: const Icon(Icons.notifications_outlined), - title: Text(L10n.of(context).notifications), - onTap: () => context.go('/rooms/settings/notifications'), - ), - ListTile( - leading: const Icon(Icons.devices_outlined), - title: Text(L10n.of(context).devices), - onTap: () => context.go('/rooms/settings/devices'), - ), - ListTile( - leading: const Icon(Icons.forum_outlined), - title: Text(L10n.of(context).chat), - onTap: () => context.go('/rooms/settings/chat'), - ), - // #Pangea - ListTile( - leading: const Icon(Icons.account_circle_outlined), - title: Text(L10n.of(context).subscriptionManagement), - onTap: () => context.go('/rooms/settings/subscription'), - ), - // Pangea# - ListTile( - leading: const Icon(Icons.shield_outlined), - title: Text(L10n.of(context).security), - onTap: () => context.go('/rooms/settings/security'), - ), - Divider(color: theme.dividerColor), - // #Pangea - // ListTile( - // leading: const Icon(Icons.dns_outlined), - // title: Text( - // L10n.of(context).aboutHomeserver( - // Matrix.of(context).client.userID?.domain ?? 'homeserver', - // ), - // ), - // onTap: () => context.go('/rooms/settings/homeserver'), - // ), - ListTile( - leading: const Icon(Icons.help_outline_outlined), - title: Text(L10n.of(context).help), - onTap: () async { - await showFutureLoadingDialog( - context: context, - future: () async { - final roomId = - await Matrix.of(context).client.startDirectChat( - Environment.supportUserId, - enableEncryption: false, - ); - context.go('/rooms/$roomId'); - }, - ); - }, - ), - // ListTile( - // leading: const Icon(Icons.shield_sharp), - // title: Text(L10n.of(context).privacy), - // onTap: () => launchUrlString(AppConfig.privacyUrl), - // ), - // ListTile( - // leading: const Icon(Icons.info_outline_rounded), - // title: Text(L10n.of(context).about), - // onTap: () => PlatformInfos.showDialog(context), - // ), - ListTile( - leading: const Icon(Icons.shield_outlined), - title: Text(L10n.of(context).termsAndConditions), - onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), - trailing: const Icon(Icons.open_in_new_outlined), - ), - FutureBuilder( - future: PackageInfo.fromPlatform(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return ListTile( - leading: const Icon(Icons.info_outline), - trailing: const Icon(Icons.copy_outlined), - onTap: () async { - if (snapshot.data == null) return; - await Clipboard.setData( - ClipboardData( - text: - "${snapshot.data!.version}+${snapshot.data!.buildNumber}", - ), - ); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context).copiedToClipboard), - ), - ); - }, - title: Text( - snapshot.data != null - ? L10n.of(context).versionText( - snapshot.data!.version, - snapshot.data!.buildNumber, - ) - : L10n.of(context).versionNotFound, - ), - ); - } else if (snapshot.hasError) { - return ListTile( - leading: const Icon(Icons.error_outline), - title: Text(L10n.of(context).versionFetchError), - ); - } else { - return ListTile( - leading: const CircularProgressIndicator(), - title: Text(L10n.of(context).fetchingVersion), - ); - } - }, - ), - // Conditional ListTile based on the environment (staging or not) - if (Environment.isStaging) - ListTile( - leading: const Icon(Icons.bug_report_outlined), - title: Text(L10n.of(context).connectedToStaging), - ), - // Pangea# - Divider(color: theme.dividerColor), - ListTile( - leading: const Icon(Icons.logout_outlined), - title: Text(L10n.of(context).logout), - onTap: controller.logoutAction, - ), - ], - ); - }, - ), - ), + ], ); } } diff --git a/lib/pages/settings_chat/settings_chat_view.dart b/lib/pages/settings_chat/settings_chat_view.dart index 0e6d45940..fa165ecfd 100644 --- a/lib/pages/settings_chat/settings_chat_view.dart +++ b/lib/pages/settings_chat/settings_chat_view.dart @@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/settings_switch_list_tile.dart'; @@ -18,7 +19,11 @@ class SettingsChatView extends StatelessWidget { final theme = Theme.of(context); return Scaffold( - appBar: AppBar(title: Text(L10n.of(context).chat)), + appBar: AppBar( + title: Text(L10n.of(context).chat), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), + ), body: ListTileTheme( iconColor: theme.textTheme.bodyLarge!.color, child: MaxWidthBody( @@ -114,16 +119,6 @@ class SettingsChatView extends StatelessWidget { // storeKey: SettingKeys.experimentalVoip, // defaultValue: AppConfig.experimentalVoip, // ), - // if (PlatformInfos.isMobile) - // ListTile( - // title: Text(L10n.of(context).callingPermissions), - // onTap: () => - // CallKeepManager().checkoutPhoneAccountSetting(context), - // trailing: const Padding( - // padding: EdgeInsets.all(16.0), - // child: Icon(Icons.call), - // ), - // ), // Pangea# ], ), diff --git a/lib/pages/settings_homeserver/settings_homeserver_view.dart b/lib/pages/settings_homeserver/settings_homeserver_view.dart index 59ee61c96..6de7102e8 100644 --- a/lib/pages/settings_homeserver/settings_homeserver_view.dart +++ b/lib/pages/settings_homeserver/settings_homeserver_view.dart @@ -8,6 +8,7 @@ import 'package:matrix/matrix.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import '../../widgets/matrix.dart'; @@ -26,14 +27,15 @@ class SettingsHomeserverView extends StatelessWidget { return Scaffold( appBar: AppBar( - leading: const Center(child: BackButton()), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), title: Text( L10n.of(context) .aboutHomeserver(client.userID?.domain ?? 'Homeserver'), ), ), body: MaxWidthBody( - withScrolling: false, + withScrolling: true, child: SelectionArea( child: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/pages/settings_notifications/push_rule_extensions.dart b/lib/pages/settings_notifications/push_rule_extensions.dart new file mode 100644 index 000000000..59dd6997a --- /dev/null +++ b/lib/pages/settings_notifications/push_rule_extensions.dart @@ -0,0 +1,121 @@ +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +extension PushRuleExtension on PushRule { + String getPushRuleName(L10n l10n) { + switch (ruleId) { + case '.m.rule.contains_user_name': + return l10n.notificationRuleContainsUserName; + case '.m.rule.master': + return l10n.notificationRuleMaster; + case '.m.rule.suppress_notices': + return l10n.notificationRuleSuppressNotices; + case '.m.rule.invite_for_me': + return l10n.notificationRuleInviteForMe; + case '.m.rule.member_event': + return l10n.notificationRuleMemberEvent; + case '.m.rule.is_user_mention': + return l10n.notificationRuleIsUserMention; + case '.m.rule.contains_display_name': + return l10n.notificationRuleContainsDisplayName; + case '.m.rule.is_room_mention': + return l10n.notificationRuleIsRoomMention; + case '.m.rule.roomnotif': + return l10n.notificationRuleRoomnotif; + case '.m.rule.tombstone': + return l10n.notificationRuleTombstone; + case '.m.rule.reaction': + return l10n.notificationRuleReaction; + case '.m.rule.room_server_acl': + return l10n.notificationRuleRoomServerAcl; + case '.m.rule.suppress_edits': + return l10n.notificationRuleSuppressEdits; + case '.m.rule.call': + return l10n.notificationRuleCall; + case '.m.rule.encrypted_room_one_to_one': + return l10n.notificationRuleEncryptedRoomOneToOne; + case '.m.rule.room_one_to_one': + return l10n.notificationRuleRoomOneToOne; + case '.m.rule.message': + return l10n.notificationRuleMessage; + case '.m.rule.encrypted': + return l10n.notificationRuleEncrypted; + case '.m.rule.room.server_acl': + return l10n.notificationRuleServerAcl; + case '.im.vector.jitsi': + return l10n.notificationRuleJitsi; + default: + return ruleId.split('.').last.replaceAll('_', ' ').capitalize(); + } + } + + String getPushRuleDescription(L10n l10n) { + switch (ruleId) { + case '.m.rule.contains_user_name': + return l10n.notificationRuleContainsUserNameDescription; + case '.m.rule.master': + return l10n.notificationRuleMasterDescription; + case '.m.rule.suppress_notices': + return l10n.notificationRuleSuppressNoticesDescription; + case '.m.rule.invite_for_me': + return l10n.notificationRuleInviteForMeDescription; + case '.m.rule.member_event': + return l10n.notificationRuleMemberEventDescription; + case '.m.rule.is_user_mention': + return l10n.notificationRuleIsUserMentionDescription; + case '.m.rule.contains_display_name': + return l10n.notificationRuleContainsDisplayNameDescription; + case '.m.rule.is_room_mention': + return l10n.notificationRuleIsRoomMentionDescription; + case '.m.rule.roomnotif': + return l10n.notificationRuleRoomnotifDescription; + case '.m.rule.tombstone': + return l10n.notificationRuleTombstoneDescription; + case '.m.rule.reaction': + return l10n.notificationRuleReactionDescription; + case '.m.rule.room_server_acl': + return l10n.notificationRuleRoomServerAclDescription; + case '.m.rule.suppress_edits': + return l10n.notificationRuleSuppressEditsDescription; + case '.m.rule.call': + return l10n.notificationRuleCallDescription; + case '.m.rule.encrypted_room_one_to_one': + return l10n.notificationRuleEncryptedRoomOneToOneDescription; + case '.m.rule.room_one_to_one': + return l10n.notificationRuleRoomOneToOneDescription; + case '.m.rule.message': + return l10n.notificationRuleMessageDescription; + case '.m.rule.encrypted': + return l10n.notificationRuleEncryptedDescription; + case '.m.rule.room.server_acl': + return l10n.notificationRuleServerAclDescription; + case '.im.vector.jitsi': + return l10n.notificationRuleJitsiDescription; + default: + return l10n.unknownPushRule(ruleId); + } + } +} + +extension PushRuleKindLocal on PushRuleKind { + String localized(L10n l10n) { + switch (this) { + case PushRuleKind.content: + return l10n.contentNotificationSettings; + case PushRuleKind.override: + return l10n.generalNotificationSettings; + case PushRuleKind.room: + return l10n.roomNotificationSettings; + case PushRuleKind.sender: + return l10n.userSpecificNotificationSettings; + case PushRuleKind.underride: + return l10n.otherNotificationSettings; + } + } +} + +extension on String { + String capitalize() { + return "${this[0].toUpperCase()}${substring(1).toLowerCase()}"; + } +} diff --git a/lib/pages/settings_notifications/settings_notifications.dart b/lib/pages/settings_notifications/settings_notifications.dart index 772cdef5a..887d0246c 100644 --- a/lib/pages/settings_notifications/settings_notifications.dart +++ b/lib/pages/settings_notifications/settings_notifications.dart @@ -1,59 +1,20 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; -import 'package:collection/collection.dart' show IterableExtension; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pages/settings_notifications/push_rule_extensions.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import '../../widgets/matrix.dart'; import 'settings_notifications_view.dart'; -class NotificationSettingsItem { - final PushRuleKind type; - final String key; - final String Function(BuildContext) title; - const NotificationSettingsItem(this.type, this.key, this.title); - static List items = [ - NotificationSettingsItem( - PushRuleKind.underride, - '.m.rule.message', - (c) => L10n.of(c).allRooms, - ), - NotificationSettingsItem( - PushRuleKind.underride, - '.m.rule.room_one_to_one', - (c) => L10n.of(c).directChats, - ), - NotificationSettingsItem( - PushRuleKind.override, - '.m.rule.contains_display_name', - (c) => L10n.of(c).containsDisplayName, - ), - NotificationSettingsItem( - PushRuleKind.content, - '.m.rule.contains_user_name', - (c) => L10n.of(c).containsUserName, - ), - NotificationSettingsItem( - PushRuleKind.override, - '.m.rule.invite_for_me', - (c) => L10n.of(c).inviteForMe, - ), - NotificationSettingsItem( - PushRuleKind.override, - '.m.rule.member_event', - (c) => L10n.of(c).memberChanges, - ), - NotificationSettingsItem( - PushRuleKind.override, - '.m.rule.suppress_notices', - (c) => L10n.of(c).botMessages, - ), - ]; -} - class SettingsNotifications extends StatefulWidget { const SettingsNotifications({super.key}); @@ -63,80 +24,8 @@ class SettingsNotifications extends StatefulWidget { } class SettingsNotificationsController extends State { - bool? getNotificationSetting(NotificationSettingsItem item) { - final pushRules = Matrix.of(context).client.globalPushRules; - if (pushRules == null) return null; - switch (item.type) { - case PushRuleKind.content: - return pushRules.content - ?.singleWhereOrNull((r) => r.ruleId == item.key) - ?.enabled; - case PushRuleKind.override: - return pushRules.override - ?.singleWhereOrNull((r) => r.ruleId == item.key) - ?.enabled; - case PushRuleKind.room: - return pushRules.room - ?.singleWhereOrNull((r) => r.ruleId == item.key) - ?.enabled; - case PushRuleKind.sender: - return pushRules.sender - ?.singleWhereOrNull((r) => r.ruleId == item.key) - ?.enabled; - case PushRuleKind.underride: - return pushRules.underride - ?.singleWhereOrNull((r) => r.ruleId == item.key) - ?.enabled; - } - } - bool isLoading = false; - void setNotificationSetting( - NotificationSettingsItem item, - bool enabled, - ) async { - final scaffoldMessenger = ScaffoldMessenger.of(context); - setState(() { - isLoading = true; - }); - try { - await Matrix.of(context).client.setPushRuleEnabled( - item.type, - item.key, - enabled, - ); - } catch (e, s) { - Logs().w('Unable to change notification settings', e, s); - scaffoldMessenger - .showSnackBar(SnackBar(content: Text(e.toLocalizedString(context)))); - } finally { - setState(() { - isLoading = false; - }); - } - } - - void onToggleMuteAllNotifications() async { - final scaffoldMessenger = ScaffoldMessenger.of(context); - setState(() { - isLoading = true; - }); - try { - await Matrix.of(context).client.setMuteAllPushNotifications( - !Matrix.of(context).client.allPushNotificationsMuted, - ); - } catch (e, s) { - Logs().w('Unable to change notification settings', e, s); - scaffoldMessenger - .showSnackBar(SnackBar(content: Text(e.toLocalizedString(context)))); - } finally { - setState(() { - isLoading = false; - }); - } - } - void onPusherTap(Pusher pusher) async { final delete = await showModalActionPopup( context: context, @@ -172,6 +61,146 @@ class SettingsNotificationsController extends State { Future?>? pusherFuture; + void togglePushRule(PushRuleKind kind, PushRule pushRule) async { + setState(() { + isLoading = true; + }); + try { + final updateFromSync = Matrix.of(context) + .client + .onSync + .stream + .where( + (syncUpdate) => + syncUpdate.accountData?.any( + (accountData) => accountData.type == 'm.push_rules', + ) ?? + false, + ) + .first; + await Matrix.of(context).client.setPushRuleEnabled( + kind, + pushRule.ruleId, + !pushRule.enabled, + ); + await updateFromSync; + } catch (e, s) { + Logs().w('Unable to toggle push rule', e, s); + if (!mounted) return; + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(e.toLocalizedString(context)))); + } finally { + if (mounted) { + setState(() { + isLoading = false; + }); + } + } + } + + void editPushRule(PushRule rule, PushRuleKind kind) async { + final theme = Theme.of(context); + final action = await showAdaptiveDialog( + context: context, + builder: (context) => ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256), + child: AlertDialog.adaptive( + title: Text(rule.getPushRuleName(L10n.of(context))), + content: Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Material( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + color: theme.colorScheme.surfaceContainer, + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + scrollDirection: Axis.horizontal, + child: SelectableText( + prettyJson(rule.toJson()), + style: TextStyle( + color: theme.colorScheme.onSurface, + ), + ), + ), + ), + ), + actions: [ + AdaptiveDialogAction( + onPressed: Navigator.of(context).pop, + child: Text(L10n.of(context).close), + ), + if (!rule.ruleId.startsWith('.m.')) + AdaptiveDialogAction( + onPressed: () => + Navigator.of(context).pop(PushRuleDialogAction.delete), + child: Text( + L10n.of(context).delete, + style: TextStyle(color: theme.colorScheme.error), + ), + ), + ], + ), + ), + ); + if (action == null) return; + if (!mounted) return; + switch (action) { + case PushRuleDialogAction.delete: + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context).areYouSure, + message: L10n.of(context).deletePushRuleCanNotBeUndone, + okLabel: L10n.of(context).delete, + isDestructive: true, + ); + if (consent != OkCancelResult.ok) return; + if (!mounted) return; + setState(() { + isLoading = true; + }); + try { + final updateFromSync = Matrix.of(context) + .client + .onSync + .stream + .where( + (syncUpdate) => + syncUpdate.accountData?.any( + (accountData) => accountData.type == 'm.push_rules', + ) ?? + false, + ) + .first; + await Matrix.of(context).client.deletePushRule( + kind, + rule.ruleId, + ); + await updateFromSync; + } catch (e, s) { + Logs().w('Unable to delete push rule', e, s); + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(e.toLocalizedString(context))), + ); + } finally { + if (mounted) { + setState(() { + isLoading = false; + }); + } + } + return; + } + } + @override Widget build(BuildContext context) => SettingsNotificationsView(this); } + +enum PushRuleDialogAction { delete } + +String prettyJson(Map json) { + const decoder = JsonDecoder(); + const encoder = JsonEncoder.withIndent(' '); + final object = decoder.convert(jsonEncode(json)); + return encoder.convert(object); +} diff --git a/lib/pages/settings_notifications/settings_notifications_view.dart b/lib/pages/settings_notifications/settings_notifications_view.dart index ed934c539..63bd3a166 100644 --- a/lib/pages/settings_notifications/settings_notifications_view.dart +++ b/lib/pages/settings_notifications/settings_notifications_view.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/settings_notifications/push_rule_extensions.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import '../../utils/localized_exception_extension.dart'; import '../../widgets/matrix.dart'; @@ -15,9 +17,21 @@ class SettingsNotificationsView extends StatelessWidget { @override Widget build(BuildContext context) { + final pushRules = Matrix.of(context).client.globalPushRules; + final pushCategories = [ + if (pushRules?.override?.isNotEmpty ?? false) + (rules: pushRules?.override ?? [], kind: PushRuleKind.override), + if (pushRules?.content?.isNotEmpty ?? false) + (rules: pushRules?.content ?? [], kind: PushRuleKind.content), + if (pushRules?.sender?.isNotEmpty ?? false) + (rules: pushRules?.sender ?? [], kind: PushRuleKind.sender), + if (pushRules?.underride?.isNotEmpty ?? false) + (rules: pushRules?.underride ?? [], kind: PushRuleKind.underride), + ]; return Scaffold( appBar: AppBar( - leading: const Center(child: BackButton()), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), title: Text(L10n.of(context).notifications), ), body: MaxWidthBody( @@ -31,92 +45,121 @@ class SettingsNotificationsView extends StatelessWidget { ), builder: (BuildContext context, _) { final theme = Theme.of(context); - return Column( - children: [ - SwitchListTile.adaptive( - value: !Matrix.of(context).client.allPushNotificationsMuted, - title: Text( - L10n.of(context).notificationsEnabledForThisAccount, - ), - onChanged: controller.isLoading - ? null - : (_) => controller.onToggleMuteAllNotifications(), - ), - Divider(color: theme.dividerColor), - ListTile( - title: Text( - L10n.of(context).notifyMeFor, - style: TextStyle( - color: theme.colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - ), - for (final item in NotificationSettingsItem.items) - SwitchListTile.adaptive( - value: Matrix.of(context).client.allPushNotificationsMuted - ? false - : controller.getNotificationSetting(item) ?? true, - title: Text(item.title(context)), - onChanged: controller.isLoading - ? null - : Matrix.of(context).client.allPushNotificationsMuted - ? null - : (bool enabled) => controller - .setNotificationSetting(item, enabled), - ), - Divider(color: theme.dividerColor), - ListTile( - title: Text( - L10n.of(context).devices, - style: TextStyle( - color: theme.colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - ), - FutureBuilder?>( - future: controller.pusherFuture ??= - Matrix.of(context).client.getPushers(), - builder: (context, snapshot) { - if (snapshot.hasError) { - Center( - child: Text( - snapshot.error!.toLocalizedString(context), - ), - ); - } - if (snapshot.connectionState != ConnectionState.done) { - const Center( - child: CircularProgressIndicator.adaptive( - strokeWidth: 2, - ), - ); - } - final pushers = snapshot.data ?? []; - if (pushers.isEmpty) { - return Center( - child: Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: Text(L10n.of(context).noOtherDevicesFound), - ), - ); - } - return ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: pushers.length, - itemBuilder: (_, i) => ListTile( + return SelectionArea( + child: Column( + children: [ + if (pushRules != null) + for (final category in pushCategories) ...[ + ListTile( title: Text( - '${pushers[i].appDisplayName} - ${pushers[i].appId}', + category.kind.localized(L10n.of(context)), + style: TextStyle( + color: theme.colorScheme.secondary, + fontWeight: FontWeight.bold, + ), ), - subtitle: Text(pushers[i].data.url.toString()), - onTap: () => controller.onPusherTap(pushers[i]), ), - ); - }, - ), - ], + for (final rule in category.rules) + ListTile( + title: Text(rule.getPushRuleName(L10n.of(context))), + subtitle: Text.rich( + TextSpan( + children: [ + TextSpan( + text: rule.getPushRuleDescription( + L10n.of(context), + ), + ), + const TextSpan(text: ' '), + WidgetSpan( + child: InkWell( + onTap: () => controller.editPushRule( + rule, + category.kind, + ), + child: Text( + L10n.of(context).more, + style: TextStyle( + color: theme.colorScheme.primary, + decoration: TextDecoration.underline, + decorationColor: + theme.colorScheme.primary, + ), + ), + ), + ), + ], + ), + ), + trailing: Switch.adaptive( + value: rule.enabled, + onChanged: controller.isLoading + ? null + : rule.ruleId != '.m.rule.master' && + Matrix.of(context) + .client + .allPushNotificationsMuted + ? null + : (_) => controller.togglePushRule( + category.kind, + rule, + ), + ), + ), + Divider(color: theme.dividerColor), + ], + ListTile( + title: Text( + L10n.of(context).devices, + style: TextStyle( + color: theme.colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + ), + FutureBuilder?>( + future: controller.pusherFuture ??= + Matrix.of(context).client.getPushers(), + builder: (context, snapshot) { + if (snapshot.hasError) { + Center( + child: Text( + snapshot.error!.toLocalizedString(context), + ), + ); + } + if (snapshot.connectionState != ConnectionState.done) { + const Center( + child: CircularProgressIndicator.adaptive( + strokeWidth: 2, + ), + ); + } + final pushers = snapshot.data ?? []; + if (pushers.isEmpty) { + return Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: Text(L10n.of(context).noOtherDevicesFound), + ), + ); + } + return ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: pushers.length, + itemBuilder: (_, i) => ListTile( + title: Text( + '${pushers[i].appDisplayName} - ${pushers[i].appId}', + ), + subtitle: Text(pushers[i].data.url.toString()), + onTap: () => controller.onPusherTap(pushers[i]), + ), + ); + }, + ), + ], + ), ); }, ), diff --git a/lib/pages/settings_security/settings_security.dart b/lib/pages/settings_security/settings_security.dart index ba03ebc06..af9a33dc1 100644 --- a/lib/pages/settings_security/settings_security.dart +++ b/lib/pages/settings_security/settings_security.dart @@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart'; import 'package:fluffychat/widgets/app_lock.dart'; @@ -135,6 +136,16 @@ class SettingsSecurityController extends State { Future dehydrateAction() => Matrix.of(context).dehydrateAction(context); + void changeShareKeysWith(ShareKeysWith? shareKeysWith) async { + if (shareKeysWith == null) return; + Matrix.of(context).store.setString( + SettingKeys.shareKeysWith, + shareKeysWith.name, + ); + Matrix.of(context).client.shareKeysWith = shareKeysWith; + setState(() {}); + } + @override Widget build(BuildContext context) => SettingsSecurityView(this); } diff --git a/lib/pages/settings_security/settings_security_view.dart b/lib/pages/settings_security/settings_security_view.dart index 28f8908ba..0861f1351 100644 --- a/lib/pages/settings_security/settings_security_view.dart +++ b/lib/pages/settings_security/settings_security_view.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/utils/beautify_string_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; @@ -21,7 +23,11 @@ class SettingsSecurityView extends StatelessWidget { final theme = Theme.of(context); return Scaffold( - appBar: AppBar(title: Text(L10n.of(context).security)), + appBar: AppBar( + title: Text(L10n.of(context).security), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), + ), body: ListTileTheme( iconColor: theme.colorScheme.onSurface, child: MaxWidthBody( @@ -88,6 +94,41 @@ class SettingsSecurityView extends StatelessWidget { ), }, Divider(color: theme.dividerColor), + ListTile( + title: Text( + L10n.of(context).shareKeysWith, + style: TextStyle( + color: theme.colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context).shareKeysWithDescription), + ), + ListTile( + title: Material( + borderRadius: + BorderRadius.circular(AppConfig.borderRadius / 2), + color: theme.colorScheme.onInverseSurface, + child: DropdownButton( + isExpanded: true, + padding: const EdgeInsets.symmetric(horizontal: 8.0), + borderRadius: + BorderRadius.circular(AppConfig.borderRadius / 2), + underline: const SizedBox.shrink(), + value: Matrix.of(context).client.shareKeysWith, + items: ShareKeysWith.values + .map( + (share) => DropdownMenuItem( + value: share, + child: Text(share.localized(L10n.of(context))), + ), + ) + .toList(), + onChanged: controller.changeShareKeysWith, + ), + ), + ), + Divider(color: theme.dividerColor), ListTile( title: Text( L10n.of(context).account, @@ -102,7 +143,7 @@ class SettingsSecurityView extends StatelessWidget { leading: const Icon(Icons.vpn_key_outlined), subtitle: SelectableText( Matrix.of(context).client.fingerprintKey.beautified, - style: const TextStyle(fontFamily: 'monospace'), + style: const TextStyle(fontFamily: 'UbuntuMono'), ), ), if (capabilities?.mChangePassword?.enabled != false || @@ -142,3 +183,18 @@ class SettingsSecurityView extends StatelessWidget { ); } } + +extension on ShareKeysWith { + String localized(L10n l10n) { + switch (this) { + case ShareKeysWith.all: + return l10n.allDevices; + case ShareKeysWith.crossVerifiedIfEnabled: + return l10n.crossVerifiedDevicesIfEnabled; + case ShareKeysWith.crossVerified: + return l10n.crossVerifiedDevices; + case ShareKeysWith.directlyVerifiedOnly: + return l10n.verifiedDevicesOnly; + } + } +} diff --git a/lib/pages/settings_style/settings_style_view.dart b/lib/pages/settings_style/settings_style_view.dart index d93e492fc..d234759df 100644 --- a/lib/pages/settings_style/settings_style_view.dart +++ b/lib/pages/settings_style/settings_style_view.dart @@ -32,7 +32,8 @@ class SettingsStyleView extends StatelessWidget { final client = Matrix.of(context).client; return Scaffold( appBar: AppBar( - leading: const Center(child: BackButton()), + automaticallyImplyLeading: !FluffyThemes.isColumnMode(context), + centerTitle: FluffyThemes.isColumnMode(context), title: Text(L10n.of(context).changeTheme), ), backgroundColor: theme.colorScheme.surface, @@ -214,9 +215,7 @@ class SettingsStyleView extends StatelessWidget { ), child: DecoratedBox( decoration: BoxDecoration( - color: theme.brightness == Brightness.light - ? theme.colorScheme.primary - : theme.colorScheme.primaryContainer, + color: theme.bubbleColor, borderRadius: BorderRadius.circular( AppConfig.borderRadius, ), @@ -229,11 +228,7 @@ class SettingsStyleView extends StatelessWidget { child: Text( 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor', style: TextStyle( - color: - theme.brightness == Brightness.light - ? theme.colorScheme.onPrimary - : theme.colorScheme - .onPrimaryContainer, + color: theme.onBubbleColor, fontSize: AppConfig.messageFontSize * AppConfig.fontSizeFactor, ), diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index eab05b554..7aa92f6ba 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; +import 'package:collection/collection.dart'; import 'package:desktop_notifications/desktop_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:hive_flutter/hive_flutter.dart'; @@ -12,6 +13,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; import 'package:fluffychat/utils/custom_http_client.dart'; @@ -43,7 +45,8 @@ abstract class ClientManager { clientNames.add(PlatformInfos.clientName); await store.setStringList(clientNamespace, clientNames.toList()); } - final clients = clientNames.map(createClient).toList(); + final clients = + clientNames.map((name) => createClient(name, store)).toList(); if (initialize) { await Future.wait( clients.map( @@ -99,7 +102,9 @@ abstract class ClientManager { ? const NativeImplementationsDummy() : NativeImplementationsIsolate(compute); - static Client createClient(String clientName) { + static Client createClient(String clientName, SharedPreferences store) { + final shareKeysWith = store.getString(SettingKeys.shareKeysWith) ?? 'all'; + return Client( clientName, httpClient: @@ -136,6 +141,10 @@ abstract class ClientManager { customImageResizer: PlatformInfos.isMobile ? customImageResizer : null, defaultNetworkRequestTimeout: const Duration(minutes: 30), enableDehydratedDevices: true, + shareKeysWith: ShareKeysWith.values + .singleWhereOrNull((share) => share.name == shareKeysWith) ?? + ShareKeysWith.all, + convertLinebreaksInFormatting: false, // #Pangea syncFilter: Filter( room: RoomFilter( diff --git a/lib/utils/room_status_extension.dart b/lib/utils/room_status_extension.dart index a54b003da..868e3f821 100644 --- a/lib/utils/room_status_extension.dart +++ b/lib/utils/room_status_extension.dart @@ -28,11 +28,10 @@ extension RoomStatusExtension on Room { typingUsers[1].calcDisplayname(), ); } else if (typingUsers.length > 2) { - typingText = L10n.of(context).isTyping; - if (typingUsers.first.id != directChatMatrixID) { - typingText = - L10n.of(context).userIsTyping(typingUsers.first.calcDisplayname()); - } + typingText = L10n.of(context).userAndOthersAreTyping( + typingUsers.first.calcDisplayname(), + (typingUsers.length - 1), + ); } return typingText; } diff --git a/lib/utils/sync_status_localization.dart b/lib/utils/sync_status_localization.dart index 0cccbc7b9..1ea8f14e1 100644 --- a/lib/utils/sync_status_localization.dart +++ b/lib/utils/sync_status_localization.dart @@ -6,21 +6,6 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; extension SyncStatusLocalization on SyncStatusUpdate { - IconData get icon { - switch (status) { - case SyncStatus.waitingForResponse: - return Icons.hourglass_empty_outlined; - case SyncStatus.error: - return Icons.cloud_off_outlined; - case SyncStatus.processing: - return Icons.hourglass_top_outlined; - case SyncStatus.cleaningUp: - return Icons.hourglass_bottom_outlined; - case SyncStatus.finished: - return Icons.hourglass_full_outlined; - } - } - String calcLocalizedString(BuildContext context) { final progress = this.progress; switch (status) { diff --git a/lib/widgets/adaptive_dialogs/dialog_text_field.dart b/lib/widgets/adaptive_dialogs/dialog_text_field.dart new file mode 100644 index 000000000..7b8e07b26 --- /dev/null +++ b/lib/widgets/adaptive_dialogs/dialog_text_field.dart @@ -0,0 +1,107 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class DialogTextField extends StatelessWidget { + final TextEditingController? controller; + final String? hintText; + final String? labelText; + final String? initialText; + final String? counterText; + final String? prefixText; + final String? suffixText; + final String? errorText; + final bool obscureText = false; + final bool isDestructive = false; + final int? minLines; + final int? maxLines; + final TextInputType? keyboardType; + final int? maxLength; + final bool autocorrect = true; + // #Pangea + final void Function(String)? onSubmitted; + // Pangea# + + const DialogTextField({ + super.key, + this.hintText, + this.labelText, + this.initialText, + this.prefixText, + this.suffixText, + this.minLines, + this.maxLines, + this.keyboardType, + this.maxLength, + this.controller, + this.counterText, + this.errorText, + // #Pangea + this.onSubmitted, + // Pangea# + }); + + @override + Widget build(BuildContext context) { + final prefixText = this.prefixText; + final suffixText = this.suffixText; + final errorText = this.errorText; + final theme = Theme.of(context); + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return TextField( + controller: controller, + obscureText: obscureText, + minLines: minLines, + maxLines: maxLines, + maxLength: maxLength, + keyboardType: keyboardType, + autocorrect: autocorrect, + decoration: InputDecoration( + errorText: errorText, + hintText: hintText, + labelText: labelText, + prefixText: prefixText, + suffixText: suffixText, + counterText: counterText, + ), + // #Pangea + onSubmitted: onSubmitted, + // Pangea# + ); + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + CupertinoTextField( + controller: controller, + obscureText: obscureText, + minLines: minLines, + maxLines: maxLines, + maxLength: maxLength, + keyboardType: keyboardType, + autocorrect: autocorrect, + prefix: prefixText != null ? Text(prefixText) : null, + suffix: suffixText != null ? Text(suffixText) : null, + placeholder: labelText ?? hintText, + // #Pangea + onSubmitted: onSubmitted, + // Pangea# + ), + if (errorText != null) + Text( + errorText, + style: TextStyle( + fontSize: 11, + color: theme.colorScheme.error, + ), + textAlign: TextAlign.left, + ), + ], + ); + } + } +} diff --git a/lib/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart b/lib/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart index c8fb53c38..8c2f861e4 100644 --- a/lib/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart +++ b/lib/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter_linkify/flutter_linkify.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; enum OkCancelResult { ok, cancel } @@ -25,7 +27,17 @@ Future showOkCancelAlertDialog({ ), content: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 256), - child: message == null ? null : Text(message), + child: message == null + ? null + : SelectableLinkify( + text: message, + linkStyle: TextStyle( + color: Theme.of(context).colorScheme.primary, + decorationColor: Theme.of(context).colorScheme.primary, + ), + options: const LinkifyOptions(humanize: false), + onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), + ), ), actions: [ AdaptiveDialogAction( @@ -65,7 +77,17 @@ Future showOkAlertDialog({ ), content: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 256), - child: message == null ? null : Text(message), + child: message == null + ? null + : SelectableLinkify( + text: message, + linkStyle: TextStyle( + color: Theme.of(context).colorScheme.primary, + decorationColor: Theme.of(context).colorScheme.primary, + ), + options: const LinkifyOptions(humanize: false), + onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), + ), ), actions: [ AdaptiveDialogAction( diff --git a/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart b/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart index 9f017b086..cd571fc2e 100644 --- a/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart +++ b/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart @@ -2,7 +2,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter_linkify/flutter_linkify.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; Future showTextInputDialog({ @@ -43,103 +45,111 @@ Future showTextInputDialog({ constraints: const BoxConstraints(maxWidth: 256), child: Text(title), ), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (message != null) - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 256), - child: Text(message), - ), - const SizedBox(height: 16), - ValueListenableBuilder( - valueListenable: error, - builder: (context, error, _) { - switch (theme.platform) { - case TargetPlatform.android: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.windows: - return TextField( - controller: controller, - obscureText: obscureText, - // #Pangea - // minLines: minLines, - // maxLines: maxLines, - minLines: autoSubmit ? 1 : minLines, - maxLines: autoSubmit ? 1 : maxLines, - onSubmitted: autoSubmit - ? (_) { - final input = controller.text; - final errorText = validator?.call(input); - if (errorText != null) { - error = errorText; - return; - } - Navigator.of(context).pop(input); - } - : null, - // Pangea# - maxLength: maxLength, - keyboardType: keyboardType, - autocorrect: autocorrect, - decoration: InputDecoration( - errorText: error, - hintText: hintText, - labelText: labelText, - prefixText: prefixText, - suffixText: suffixText, - ), - ); - case TargetPlatform.iOS: - case TargetPlatform.macOS: - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - CupertinoTextField( - controller: controller, - obscureText: obscureText, - // #Pangea - // minLines: minLines, - // maxLines: maxLines, - minLines: autoSubmit ? 1 : minLines, - maxLines: autoSubmit ? 1 : maxLines, - onSubmitted: autoSubmit - ? (_) { - final input = controller.text; - final errorText = validator?.call(input); - if (errorText != null) { - error = errorText; - return; - } - Navigator.of(context).pop(input); + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (message != null) + SelectableLinkify( + text: message, + linkStyle: TextStyle( + color: Theme.of(context).colorScheme.primary, + decorationColor: Theme.of(context).colorScheme.primary, + ), + options: const LinkifyOptions(humanize: false), + onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), + ), + const SizedBox(height: 16), + ValueListenableBuilder( + valueListenable: error, + builder: (context, error, _) { + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return TextField( + controller: controller, + obscureText: obscureText, + // #Pangea + // minLines: minLines, + // maxLines: maxLines, + minLines: autoSubmit ? 1 : minLines, + maxLines: autoSubmit ? 1 : maxLines, + onSubmitted: autoSubmit + ? (_) { + final input = controller.text; + final errorText = validator?.call(input); + if (errorText != null) { + error = errorText; + return; } - : null, - // Pangea# - maxLength: maxLength, - keyboardType: keyboardType, - autocorrect: autocorrect, - prefix: - prefixText != null ? Text(prefixText) : null, - suffix: - suffixText != null ? Text(suffixText) : null, - placeholder: labelText ?? hintText, + Navigator.of(context).pop(input); + } + : null, + // Pangea# + maxLength: maxLength, + keyboardType: keyboardType, + autocorrect: autocorrect, + decoration: InputDecoration( + errorText: error, + hintText: hintText, + labelText: labelText, + prefixText: prefixText, + suffixText: suffixText, ), - if (error != null) - Text( - error!, - style: TextStyle( - fontSize: 11, - color: theme.colorScheme.error, - ), - textAlign: TextAlign.left, + ); + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + CupertinoTextField( + controller: controller, + obscureText: obscureText, + // #Pangea + // minLines: minLines, + // maxLines: maxLines, + minLines: autoSubmit ? 1 : minLines, + maxLines: autoSubmit ? 1 : maxLines, + onSubmitted: autoSubmit + ? (_) { + final input = controller.text; + final errorText = validator?.call(input); + if (errorText != null) { + error = errorText; + return; + } + Navigator.of(context).pop(input); + } + : null, + // Pangea# + maxLength: maxLength, + keyboardType: keyboardType, + autocorrect: autocorrect, + prefix: + prefixText != null ? Text(prefixText) : null, + suffix: + suffixText != null ? Text(suffixText) : null, + placeholder: labelText ?? hintText, ), - ], - ); - } - }, - ), - ], + if (error != null) + Text( + error!, + style: TextStyle( + fontSize: 11, + color: theme.colorScheme.error, + ), + textAlign: TextAlign.left, + ), + ], + ); + } + }, + ), + ], + ), ), actions: [ AdaptiveDialogAction( diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 4b9ced80b..68a3c2d44 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -56,15 +56,14 @@ class ChatSettingsPopupMenuState extends State { switch (choice) { case ChatPopupMenuActions.leave: final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, context: context, title: L10n.of(context).areYouSure, - okLabel: L10n.of(context).ok, - cancelLabel: L10n.of(context).cancel, // #Pangea // message: L10n.of(context).archiveRoomDescription, message: L10n.of(context).leaveRoomDescription, // Pangea# + okLabel: L10n.of(context).leave, + cancelLabel: L10n.of(context).cancel, isDestructive: true, ); if (confirmed == OkCancelResult.ok) { diff --git a/lib/widgets/layouts/max_width_body.dart b/lib/widgets/layouts/max_width_body.dart index 4e44cc796..5720d94bb 100644 --- a/lib/widgets/layouts/max_width_body.dart +++ b/lib/widgets/layouts/max_width_body.dart @@ -34,12 +34,18 @@ class MaxWidthBody extends StatelessWidget { maxWidth: FluffyThemes.columnWidth * 1.5, ), child: Material( - elevation: theme.appBarTheme.scrolledUnderElevation ?? 4, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(AppConfig.borderRadius), + side: BorderSide( + color: theme.dividerColor, + ), + ), clipBehavior: Clip.hardEdge, - borderRadius: - BorderRadius.circular(AppConfig.borderRadius), - shadowColor: theme.appBarTheme.shadowColor, - child: child, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: child, + ), ), ), ); diff --git a/lib/widgets/layouts/two_column_layout.dart b/lib/widgets/layouts/two_column_layout.dart index 36e815ebb..86a6f56c5 100644 --- a/lib/widgets/layouts/two_column_layout.dart +++ b/lib/widgets/layouts/two_column_layout.dart @@ -5,13 +5,11 @@ import 'package:fluffychat/config/themes.dart'; class TwoColumnLayout extends StatelessWidget { final Widget mainView; final Widget sideView; - final bool displayNavigationRail; const TwoColumnLayout({ super.key, required this.mainView, required this.sideView, - required this.displayNavigationRail, }); @override Widget build(BuildContext context) { @@ -24,8 +22,7 @@ class TwoColumnLayout extends StatelessWidget { Container( clipBehavior: Clip.antiAlias, decoration: const BoxDecoration(), - width: FluffyThemes.columnWidth + - (displayNavigationRail ? FluffyThemes.navRailWidth : 0), + width: FluffyThemes.columnWidth + FluffyThemes.navRailWidth, child: mainView, ), Container( diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 40ae171b8..3f1673033 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -168,6 +168,7 @@ class MatrixState extends State with WidgetsBindingObserver { } final candidate = _loginClientCandidate ??= ClientManager.createClient( '${AppConfig.applicationName}-${DateTime.now().millisecondsSinceEpoch}', + store, )..onLoginStateChanged .stream .where((l) => l == LoginState.loggedIn) diff --git a/lib/widgets/navigation_rail.dart b/lib/widgets/navigation_rail.dart new file mode 100644 index 000000000..04be771e2 --- /dev/null +++ b/lib/widgets/navigation_rail.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat_list/navi_rail_item.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/utils/stream_extension.dart'; +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SpacesNavigationRail extends StatelessWidget { + final String? activeSpaceId; + final void Function() onGoToChats; + final void Function(String) onGoToSpaceId; + + const SpacesNavigationRail({ + required this.activeSpaceId, + required this.onGoToChats, + required this.onGoToSpaceId, + super.key, + }); + + @override + Widget build(BuildContext context) { + final client = Matrix.of(context).client; + final isSettings = GoRouter.of(context) + .routeInformationProvider + .value + .uri + .path + .startsWith('/rooms/settings'); + return StreamBuilder( + key: ValueKey( + client.userID.toString(), + ), + stream: client.onSync.stream + .where((s) => s.hasRoomUpdate) + .rateLimit(const Duration(seconds: 1)), + builder: (context, _) { + final allSpaces = client.rooms.where((room) => room.isSpace); + final rootSpaces = allSpaces + .where( + (space) => !allSpaces.any( + (parentSpace) => parentSpace.spaceChildren + .any((child) => child.roomId == space.id), + ), + ) + .toList(); + + return SizedBox( + width: FluffyThemes.navRailWidth, + child: Column( + children: [ + Expanded( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: rootSpaces.length + 2, + itemBuilder: (context, i) { + if (i == 0) { + return NaviRailItem( + isSelected: activeSpaceId == null && !isSettings, + onTap: onGoToChats, + icon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.forum_outlined), + ), + selectedIcon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.forum), + ), + toolTip: L10n.of(context).chats, + unreadBadgeFilter: (room) => true, + ); + } + i--; + if (i == rootSpaces.length) { + return NaviRailItem( + isSelected: false, + onTap: () => context.go('/rooms/newspace'), + icon: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon(Icons.add), + ), + toolTip: L10n.of(context).createNewSpace, + ); + } + final space = rootSpaces[i]; + final displayname = rootSpaces[i].getLocalizedDisplayname( + MatrixLocals(L10n.of(context)), + ); + final spaceChildrenIds = + space.spaceChildren.map((c) => c.roomId).toSet(); + return NaviRailItem( + toolTip: displayname, + isSelected: activeSpaceId == space.id, + onTap: () => onGoToSpaceId(rootSpaces[i].id), + unreadBadgeFilter: (room) => + spaceChildrenIds.contains(room.id), + icon: Avatar( + mxContent: rootSpaces[i].avatar, + name: displayname, + border: BorderSide( + width: 1, + color: Theme.of(context).dividerColor, + ), + borderRadius: BorderRadius.circular( + AppConfig.borderRadius / 2, + ), + ), + ); + }, + ), + ), + NaviRailItem( + isSelected: isSettings, + onTap: () => context.go('/rooms/settings'), + icon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.settings_outlined), + ), + selectedIcon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.settings), + ), + toolTip: L10n.of(context).settings, + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index cc9867c35..4a8178d7d 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -345,9 +345,9 @@ class PublicRoomBottomSheetState extends State { ListTile( subtitle: SelectableLinkify( text: profile!.topic!, - linkStyle: const TextStyle( - color: Colors.blueAccent, - decorationColor: Colors.blueAccent, + linkStyle: TextStyle( + color: theme.colorScheme.primary, + decorationColor: theme.colorScheme.primary, ), style: TextStyle( fontSize: 14, diff --git a/licenses.yaml b/licenses.yaml index ebab43440..02b7ad97e 100644 --- a/licenses.yaml +++ b/licenses.yaml @@ -25,6 +25,7 @@ packageLicenseOverride: latlong2: Apache-2.0 platform_detect: Apache-2.0 rxdart: Apache-2.0 + flutter_new_badger: MIT # flutter's internal packages flutter_driver: BSD-3-Clause diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 63e1af5cd..e8936458f 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,7 +7,6 @@ #include "generated_plugin_registrant.h" #include -#include #include #include #include @@ -26,9 +25,6 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); - g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin"); - desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar); g_autoptr(FlPluginRegistrar) dynamic_color_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 3273dcc88..f782b903e 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_linux - desktop_webview_window dynamic_color emoji_picker_flutter file_selector_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index b51c9c563..242556930 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,7 +8,6 @@ import Foundation import app_links import audio_session import audioplayers_darwin -import desktop_webview_window import device_info_plus import dynamic_color import emoji_picker_flutter @@ -47,7 +46,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) - DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) EmojiPickerFlutterPlugin.register(with: registry.registrar(forPlugin: "EmojiPickerFlutterPlugin")) diff --git a/pangea_packages/fcm_shared_isolate/.github/CODEOWNERS b/pangea_packages/fcm_shared_isolate/.github/CODEOWNERS new file mode 100644 index 000000000..f3d7629e3 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/.github/CODEOWNERS @@ -0,0 +1 @@ +* @famedly/instant-messaging \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/.gitignore b/pangea_packages/fcm_shared_isolate/.gitignore new file mode 100644 index 000000000..391def37e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +.dart_tool/ +.idea/ + +.packages +.pub/ +pubspec.lock +.flutter-plugins* + +build/ diff --git a/pangea_packages/fcm_shared_isolate/.gitlab-ci.yml b/pangea_packages/fcm_shared_isolate/.gitlab-ci.yml new file mode 100644 index 000000000..615c3cab9 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/.gitlab-ci.yml @@ -0,0 +1,13 @@ +image: registry.gitlab.com/famedly/company/frontend/flutter-dockerimages/flutter/stable + +stages: + - test + +code_analyze: + tags: + - docker + stage: test + script: + - flutter pub get + - flutter format --set-exit-if-changed lib/ test/ + - flutter analyze diff --git a/pangea_packages/fcm_shared_isolate/.metadata b/pangea_packages/fcm_shared_isolate/.metadata new file mode 100644 index 000000000..4129ce957 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 84f3d28555368a70270e9ac8390a9441df95e752 + channel: stable + +project_type: plugin diff --git a/pangea_packages/fcm_shared_isolate/CHANGELOG.md b/pangea_packages/fcm_shared_isolate/CHANGELOG.md index e53776993..b1d2b08e2 100644 --- a/pangea_packages/fcm_shared_isolate/CHANGELOG.md +++ b/pangea_packages/fcm_shared_isolate/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0 + +- Upgrade kotlin version and dependencies + ## 0.1.0 - Initial release \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/analysis_options.yaml b/pangea_packages/fcm_shared_isolate/analysis_options.yaml index 0996667b3..1d28945e8 100644 --- a/pangea_packages/fcm_shared_isolate/analysis_options.yaml +++ b/pangea_packages/fcm_shared_isolate/analysis_options.yaml @@ -1,5 +1,3 @@ -include: package:pedantic/analysis_options.yaml - linter: rules: - camel_case_types @@ -7,3 +5,11 @@ linter: - constant_identifier_names - prefer_final_locals - prefer_final_in_for_each + - prefer_relative_imports + - unawaited_futures + - require_trailing_commas + +analyzer: + errors: + todo: ignore + fixme: ignore diff --git a/pangea_packages/fcm_shared_isolate/android/.gitignore b/pangea_packages/fcm_shared_isolate/android/.gitignore new file mode 100644 index 000000000..c6cbe562a --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock deleted file mode 100644 index ec3fe34fd..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin deleted file mode 100644 index f76dd238a..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin deleted file mode 100644 index 5dfd940b6..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin deleted file mode 100644 index f76dd238a..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock deleted file mode 100644 index 6eb41fd25..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock deleted file mode 100644 index 9b9a81fae..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock deleted file mode 100644 index 166e91e36..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin deleted file mode 100644 index f76dd238a..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock deleted file mode 100644 index d6084472c..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 889a37ac8..000000000 --- a/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Tue Jan 17 18:47:16 PKT 2023 -gradle.version=6.7.1 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin deleted file mode 100644 index 6f9cbd72b..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin deleted file mode 100644 index 9391a9b33..000000000 Binary files a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/configuration-cache/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/configuration-cache/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/vcs-1/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/vcs-1/gc.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/pangea_packages/fcm_shared_isolate/android/build.gradle b/pangea_packages/fcm_shared_isolate/android/build.gradle index 443be8168..bba032196 100644 --- a/pangea_packages/fcm_shared_isolate/android/build.gradle +++ b/pangea_packages/fcm_shared_isolate/android/build.gradle @@ -2,14 +2,14 @@ group 'com.famedly.fcm_shared_isolate' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.4.32' + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' + classpath 'com.android.tools.build:gradle:8.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -26,10 +26,9 @@ apply plugin: 'kotlin-android' def firebaseCoreProject = findProject(':firebase_core') if (firebaseCoreProject == null) { - - throw GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') + throw new GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') } else if (!firebaseCoreProject.properties['FirebaseSDKVersion']) { - throw GradleException('A newer version of the firebase_core FlutterFire plugin is required, please update your firebase_core pubspec dependency.') + throw new GradleException('A newer version of the firebase_core FlutterFire plugin is required, please update your firebase_core pubspec dependency.') } def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { @@ -39,13 +38,14 @@ def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { } android { - compileSdkVersion 34 + compileSdk 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { - minSdkVersion 21 + minSdkVersion 19 + namespace "com.famedly.fcm_shared_isolate" } lintOptions { disable 'InvalidPackage' @@ -53,10 +53,14 @@ android { dependencies { api firebaseCoreProject implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}") + api 'com.google.firebase:firebase-messaging' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.google.firebase:firebase-messaging-ktx:23.0.2' } diff --git a/pangea_packages/fcm_shared_isolate/android/local.properties b/pangea_packages/fcm_shared_isolate/android/local.properties deleted file mode 100644 index 5ca26ae66..000000000 --- a/pangea_packages/fcm_shared_isolate/android/local.properties +++ /dev/null @@ -1,8 +0,0 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Tue Jan 17 02:51:21 PKT 2023 -sdk.dir=/Users/lalaiqbalkhokhar/Library/Android/sdk diff --git a/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt index fe0f85af3..54cdc9f00 100644 --- a/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt +++ b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt @@ -1,4 +1,3 @@ - package com.famedly.fcm_shared_isolate import androidx.annotation.NonNull @@ -12,7 +11,7 @@ import io.flutter.plugin.common.MethodChannel.Result class FcmSharedIsolatePlugin : FlutterPlugin, MethodCallHandler { private lateinit var channel: MethodChannel - private val fcm = FirebaseMessaging.getInstance() + private val fcm = try { FirebaseMessaging.getInstance() } catch (e: Exception) { null } override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "fcm_shared_isolate") @@ -26,7 +25,7 @@ class FcmSharedIsolatePlugin : FlutterPlugin, MethodCallHandler { } if (call.method == "getToken") { - val getToken = FirebaseMessaging.getInstance().getToken() + val getToken = fcm.getToken() getToken.addOnSuccessListener { result.success(it) } getToken.addOnFailureListener { result.error("unknown", null, null) } } else { diff --git a/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill b/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill deleted file mode 100644 index 4c868dc8b..000000000 Binary files a/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json deleted file mode 100644 index 9e26dfeeb..000000000 --- a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json deleted file mode 100644 index 0637a088a..000000000 --- a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z deleted file mode 100644 index 2b6801c84..000000000 Binary files a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag deleted file mode 100644 index ead18b083..000000000 Binary files a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag and /dev/null differ diff --git a/pangea_packages/fcm_shared_isolate/example/.gitignore b/pangea_packages/fcm_shared_isolate/example/.gitignore new file mode 100644 index 000000000..0fa6b675c --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/pangea_packages/fcm_shared_isolate/example/.metadata b/pangea_packages/fcm_shared_isolate/example/.metadata new file mode 100644 index 000000000..92f6487f6 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: b1395592de68cc8ac4522094ae59956dd21a91db + channel: stable + +project_type: app diff --git a/pangea_packages/fcm_shared_isolate/example/README.md b/pangea_packages/fcm_shared_isolate/example/README.md new file mode 100644 index 000000000..75d7f21da --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/README.md @@ -0,0 +1,16 @@ +# fcm_shared_isolate_example + +Demonstrates how to use the fcm_shared_isolate plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/pangea_packages/fcm_shared_isolate/example/android/.gitignore b/pangea_packages/fcm_shared_isolate/example/android/.gitignore new file mode 100644 index 000000000..0a741cb43 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/build.gradle b/pangea_packages/fcm_shared_isolate/example/android/app/build.gradle new file mode 100644 index 000000000..21145f1e3 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/build.gradle @@ -0,0 +1,64 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdk 33 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.famedly.fcm_shared_isolate_example" + minSdkVersion 26 + targetSdkVersion 33 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } + namespace 'com.famedly.fcm_shared_isolate_example' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +} diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/debug/AndroidManifest.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..f880684a6 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/AndroidManifest.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..d129cbffd --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/kotlin/com/famedly/fcm_shared_isolate_example/MainActivity.kt b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/kotlin/com/famedly/fcm_shared_isolate_example/MainActivity.kt new file mode 100644 index 000000000..c8252a5ae --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/kotlin/com/famedly/fcm_shared_isolate_example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.famedly.fcm_shared_isolate_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable-v21/launch_background.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000..f74085f3f --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable/launch_background.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000..304732f88 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..db77bb4b7 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..17987b79b Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..09d439148 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..d5f1c8d34 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..4d6372eeb Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values-night/styles.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..449a9f930 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values/styles.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..d74aa35c2 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/app/src/profile/AndroidManifest.xml b/pangea_packages/fcm_shared_isolate/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 000000000..f880684a6 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/android/build.gradle b/pangea_packages/fcm_shared_isolate/example/android/build.gradle new file mode 100644 index 000000000..d86cd81a7 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.7.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:8.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/pangea_packages/fcm_shared_isolate/example/android/gradle.properties b/pangea_packages/fcm_shared_isolate/example/android/gradle.properties new file mode 100644 index 000000000..b9a9a2464 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/gradle.properties @@ -0,0 +1,6 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/pangea_packages/fcm_shared_isolate/example/android/gradle/wrapper/gradle-wrapper.properties b/pangea_packages/fcm_shared_isolate/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..da1db5f04 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/pangea_packages/fcm_shared_isolate/example/android/settings.gradle b/pangea_packages/fcm_shared_isolate/example/android/settings.gradle new file mode 100644 index 000000000..44e62bcf0 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/pangea_packages/fcm_shared_isolate/example/ios/.gitignore b/pangea_packages/fcm_shared_isolate/example/ios/.gitignore new file mode 100644 index 000000000..e96ef602b --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Flutter/AppFrameworkInfo.plist b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..9367d483e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Debug.xcconfig b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..ec97fc6f3 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Release.xcconfig b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..c4855bfe2 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Podfile b/pangea_packages/fcm_shared_isolate/example/ios/Podfile new file mode 100644 index 000000000..fdcc671eb --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.pbxproj b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..72c3dd0cf --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,471 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.famedly.fcmSharedIsolateExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.famedly.fcmSharedIsolateExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.famedly.fcmSharedIsolateExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..a28140cfd --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..1d526a16e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/AppDelegate.swift b/pangea_packages/fcm_shared_isolate/example/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000..70693e4a8 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d36b1fab2 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000..dc9ada472 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..28c6bf030 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..f091b6b0b Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..4cde12118 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..d0ef06e7e Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..dcdc2306c Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..c8f9ed8f5 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..75b2d164a Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..c4df70d39 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..6a84f41e1 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..d0e1f5853 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000..0bedcf2fd --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/Main.storyboard b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Info.plist b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Info.plist new file mode 100644 index 000000000..c4dedcf7d --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + fcm_shared_isolate_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/pangea_packages/fcm_shared_isolate/example/ios/Runner/Runner-Bridging-Header.h b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000..308a2a560 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/pangea_packages/fcm_shared_isolate/example/lib/main.dart b/pangea_packages/fcm_shared_isolate/example/lib/main.dart new file mode 100644 index 000000000..95b3d1094 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/lib/main.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import 'package:fcm_shared_isolate/fcm_shared_isolate.dart'; + +void main() { + FcmSharedIsolate(); + runApp(MyApp()); +} + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Text('Hello World\n'), + ), + ), + ); + } +} diff --git a/pangea_packages/fcm_shared_isolate/example/pubspec.yaml b/pangea_packages/fcm_shared_isolate/example/pubspec.yaml new file mode 100644 index 000000000..d37e1d0b8 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/pubspec.yaml @@ -0,0 +1,71 @@ +name: fcm_shared_isolate_example +description: Demonstrates how to use the fcm_shared_isolate plugin. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: "none" # Remove this line if you wish to publish to pub.dev + +environment: + sdk: ">=2.12.0 <4.0.0" + +dependencies: + flutter: + sdk: flutter + + fcm_shared_isolate: + # When depending on this package from a real application you should use: + # fcm_shared_isolate: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + +dev_dependencies: + lints: ">=2.0.0 <4.0.0" + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/pangea_packages/fcm_shared_isolate/example/test/widget_test.dart b/pangea_packages/fcm_shared_isolate/example/test/widget_test.dart new file mode 100644 index 000000000..3e83d9d80 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:fcm_shared_isolate_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => + widget is Text && widget.data?.startsWith('Running on:') == false, + ), + findsOneWidget, + ); + }); +} diff --git a/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift b/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift index 50a89f127..84f4a31de 100644 --- a/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift +++ b/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift @@ -6,7 +6,7 @@ import FirebaseMessaging internal init(channel: FlutterMethodChannel) { self.channel = channel } - + public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "fcm_shared_isolate", binaryMessenger: registrar.messenger()) let instance = FcmSharedIsolatePlugin(channel: channel) @@ -86,7 +86,6 @@ import FirebaseMessaging } public func messaging(_ messaging: Messaging, didReceiveRegistrationToken token: String?) { - channel.invokeMethod("token", arguments: [token]) } } diff --git a/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec b/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec index 9e2fb06ed..e54f2b538 100644 --- a/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec +++ b/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec @@ -9,10 +9,8 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'FirebaseCore' - s.dependency 'FirebaseMessaging' + s.dependency 'Firebase/Messaging' s.swift_version = '5.2' - s.ios.deployment_target = '11.0' + s.ios.deployment_target = '10.0' s.static_framework = true - end diff --git a/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart b/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart index 843716626..de6ab2d82 100644 --- a/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart +++ b/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart @@ -31,10 +31,6 @@ class FcmSharedIsolate { } Future getToken() async { - // if (Platform.isAndroid) { - // await Firebase.initializeApp(); - // return (await FirebaseMessaging.instance.getToken())!; - // } return await _channel.invokeMethod('getToken'); } @@ -54,7 +50,7 @@ class FcmSharedIsolate { {bool sound = true, bool alert = true, bool badge = true, - bool provisional = false}) async { + bool provisional = false,}) async { if (kIsWeb || !Platform.isIOS) { return true; } diff --git a/pangea_packages/fcm_shared_isolate/pubspec.lock b/pangea_packages/fcm_shared_isolate/pubspec.lock deleted file mode 100644 index 7f3457dbe..000000000 --- a/pangea_packages/fcm_shared_isolate/pubspec.lock +++ /dev/null @@ -1,286 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - sha256: "0816f12bbbd9e21f72ea8592b11bce4a628d4e5cb7a81ff9f1eee4f3dc23206e" - url: "https://pub.dev" - source: hosted - version: "1.3.37" - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: fae4ab4317c2a7afb13d44ef1e3f9f28a630e10016bc5cfe761e8e6a0ed7816a - url: "https://pub.dev" - source: hosted - version: "3.1.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - sha256: "1003a5a03a61fc9a22ef49f37cbcb9e46c86313a7b2e7029b9390cf8c6fc32cb" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "6643fe3dbd021e6ccfb751f7882b39df355708afbdeb4130fc50f9305a9d1a3d" - url: "https://pub.dev" - source: hosted - version: "2.17.2" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - sha256: "2d0ea2234ce46030eda2e6922611115ce603adc614ebd8c00e7db06a8929efbb" - url: "https://pub.dev" - source: hosted - version: "15.0.1" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - sha256: c38c27f58cb6a88b8c145018d0567802376549c32a60098a13f3bdf3ddea326f - url: "https://pub.dev" - source: hosted - version: "4.5.39" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - sha256: "8502849c2f232f7db338c052e045442207a0db82bd03ff14be3c80897dd8c26c" - url: "https://pub.dev" - source: hosted - version: "3.8.9" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" - url: "https://pub.dev" - source: hosted - version: "10.0.4" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" - url: "https://pub.dev" - source: hosted - version: "3.0.3" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" - version: "0.12.16+1" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" - url: "https://pub.dev" - source: hosted - version: "0.8.0" - version: "0.8.0" - meta: - dependency: transitive - description: - name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" - url: "https://pub.dev" - source: hosted - version: "1.12.0" - version: "1.12.0" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - version: "1.9.0" - pedantic: - dependency: "direct dev" - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a - url: "https://pub.dev" - source: hosted - version: "2.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - version: "0.7.0" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" - url: "https://pub.dev" - source: hosted - version: "14.2.1" - web: - dependency: transitive - description: - name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" - url: "https://pub.dev" - source: hosted - version: "0.5.1" -sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" diff --git a/pangea_packages/fcm_shared_isolate/pubspec.yaml b/pangea_packages/fcm_shared_isolate/pubspec.yaml index eda937d30..ba513c274 100644 --- a/pangea_packages/fcm_shared_isolate/pubspec.yaml +++ b/pangea_packages/fcm_shared_isolate/pubspec.yaml @@ -1,22 +1,21 @@ name: fcm_shared_isolate description: Firebase Messaging Plugin for Flutter supporting shared isolate homepage: https://famedly.com -version: 0.1.0 -repository: https://gitlab.com/famedly/libraries/fcm_shared_isolate -issue_tracker: https://gitlab.com/famedly/libraries/fcm_shared_isolate/issues +version: 0.2.0 +repository: https://github.com/famedly/fcm_shared_isolate +issue_tracker: https://github.com/famedly/fcm_shared_isolate/issues environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.12.0 <4.0.0" flutter: ">=1.20.0" dependencies: firebase_core: ^3.1.0 - firebase_messaging: ^15.0.1 flutter: sdk: flutter dev_dependencies: - pedantic: ^1.11.0 + lints: ">=2.0.0 <4.0.0" flutter_test: sdk: flutter diff --git a/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart b/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart index 322ec0bd4..a69cf9ac2 100644 --- a/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart +++ b/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart @@ -1,21 +1,25 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:fcm_shared_isolate/fcm_shared_isolate.dart'; void main() { const channel = MethodChannel('fcm_shared_isolate'); + TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { - // ignore: deprecated_member_use - channel.setMockMethodCallHandler((MethodCall methodCall) async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { return '42'; }); }); tearDown(() { - // ignore: deprecated_member_use - channel.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, null); }); - test('create', () async {}); + test('create', () { + FcmSharedIsolate(); + }); } diff --git a/pubspec.lock b/pubspec.lock index 8ef3fdbfb..fb1e21214 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -393,14 +393,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" - dart_levenshtein: - dependency: "direct main" - description: - name: dart_levenshtein - sha256: f38182278b774cbb0d5993de50848e65da5a9f722b7f07787f0c26de009e0322 - url: "https://pub.dev" - source: hosted - version: "1.0.1" dart_webrtc: dependency: transitive description: @@ -433,14 +425,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.3" - desktop_webview_window: - dependency: transitive - description: - name: desktop_webview_window - sha256: "57cf20d81689d5cbb1adfd0017e96b669398a669d927906073b0e42fc64111c0" - url: "https://pub.dev" - source: hosted - version: "0.2.3" device_info_plus: dependency: "direct main" description: @@ -535,7 +519,7 @@ packages: path: "pangea_packages/fcm_shared_isolate" relative: true source: path - version: "0.1.0" + version: "0.2.0" ffi: dependency: transitive description: @@ -704,14 +688,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - fl_chart: - dependency: "direct main" - description: - name: fl_chart - sha256: "2b7c1f5d867da9a054661641c8f499c55c47c39acccb97b3bc673f5fa9a39e74" - url: "https://pub.dev" - source: hosted - version: "0.67.0" flutter: dependency: "direct main" description: flutter @@ -983,19 +959,20 @@ packages: flutter_web_auth_2: dependency: "direct main" description: - name: flutter_web_auth_2 - sha256: "3c14babeaa066c371f3a743f204dd0d348b7d42ffa6fae7a9847a521aff33696" - url: "https://pub.dev" - source: hosted - version: "4.1.0" + path: flutter_web_auth_2 + ref: "3.x-without-v1" + resolved-ref: "48682f19576001e50104a602d891343850adb67f" + url: "https://github.com/ThexXTURBOXx/flutter_web_auth_2.git" + source: git + version: "3.1.2-without-v1" flutter_web_auth_2_platform_interface: dependency: transitive description: name: flutter_web_auth_2_platform_interface - sha256: c63a472c8070998e4e422f6b34a17070e60782ac442107c70000dd1bed645f4d + sha256: e8669e262005a8354389ba2971f0fc1c36188481234ff50d013aaf993f30f739 url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "3.1.0" flutter_web_plugins: dependency: transitive description: flutter @@ -1403,14 +1380,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" - language_tool: - dependency: "direct main" - description: - name: language_tool - sha256: a27c4ccff2b90647c5fa0f702d7c0c172c3d11d1a7b6c4ffc3c51ba8e7fc5a84 - url: "https://pub.dev" - source: hosted - version: "2.2.0" latlong2: dependency: "direct main" description: @@ -1528,10 +1497,10 @@ packages: description: path: "." ref: main - resolved-ref: e77d79ff2a9b91d5cd950a0742be2f74781cb19f + resolved-ref: d79d1b9eba991a76592a8e6673e582b2d1a2af49 url: "https://github.com/pangeachat/matrix-dart-sdk.git" source: git - version: "0.37.0" + version: "0.38.0" meta: dependency: transitive description: @@ -2088,10 +2057,10 @@ packages: dependency: transitive description: name: sentry - sha256: "1af8308298977259430d118ab25be8e1dda626cdefa1e6ce869073d530d39271" + sha256: "90c2f956c146bcc9c4843406dd4a65d08b25575828dc2ad51de0ca5cd713209f" url: "https://pub.dev" source: hosted - version: "8.8.0" + version: "8.13.2" sentry_dart_plugin: dependency: "direct dev" description: @@ -2104,10 +2073,10 @@ packages: dependency: "direct main" description: name: sentry_flutter - sha256: "18fe4d125c2d529bd6127200f0d2895768266a8c60b4fb50b2086fd97e1a4ab2" + sha256: ee6b41956ad570706bf5c2489915d71d75522d154200c0df24be2c4e5654ca21 url: "https://pub.dev" source: hosted - version: "8.8.0" + version: "8.13.2" share_plus: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 0235b30df..73c468714 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,7 +33,7 @@ dependencies: dynamic_color: ^1.7.0 emoji_picker_flutter: ^3.1.0 emojis: ^0.9.9 - #fcm_shared_isolate: ^0.1.0 + #fcm_shared_isolate: ^0.2.0 file_picker: ^8.1.2 file_selector: ^1.0.3 flutter: @@ -53,7 +53,7 @@ dependencies: flutter_secure_storage: ^9.2.3 flutter_shortcuts_new: ^2.0.0 flutter_typeahead: ^5.2.0 - flutter_web_auth_2: ^4.1.0 + flutter_web_auth_2: ^3.1.1 # Version 4 blocked by https://github.com/MixinNetwork/flutter-plugins/issues/379 flutter_webrtc: ^0.12.9 geolocator: ^13.0.1 go_router: ^14.3.0 @@ -73,7 +73,7 @@ dependencies: git: url: https://github.com/pangeachat/matrix-dart-sdk.git # repo ref: main # branch - # matrix: ^0.37.0 + # matrix: ^0.38.0 # Pangea# mime: ^1.0.6 native_imaging: ^0.2.0 @@ -113,7 +113,6 @@ dependencies: csv: ^6.0.0 dropdown_button2: ^2.3.9 excel: ^4.0.6 - fl_chart: ^0.67.0 firebase_analytics: ^11.0.1 firebase_core: ^3.1.0 firebase_messaging: ^15.1.5 @@ -124,16 +123,14 @@ dependencies: get_storage: ^2.1.1 in_app_purchase: ^3.2.1 jwt_decode: ^0.3.1 - language_tool: ^2.2.0 material_symbols_icons: ^4.2741.0 open_file: ^3.3.2 purchases_flutter: ^8.5.1 - sentry_flutter: ^8.2.0 + sentry_flutter: ^8.13.2 shimmer: ^3.0.0 rive: 0.11.11 text_to_speech: ^0.2.3 flutter_tts: ^4.2.0 - dart_levenshtein: ^1.0.1 # Pangea# dev_dependencies: @@ -176,6 +173,8 @@ flutter: - family: Ubuntu fonts: - asset: fonts/Ubuntu/Ubuntu-Regular.ttf + - asset: fonts/Ubuntu/Ubuntu-Medium.ttf + weight: 500 - asset: fonts/Ubuntu/Ubuntu-Bold.ttf weight: 600 - asset: fonts/Ubuntu/Ubuntu-Italic.ttf @@ -216,4 +215,10 @@ msix_config: install_certificate: false dependency_overrides: - win32: 5.5.3 \ No newline at end of file + # https://github.com/ThexXTURBOXx/flutter_web_auth_2/issues/155 + flutter_web_auth_2: + git: + url: https://github.com/ThexXTURBOXx/flutter_web_auth_2.git + ref: 3.x-without-v1 + path: flutter_web_auth_2 + win32: 5.5.3 diff --git a/scripts/enable-android-google-services.patch b/scripts/enable-android-google-services.patch index def051189..c56444146 100644 --- a/scripts/enable-android-google-services.patch +++ b/scripts/enable-android-google-services.patch @@ -97,8 +97,8 @@ index b2fd960a..fdb01a4d 100644 +++ b/android/settings.gradle @@ -20,7 +20,7 @@ plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.1.2" apply false - id "org.jetbrains.kotlin.android" version "1.8.0" apply false + id "com.android.application" version "7.3.1" apply false + id "org.jetbrains.kotlin.android" version "2.1.10" apply false - // id "com.google.gms.google-services" version "4.3.8" apply false + id "com.google.gms.google-services" version "4.3.8" apply false } @@ -135,8 +135,8 @@ index fb3e3ca4..039b2ccc 100644 dynamic_color: ^1.7.0 emoji_picker_flutter: ^3.1.0 emojis: ^0.9.9 -- #fcm_shared_isolate: ^0.1.0 -+ fcm_shared_isolate: ^0.1.0 +- #fcm_shared_isolate: ^0.2.0 ++ fcm_shared_isolate: ^0.2.0 file_picker: ^8.1.2 file_selector: ^1.0.3 flutter: diff --git a/scripts/generate-locale-config.sh b/scripts/generate-locale-config.sh new file mode 100755 index 000000000..5f1b4871d --- /dev/null +++ b/scripts/generate-locale-config.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Directory containing the ARB files +l10n_dir="./assets/l10n" +# Target directory for the locale_config.xml file +xml_dir="./android/app/src/main/res/xml" + +# Create the target directory if it does not exist +mkdir -p "$xml_dir" + +# Output file name +xml_file="$xml_dir/locale_config.xml" + +rm -rf "$xml_file" + +# XML Header +echo '' > "$xml_file" +echo '' >> "$xml_file" + +# Search for ARB files and extract language codes +for file in "$l10n_dir"/intl_*.arb; do + # Extract language code + language_code=$(basename "$file" | cut -d'_' -f2 | cut -d'.' -f1) + # Write language code to the XML file + echo " " >> "$xml_file" +done + +# XML Footer +echo '' >> "$xml_file" + +echo "locale_config.xml file has been successfully created in the $xml_dir directory." diff --git a/scripts/prepare-web.sh b/scripts/prepare-web.sh index 798bbe37f..82d4af3d0 100755 --- a/scripts/prepare-web.sh +++ b/scripts/prepare-web.sh @@ -1,5 +1,5 @@ #!/bin/sh -ve -rm -r assets/js/package +rm -rf assets/js/package OLM_VERSION=$(cat pubspec.yaml | yq .dependencies.flutter_olm) DOWNLOAD_PATH="https://github.com/famedly/olm/releases/download/v$OLM_VERSION/olm.zip" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 87efdcd88..baf96d923 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -61,18 +61,41 @@ parts: build-packages: - g++ + flutter-git: + source: https://github.com/flutter/flutter.git + source-tag: 3.27.4 + plugin: nil + override-build: | + set -eux + mkdir -p $CRAFT_PART_INSTALL/usr/bin + mkdir -p $CRAFT_PART_INSTALL/usr/libexec + cp -r $CRAFT_PART_SRC $CRAFT_PART_INSTALL/usr/libexec/flutter + ln -sf $CRAFT_PART_INSTALL/usr/libexec/flutter/bin/flutter $CRAFT_PART_INSTALL/usr/bin/flutter + export PATH="$CRAFT_PART_INSTALL/usr/bin:$PATH" + flutter doctor + build-packages: + - clang + - cmake + - curl + - ninja-build + - unzip + override-prime: '' + fluffychat: - plugin: flutter + after: [ flutter-git ] + plugin: nil source: . override-build: | - # Workaround for Flutter build error: - rm -rf build - craftctl default + flutter pub get || true + flutter build linux --release -v + mkdir -p $CRAFT_PART_INSTALL/bin + cp -r build/linux/*/release/bundle/* $CRAFT_PART_INSTALL/bin/ build-packages: - libsecret-1-dev - libjsoncpp-dev - libssl-dev - curl + - jq stage-packages: - libsecret-1-0 - libjsoncpp25 @@ -85,7 +108,7 @@ slots: apps: fluffychat: - command: fluffychat + command: bin/fluffychat extensions: [ gnome ] plugs: - audio-playback diff --git a/web/index.html b/web/index.html index 44446e712..1a3730e5e 100644 --- a/web/index.html +++ b/web/index.html @@ -44,10 +44,6 @@ - @@ -56,19 +52,21 @@ @@ -91,4 +89,4 @@ - \ No newline at end of file + diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 60a2f4afe..65f8c87c5 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -32,8 +31,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("AppLinksPluginCApi")); AudioplayersWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); - DesktopWebviewWindowPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin")); DynamicColorPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); EmojiPickerFlutterPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 5f639e806..78eb9922c 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,7 +5,6 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links audioplayers_windows - desktop_webview_window dynamic_color emoji_picker_flutter file_selector_windows