├── .gitignore
├── .metadata
├── CODE_OF_CONDUCT.md
├── README.md
├── SECURITY.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── io
│ │ │ │ └── flutter
│ │ │ │ └── app
│ │ │ │ └── FlutterMultiDexApplication.java
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── rightdevs
│ │ │ │ └── status_saver
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
└── RunnerTests
│ └── RunnerTests.swift
├── l10n.yaml
├── lib
├── main.dart
└── src
│ ├── common
│ ├── constants
│ │ └── directory_paths.dart
│ ├── extensions
│ │ ├── async_value.dart
│ │ └── permission_handler.dart
│ ├── helpers
│ │ ├── android_api_level_helper.dart
│ │ ├── get_video_thumbnail.dart
│ │ ├── show_toast.dart
│ │ ├── statuses_helper.dart
│ │ └── storage_helper.dart
│ └── views
│ │ ├── circular_loader.dart
│ │ └── common_error_screen.dart
│ ├── debug
│ ├── console_log.dart
│ └── red_container.dart
│ ├── home
│ ├── models
│ │ ├── android_info.dart
│ │ ├── tab_type.dart
│ │ └── whatsapp_type_enum.dart
│ ├── notifiers
│ │ └── selected_tab_index_notifier.dart
│ ├── services
│ │ ├── android_info_notifier.dart
│ │ └── whatsapp_type_notifier.dart
│ └── views
│ │ ├── home_screen.dart
│ │ └── my_drawer.dart
│ ├── localization
│ ├── enums
│ │ └── language_code.dart
│ ├── extensions
│ │ ├── on_build_context.dart
│ │ └── on_string.dart
│ ├── l10n
│ │ ├── app_af.arb
│ │ ├── app_ar.arb
│ │ ├── app_az.arb
│ │ ├── app_bn.arb
│ │ ├── app_en.arb
│ │ ├── app_es.arb
│ │ ├── app_gu.arb
│ │ ├── app_hi.arb
│ │ ├── app_ja.arb
│ │ ├── app_kn.arb
│ │ ├── app_ko.arb
│ │ ├── app_mr.arb
│ │ ├── app_pa.arb
│ │ ├── app_ta.arb
│ │ ├── app_te.arb
│ │ ├── app_ur.arb
│ │ └── l10n.dart
│ └── notifiers
│ │ └── locale_notifier.dart
│ ├── statuses
│ ├── notifiers
│ │ └── statuses_notifier.dart
│ └── views
│ │ ├── image_tile.dart
│ │ ├── image_view.dart
│ │ ├── status_actions.dart
│ │ ├── statuses_grid_widget.dart
│ │ ├── statuses_screen.dart
│ │ ├── video_tile.dart
│ │ └── video_view.dart
│ ├── storage_permission
│ ├── notifiers
│ │ └── storage_permission_notifier.dart
│ └── views
│ │ └── give_permissions_screen.dart
│ └── theme
│ ├── app_theme.dart
│ ├── colors.dart
│ └── notifiers
│ └── theme_mode_notifier.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Symbolication related
35 | app.*.symbols
36 |
37 | # Obfuscation related
38 | app.*.map.json
39 |
40 | # Android Studio will place build artifacts here
41 | /android/app/debug
42 | /android/app/profile
43 | /android/app/release
44 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "ba393198430278b6595976de84fe170f553cc728"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: ba393198430278b6595976de84fe170f553cc728
17 | base_revision: ba393198430278b6595976de84fe170f553cc728
18 | - platform: android
19 | create_revision: ba393198430278b6595976de84fe170f553cc728
20 | base_revision: ba393198430278b6595976de84fe170f553cc728
21 | - platform: ios
22 | create_revision: ba393198430278b6595976de84fe170f553cc728
23 | base_revision: ba393198430278b6595976de84fe170f553cc728
24 | - platform: linux
25 | create_revision: ba393198430278b6595976de84fe170f553cc728
26 | base_revision: ba393198430278b6595976de84fe170f553cc728
27 | - platform: macos
28 | create_revision: ba393198430278b6595976de84fe170f553cc728
29 | base_revision: ba393198430278b6595976de84fe170f553cc728
30 | - platform: web
31 | create_revision: ba393198430278b6595976de84fe170f553cc728
32 | base_revision: ba393198430278b6595976de84fe170f553cc728
33 | - platform: windows
34 | create_revision: ba393198430278b6595976de84fe170f553cc728
35 | base_revision: ba393198430278b6595976de84fe170f553cc728
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | We, as contributors and maintainers of the Status Saver project, pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
4 |
5 | ## Our Standards
6 |
7 | Examples of behavior that contributes to creating a positive environment include:
8 |
9 | - **Being respectful**: Disagreements happen all the time. You should focus on the issue, not the person.
10 | - **Being inclusive**: Everyone is welcome, regardless of their background.
11 | - **Being understanding**: Not everyone will agree with your decisions, but try to understand different perspectives.
12 | - **Being patient**: Processes may take time. Be patient and give people the time to voice their opinions.
13 |
14 | Examples of unacceptable behavior by participants include:
15 |
16 | - **The use of sexualized language or imagery**
17 | - **Personal attacks**
18 | - **Trolling or insulting/derogatory comments**
19 | - **Public or private harassment**
20 | - **Publishing others' private information, such as physical or electronic addresses, without explicit permission**
21 | - **Other unethical or unprofessional conduct**
22 |
23 | ## Responsibilities
24 |
25 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
26 |
27 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
28 |
29 | ## Scope
30 |
31 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
32 |
33 | ## Enforcement
34 |
35 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [geekforgeeks222@gmail.com](mailto:geekforgeeks222@gmail.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
36 |
37 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership.
38 |
39 | ## Attribution
40 |
41 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at [https://www.contributor-covenant.org/version/1/4](https://www.contributor-covenant.org/version/1/4/)
42 |
43 | For answers to common questions about this code of conduct, see [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq)
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WhatsApp Status Saver
2 |
3 | A WhatsApp status saver Flutter project.
4 |
5 | ## Features
6 | * View Recent statuses from WhatsApp & WhatsApp Business.
7 | * Share statuses without saving.
8 | * Save statuses to Gallary
9 | * Material3 UI
10 |
11 | ## Contributing
12 |
13 | Contributions are welcome!
14 |
15 | Here is a curated list of how you can help:
16 |
17 | - Report bugs and scenarios that are difficult to implement
18 | - Fix typos/grammar mistakes
19 | - Implement new features by making a pull-request
20 |
21 | If you find this project useful, please consider giving it a ⭐. Your support is much appreciated!
22 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Security Issue
4 |
5 | If you discover a security issue in Status Saver, please report it by sending an email to [geekforgeeks222@gmail.com](mailto:geekforgeeks222@gmail.com). We will promptly address the issue and keep you informed of our progress.
6 |
7 | Please do not disclose security-related issues publicly until we have had a chance to address them.
8 |
9 | ## Supported Versions
10 |
11 | These versions of Status Saver are currently being supported with security updates:
12 |
13 | - Version 1.0.0 and above
14 |
15 | ## Vulnerability Disclosure Policy
16 |
17 | We encourage responsible disclosure of security vulnerabilities. If you have discovered a vulnerability, we kindly request that you:
18 |
19 | - Email your findings to [geekforgeeks222@gmail.com](mailto:geekforgeeks222@example.com)
20 | - Do not publicize the issue until we have addressed it
21 | - Provide sufficient information to help us understand and reproduce the problem
22 |
23 | ## Guidelines for Reporting a Security Issue
24 |
25 | When reporting a security issue, please provide the following details:
26 |
27 | - Your name and affiliation (if applicable)
28 | - A description of the security issue
29 | - Steps to reproduce the issue
30 | - Any proof-of-concept or exploit code (if possible)
31 | - Your contact information, so we can reach out for further discussion
32 |
33 | ## Security Response Process
34 |
35 | Once we receive your report, we will acknowledge the receipt of the report and begin investigating the issue. We will keep you updated on our progress and let you know when the issue has been resolved.
36 |
37 | ## Responsible Disclosure
38 |
39 | We ask that you do not attempt to compromise the security of our services or systems. Please act in good faith towards our users' privacy and data during your research.
40 |
41 | Thank you for helping to improve the security of Status Saver!
42 |
43 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at https://dart.dev/lints.
17 | #
18 | # Instead of disabling a lint rule for the entire project in the
19 | # section below, it can also be suppressed for a single line of code
20 | # or a specific dart file by using the `// ignore: name_of_lint` and
21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
22 | # producing the lint.
23 | rules:
24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
26 |
27 | # Additional information about this file can be found at
28 | # https://dart.dev/guides/language/analysis-options
29 |
30 | analyzer:
31 | plugins:
32 | - custom_lint
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace "com.rightdevs.status_saver"
27 | compileSdk flutter.compileSdkVersion
28 | ndkVersion flutter.ndkVersion
29 |
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 |
35 | kotlinOptions {
36 | jvmTarget = '1.8'
37 | }
38 |
39 | sourceSets {
40 | main.java.srcDirs += 'src/main/kotlin'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.rightdevs.status_saver"
46 | // You can update the following values to match your application needs.
47 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
48 | minSdkVersion flutter.minSdkVersion
49 | targetSdkVersion flutter.targetSdkVersion
50 | versionCode flutterVersionCode.toInteger()
51 | versionName flutterVersionName
52 | }
53 |
54 | buildTypes {
55 | release {
56 | // TODO: Add your own signing config for the release build.
57 | // Signing with the debug keys for now, so `flutter run --release` works.
58 | signingConfig signingConfigs.debug
59 | }
60 | }
61 | }
62 |
63 | flutter {
64 | source '../..'
65 | }
66 |
67 | dependencies {
68 | implementation 'com.android.support:multidex:1.0.3'
69 | implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
70 | }
71 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
20 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java:
--------------------------------------------------------------------------------
1 | // Generated file.
2 | //
3 | // If you wish to remove Flutter's multidex support, delete this entire file.
4 | //
5 | // Modifications to this file should be done in a copy under a different name
6 | // as this file may be regenerated.
7 |
8 | package io.flutter.app;
9 |
10 | import android.app.Application;
11 | import android.content.Context;
12 | import androidx.annotation.CallSuper;
13 | import androidx.multidex.MultiDex;
14 |
15 | /**
16 | * Extension of {@link android.app.Application}, adding multidex support.
17 | */
18 | public class FlutterMultiDexApplication extends Application {
19 | @Override
20 | @CallSuper
21 | protected void attachBaseContext(Context base) {
22 | super.attachBaseContext(base);
23 | MultiDex.install(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/rightdevs/status_saver/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.rightdevs.status_saver
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity()
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = '../build'
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(':app')
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }
9 | settings.ext.flutterSdkPath = flutterSdkPath()
10 |
11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 | }
19 |
20 | plugins {
21 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
22 | id "com.android.application" version "7.3.0" apply false
23 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false
24 | }
25 |
26 | include ":app"
27 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 12.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '12.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | target 'RunnerTests' do
36 | inherit! :search_paths
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | flutter_additional_ios_build_settings(target)
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 97C146E61CF9000F007C117D /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = 97C146ED1CF9000F007C117D;
25 | remoteInfo = Runner;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXCopyFilesBuildPhase section */
30 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
31 | isa = PBXCopyFilesBuildPhase;
32 | buildActionMask = 2147483647;
33 | dstPath = "";
34 | dstSubfolderSpec = 10;
35 | files = (
36 | );
37 | name = "Embed Frameworks";
38 | runOnlyForDeploymentPostprocessing = 0;
39 | };
40 | /* End PBXCopyFilesBuildPhase section */
41 |
42 | /* Begin PBXFileReference section */
43 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
44 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
45 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
46 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
47 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
48 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
49 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
50 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 331C8082294A63A400263BE5 /* RunnerTests */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 331C807B294A618700263BE5 /* RunnerTests.swift */,
75 | );
76 | path = RunnerTests;
77 | sourceTree = "";
78 | };
79 | 9740EEB11CF90186004384FC /* Flutter */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
83 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
84 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
85 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
86 | );
87 | name = Flutter;
88 | sourceTree = "";
89 | };
90 | 97C146E51CF9000F007C117D = {
91 | isa = PBXGroup;
92 | children = (
93 | 9740EEB11CF90186004384FC /* Flutter */,
94 | 97C146F01CF9000F007C117D /* Runner */,
95 | 97C146EF1CF9000F007C117D /* Products */,
96 | 331C8082294A63A400263BE5 /* RunnerTests */,
97 | );
98 | sourceTree = "";
99 | };
100 | 97C146EF1CF9000F007C117D /* Products */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 97C146EE1CF9000F007C117D /* Runner.app */,
104 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
105 | );
106 | name = Products;
107 | sourceTree = "";
108 | };
109 | 97C146F01CF9000F007C117D /* Runner */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
113 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
114 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
115 | 97C147021CF9000F007C117D /* Info.plist */,
116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
118 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
119 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
120 | );
121 | path = Runner;
122 | sourceTree = "";
123 | };
124 | /* End PBXGroup section */
125 |
126 | /* Begin PBXNativeTarget section */
127 | 331C8080294A63A400263BE5 /* RunnerTests */ = {
128 | isa = PBXNativeTarget;
129 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
130 | buildPhases = (
131 | 331C807D294A63A400263BE5 /* Sources */,
132 | 331C807F294A63A400263BE5 /* Resources */,
133 | );
134 | buildRules = (
135 | );
136 | dependencies = (
137 | 331C8086294A63A400263BE5 /* PBXTargetDependency */,
138 | );
139 | name = RunnerTests;
140 | productName = RunnerTests;
141 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
142 | productType = "com.apple.product-type.bundle.unit-test";
143 | };
144 | 97C146ED1CF9000F007C117D /* Runner */ = {
145 | isa = PBXNativeTarget;
146 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
147 | buildPhases = (
148 | 9740EEB61CF901F6004384FC /* Run Script */,
149 | 97C146EA1CF9000F007C117D /* Sources */,
150 | 97C146EB1CF9000F007C117D /* Frameworks */,
151 | 97C146EC1CF9000F007C117D /* Resources */,
152 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
153 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
154 | );
155 | buildRules = (
156 | );
157 | dependencies = (
158 | );
159 | name = Runner;
160 | productName = Runner;
161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
162 | productType = "com.apple.product-type.application";
163 | };
164 | /* End PBXNativeTarget section */
165 |
166 | /* Begin PBXProject section */
167 | 97C146E61CF9000F007C117D /* Project object */ = {
168 | isa = PBXProject;
169 | attributes = {
170 | BuildIndependentTargetsInParallel = YES;
171 | LastUpgradeCheck = 1510;
172 | ORGANIZATIONNAME = "";
173 | TargetAttributes = {
174 | 331C8080294A63A400263BE5 = {
175 | CreatedOnToolsVersion = 14.0;
176 | TestTargetID = 97C146ED1CF9000F007C117D;
177 | };
178 | 97C146ED1CF9000F007C117D = {
179 | CreatedOnToolsVersion = 7.3.1;
180 | LastSwiftMigration = 1100;
181 | };
182 | };
183 | };
184 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
185 | compatibilityVersion = "Xcode 9.3";
186 | developmentRegion = en;
187 | hasScannedForEncodings = 0;
188 | knownRegions = (
189 | en,
190 | Base,
191 | );
192 | mainGroup = 97C146E51CF9000F007C117D;
193 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
194 | projectDirPath = "";
195 | projectRoot = "";
196 | targets = (
197 | 97C146ED1CF9000F007C117D /* Runner */,
198 | 331C8080294A63A400263BE5 /* RunnerTests */,
199 | );
200 | };
201 | /* End PBXProject section */
202 |
203 | /* Begin PBXResourcesBuildPhase section */
204 | 331C807F294A63A400263BE5 /* Resources */ = {
205 | isa = PBXResourcesBuildPhase;
206 | buildActionMask = 2147483647;
207 | files = (
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | 97C146EC1CF9000F007C117D /* Resources */ = {
212 | isa = PBXResourcesBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
216 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
219 | );
220 | runOnlyForDeploymentPostprocessing = 0;
221 | };
222 | /* End PBXResourcesBuildPhase section */
223 |
224 | /* Begin PBXShellScriptBuildPhase section */
225 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
226 | isa = PBXShellScriptBuildPhase;
227 | alwaysOutOfDate = 1;
228 | buildActionMask = 2147483647;
229 | files = (
230 | );
231 | inputPaths = (
232 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
233 | );
234 | name = "Thin Binary";
235 | outputPaths = (
236 | );
237 | runOnlyForDeploymentPostprocessing = 0;
238 | shellPath = /bin/sh;
239 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
240 | };
241 | 9740EEB61CF901F6004384FC /* Run Script */ = {
242 | isa = PBXShellScriptBuildPhase;
243 | alwaysOutOfDate = 1;
244 | buildActionMask = 2147483647;
245 | files = (
246 | );
247 | inputPaths = (
248 | );
249 | name = "Run Script";
250 | outputPaths = (
251 | );
252 | runOnlyForDeploymentPostprocessing = 0;
253 | shellPath = /bin/sh;
254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
255 | };
256 | /* End PBXShellScriptBuildPhase section */
257 |
258 | /* Begin PBXSourcesBuildPhase section */
259 | 331C807D294A63A400263BE5 /* Sources */ = {
260 | isa = PBXSourcesBuildPhase;
261 | buildActionMask = 2147483647;
262 | files = (
263 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
264 | );
265 | runOnlyForDeploymentPostprocessing = 0;
266 | };
267 | 97C146EA1CF9000F007C117D /* Sources */ = {
268 | isa = PBXSourcesBuildPhase;
269 | buildActionMask = 2147483647;
270 | files = (
271 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
272 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
273 | );
274 | runOnlyForDeploymentPostprocessing = 0;
275 | };
276 | /* End PBXSourcesBuildPhase section */
277 |
278 | /* Begin PBXTargetDependency section */
279 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
280 | isa = PBXTargetDependency;
281 | target = 97C146ED1CF9000F007C117D /* Runner */;
282 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
283 | };
284 | /* End PBXTargetDependency section */
285 |
286 | /* Begin PBXVariantGroup section */
287 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
288 | isa = PBXVariantGroup;
289 | children = (
290 | 97C146FB1CF9000F007C117D /* Base */,
291 | );
292 | name = Main.storyboard;
293 | sourceTree = "";
294 | };
295 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
296 | isa = PBXVariantGroup;
297 | children = (
298 | 97C147001CF9000F007C117D /* Base */,
299 | );
300 | name = LaunchScreen.storyboard;
301 | sourceTree = "";
302 | };
303 | /* End PBXVariantGroup section */
304 |
305 | /* Begin XCBuildConfiguration section */
306 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
307 | isa = XCBuildConfiguration;
308 | buildSettings = {
309 | ALWAYS_SEARCH_USER_PATHS = NO;
310 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
311 | CLANG_ANALYZER_NONNULL = YES;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
317 | CLANG_WARN_BOOL_CONVERSION = YES;
318 | CLANG_WARN_COMMA = YES;
319 | CLANG_WARN_CONSTANT_CONVERSION = YES;
320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
322 | CLANG_WARN_EMPTY_BODY = YES;
323 | CLANG_WARN_ENUM_CONVERSION = YES;
324 | CLANG_WARN_INFINITE_RECURSION = YES;
325 | CLANG_WARN_INT_CONVERSION = YES;
326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
331 | CLANG_WARN_STRICT_PROTOTYPES = YES;
332 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
333 | CLANG_WARN_UNREACHABLE_CODE = YES;
334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
336 | COPY_PHASE_STRIP = NO;
337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
338 | ENABLE_NS_ASSERTIONS = NO;
339 | ENABLE_STRICT_OBJC_MSGSEND = YES;
340 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
341 | GCC_C_LANGUAGE_STANDARD = gnu99;
342 | GCC_NO_COMMON_BLOCKS = YES;
343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
345 | GCC_WARN_UNDECLARED_SELECTOR = YES;
346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
347 | GCC_WARN_UNUSED_FUNCTION = YES;
348 | GCC_WARN_UNUSED_VARIABLE = YES;
349 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
350 | MTL_ENABLE_DEBUG_INFO = NO;
351 | SDKROOT = iphoneos;
352 | SUPPORTED_PLATFORMS = iphoneos;
353 | TARGETED_DEVICE_FAMILY = "1,2";
354 | VALIDATE_PRODUCT = YES;
355 | };
356 | name = Profile;
357 | };
358 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
359 | isa = XCBuildConfiguration;
360 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
361 | buildSettings = {
362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
363 | CLANG_ENABLE_MODULES = YES;
364 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
365 | DEVELOPMENT_TEAM = 54K3FT3CBT;
366 | ENABLE_BITCODE = NO;
367 | INFOPLIST_FILE = Runner/Info.plist;
368 | LD_RUNPATH_SEARCH_PATHS = (
369 | "$(inherited)",
370 | "@executable_path/Frameworks",
371 | );
372 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver;
373 | PRODUCT_NAME = "$(TARGET_NAME)";
374 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
375 | SWIFT_VERSION = 5.0;
376 | VERSIONING_SYSTEM = "apple-generic";
377 | };
378 | name = Profile;
379 | };
380 | 331C8088294A63A400263BE5 /* Debug */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | BUNDLE_LOADER = "$(TEST_HOST)";
384 | CODE_SIGN_STYLE = Automatic;
385 | CURRENT_PROJECT_VERSION = 1;
386 | GENERATE_INFOPLIST_FILE = YES;
387 | MARKETING_VERSION = 1.0;
388 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver.RunnerTests;
389 | PRODUCT_NAME = "$(TARGET_NAME)";
390 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
391 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
392 | SWIFT_VERSION = 5.0;
393 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
394 | };
395 | name = Debug;
396 | };
397 | 331C8089294A63A400263BE5 /* Release */ = {
398 | isa = XCBuildConfiguration;
399 | buildSettings = {
400 | BUNDLE_LOADER = "$(TEST_HOST)";
401 | CODE_SIGN_STYLE = Automatic;
402 | CURRENT_PROJECT_VERSION = 1;
403 | GENERATE_INFOPLIST_FILE = YES;
404 | MARKETING_VERSION = 1.0;
405 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver.RunnerTests;
406 | PRODUCT_NAME = "$(TARGET_NAME)";
407 | SWIFT_VERSION = 5.0;
408 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
409 | };
410 | name = Release;
411 | };
412 | 331C808A294A63A400263BE5 /* Profile */ = {
413 | isa = XCBuildConfiguration;
414 | buildSettings = {
415 | BUNDLE_LOADER = "$(TEST_HOST)";
416 | CODE_SIGN_STYLE = Automatic;
417 | CURRENT_PROJECT_VERSION = 1;
418 | GENERATE_INFOPLIST_FILE = YES;
419 | MARKETING_VERSION = 1.0;
420 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver.RunnerTests;
421 | PRODUCT_NAME = "$(TARGET_NAME)";
422 | SWIFT_VERSION = 5.0;
423 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
424 | };
425 | name = Profile;
426 | };
427 | 97C147031CF9000F007C117D /* Debug */ = {
428 | isa = XCBuildConfiguration;
429 | buildSettings = {
430 | ALWAYS_SEARCH_USER_PATHS = NO;
431 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
432 | CLANG_ANALYZER_NONNULL = YES;
433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
434 | CLANG_CXX_LIBRARY = "libc++";
435 | CLANG_ENABLE_MODULES = YES;
436 | CLANG_ENABLE_OBJC_ARC = YES;
437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
438 | CLANG_WARN_BOOL_CONVERSION = YES;
439 | CLANG_WARN_COMMA = YES;
440 | CLANG_WARN_CONSTANT_CONVERSION = YES;
441 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
442 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
443 | CLANG_WARN_EMPTY_BODY = YES;
444 | CLANG_WARN_ENUM_CONVERSION = YES;
445 | CLANG_WARN_INFINITE_RECURSION = YES;
446 | CLANG_WARN_INT_CONVERSION = YES;
447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
448 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
449 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
452 | CLANG_WARN_STRICT_PROTOTYPES = YES;
453 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
454 | CLANG_WARN_UNREACHABLE_CODE = YES;
455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
457 | COPY_PHASE_STRIP = NO;
458 | DEBUG_INFORMATION_FORMAT = dwarf;
459 | ENABLE_STRICT_OBJC_MSGSEND = YES;
460 | ENABLE_TESTABILITY = YES;
461 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
462 | GCC_C_LANGUAGE_STANDARD = gnu99;
463 | GCC_DYNAMIC_NO_PIC = NO;
464 | GCC_NO_COMMON_BLOCKS = YES;
465 | GCC_OPTIMIZATION_LEVEL = 0;
466 | GCC_PREPROCESSOR_DEFINITIONS = (
467 | "DEBUG=1",
468 | "$(inherited)",
469 | );
470 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
471 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
472 | GCC_WARN_UNDECLARED_SELECTOR = YES;
473 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
474 | GCC_WARN_UNUSED_FUNCTION = YES;
475 | GCC_WARN_UNUSED_VARIABLE = YES;
476 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
477 | MTL_ENABLE_DEBUG_INFO = YES;
478 | ONLY_ACTIVE_ARCH = YES;
479 | SDKROOT = iphoneos;
480 | TARGETED_DEVICE_FAMILY = "1,2";
481 | };
482 | name = Debug;
483 | };
484 | 97C147041CF9000F007C117D /* Release */ = {
485 | isa = XCBuildConfiguration;
486 | buildSettings = {
487 | ALWAYS_SEARCH_USER_PATHS = NO;
488 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
489 | CLANG_ANALYZER_NONNULL = YES;
490 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
491 | CLANG_CXX_LIBRARY = "libc++";
492 | CLANG_ENABLE_MODULES = YES;
493 | CLANG_ENABLE_OBJC_ARC = YES;
494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
495 | CLANG_WARN_BOOL_CONVERSION = YES;
496 | CLANG_WARN_COMMA = YES;
497 | CLANG_WARN_CONSTANT_CONVERSION = YES;
498 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
499 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
500 | CLANG_WARN_EMPTY_BODY = YES;
501 | CLANG_WARN_ENUM_CONVERSION = YES;
502 | CLANG_WARN_INFINITE_RECURSION = YES;
503 | CLANG_WARN_INT_CONVERSION = YES;
504 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
505 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
506 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
507 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
508 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
509 | CLANG_WARN_STRICT_PROTOTYPES = YES;
510 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
511 | CLANG_WARN_UNREACHABLE_CODE = YES;
512 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
513 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
514 | COPY_PHASE_STRIP = NO;
515 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
516 | ENABLE_NS_ASSERTIONS = NO;
517 | ENABLE_STRICT_OBJC_MSGSEND = YES;
518 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
519 | GCC_C_LANGUAGE_STANDARD = gnu99;
520 | GCC_NO_COMMON_BLOCKS = YES;
521 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
522 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
523 | GCC_WARN_UNDECLARED_SELECTOR = YES;
524 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
525 | GCC_WARN_UNUSED_FUNCTION = YES;
526 | GCC_WARN_UNUSED_VARIABLE = YES;
527 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
528 | MTL_ENABLE_DEBUG_INFO = NO;
529 | SDKROOT = iphoneos;
530 | SUPPORTED_PLATFORMS = iphoneos;
531 | SWIFT_COMPILATION_MODE = wholemodule;
532 | SWIFT_OPTIMIZATION_LEVEL = "-O";
533 | TARGETED_DEVICE_FAMILY = "1,2";
534 | VALIDATE_PRODUCT = YES;
535 | };
536 | name = Release;
537 | };
538 | 97C147061CF9000F007C117D /* Debug */ = {
539 | isa = XCBuildConfiguration;
540 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
541 | buildSettings = {
542 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
543 | CLANG_ENABLE_MODULES = YES;
544 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
545 | DEVELOPMENT_TEAM = 54K3FT3CBT;
546 | ENABLE_BITCODE = NO;
547 | INFOPLIST_FILE = Runner/Info.plist;
548 | LD_RUNPATH_SEARCH_PATHS = (
549 | "$(inherited)",
550 | "@executable_path/Frameworks",
551 | );
552 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver;
553 | PRODUCT_NAME = "$(TARGET_NAME)";
554 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
555 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
556 | SWIFT_VERSION = 5.0;
557 | VERSIONING_SYSTEM = "apple-generic";
558 | };
559 | name = Debug;
560 | };
561 | 97C147071CF9000F007C117D /* Release */ = {
562 | isa = XCBuildConfiguration;
563 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
564 | buildSettings = {
565 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
566 | CLANG_ENABLE_MODULES = YES;
567 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
568 | DEVELOPMENT_TEAM = 54K3FT3CBT;
569 | ENABLE_BITCODE = NO;
570 | INFOPLIST_FILE = Runner/Info.plist;
571 | LD_RUNPATH_SEARCH_PATHS = (
572 | "$(inherited)",
573 | "@executable_path/Frameworks",
574 | );
575 | PRODUCT_BUNDLE_IDENTIFIER = com.rightdevs.statusSaver;
576 | PRODUCT_NAME = "$(TARGET_NAME)";
577 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
578 | SWIFT_VERSION = 5.0;
579 | VERSIONING_SYSTEM = "apple-generic";
580 | };
581 | name = Release;
582 | };
583 | /* End XCBuildConfiguration section */
584 |
585 | /* Begin XCConfigurationList section */
586 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
587 | isa = XCConfigurationList;
588 | buildConfigurations = (
589 | 331C8088294A63A400263BE5 /* Debug */,
590 | 331C8089294A63A400263BE5 /* Release */,
591 | 331C808A294A63A400263BE5 /* Profile */,
592 | );
593 | defaultConfigurationIsVisible = 0;
594 | defaultConfigurationName = Release;
595 | };
596 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
597 | isa = XCConfigurationList;
598 | buildConfigurations = (
599 | 97C147031CF9000F007C117D /* Debug */,
600 | 97C147041CF9000F007C117D /* Release */,
601 | 249021D3217E4FDB00AE95B9 /* Profile */,
602 | );
603 | defaultConfigurationIsVisible = 0;
604 | defaultConfigurationName = Release;
605 | };
606 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
607 | isa = XCConfigurationList;
608 | buildConfigurations = (
609 | 97C147061CF9000F007C117D /* Debug */,
610 | 97C147071CF9000F007C117D /* Release */,
611 | 249021D4217E4FDB00AE95B9 /* Profile */,
612 | );
613 | defaultConfigurationIsVisible = 0;
614 | defaultConfigurationName = Release;
615 | };
616 | /* End XCConfigurationList section */
617 | };
618 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
619 | }
620 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krupal4/StatusSaver/f94ee8dfb52ac444758e2b03dd0e7aab513f63cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | 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.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Status Saver
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | status_saver
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | CADisableMinimumFrameDurationOnPhone
45 |
46 | UIApplicationSupportsIndirectInputEvents
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/src/localization/l10n
2 | template-arb-file: app_en.arb
3 | output-localization-file: app_localizations.dart
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:dynamic_color/dynamic_color.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_localizations/flutter_localizations.dart';
4 | import 'package:flutter_native_splash/flutter_native_splash.dart';
5 | import 'package:flutter_riverpod/flutter_riverpod.dart';
6 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
7 | import 'package:material_color_utilities/palettes/core_palette.dart';
8 | import 'package:status_saver/src/home/views/home_screen.dart';
9 | import 'package:status_saver/src/localization/notifiers/locale_notifier.dart';
10 | import 'package:status_saver/src/theme/app_theme.dart';
11 | import 'package:status_saver/src/theme/notifiers/theme_mode_notifier.dart';
12 |
13 | void main() async {
14 | WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
15 | FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
16 | CorePalette? corePalette = await DynamicColorPlugin.getCorePalette();
17 | FlutterNativeSplash.remove();
18 | runApp(ProviderScope(child: MyApp(corePalette: corePalette)));
19 | }
20 |
21 | class MyApp extends ConsumerWidget {
22 | final CorePalette? corePalette;
23 | const MyApp({super.key, this.corePalette});
24 |
25 | @override
26 | Widget build(BuildContext context, WidgetRef ref) {
27 | return MaterialApp(
28 | restorationScopeId: 'app',
29 | title: 'Whatsapp Status Saver',
30 | localizationsDelegates: const [
31 | GlobalMaterialLocalizations.delegate,
32 | GlobalWidgetsLocalizations.delegate,
33 | GlobalCupertinoLocalizations.delegate,
34 | AppLocalizations.delegate
35 | ],
36 | locale: ref.watch(localeProvider), // TODO: revisit implementation
37 | supportedLocales: AppLocalizations.supportedLocales,
38 | themeMode: ref.watch(themeModeProvider),
39 | theme: AppTheme.themeData(corePalette, Brightness.light),
40 | darkTheme: AppTheme.themeData(corePalette, Brightness.dark),
41 | home: const HomeScreen(),
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/src/common/constants/directory_paths.dart:
--------------------------------------------------------------------------------
1 | const String savedStatusesDirectory =
2 | "/storage/emulated/0/Download/Saved Statuses";
3 |
--------------------------------------------------------------------------------
/lib/src/common/extensions/async_value.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:status_saver/src/common/views/circular_loader.dart';
4 | import 'package:status_saver/src/common/views/common_error_screen.dart';
5 |
6 | extension WhenAsyncValue on AsyncValue {
7 | Widget whenWidget(Widget Function(T) data) => when(
8 | data: data,
9 | error: commonErrorScreen,
10 | loading: CircularLoader.new,
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/lib/src/common/extensions/permission_handler.dart:
--------------------------------------------------------------------------------
1 | import 'package:permission_handler/permission_handler.dart';
2 | import 'package:status_saver/src/debug/console_log.dart';
3 |
4 | extension CustomPermissionHandler on Permission {
5 | Future requestAndHandle() async {
6 | PermissionStatus status = await request();
7 |
8 | if (status.isPermanentlyDenied) {
9 | // The user opted to never again see the permission request dialog for this
10 | // app. The only way to change the permission's status now is to let the
11 | // user manually enables it in the system settings.
12 | openAppSettings();
13 | }
14 | return status.isGranted;
15 | }
16 | }
17 |
18 | extension CustomPermissionListHandler on List {
19 | Future requestAndHandle() async {
20 | Iterable statuses = (await request()).values;
21 | consoleLog(statuses, "statueses resp");
22 |
23 | if (statuses
24 | .any((status) => status == PermissionStatus.permanentlyDenied)) {
25 | // The user opted to never again see the permission request dialog for this
26 | // app. The only way to change the permission's status now is to let the
27 | // user manually enables it in the system settings.
28 | openAppSettings();
29 | }
30 | return statuses.every((status) => status.isGranted);
31 | }
32 |
33 | Future get isGranted async {
34 | return (await Future.wait(
35 | map((permission) => permission.status),
36 | ))
37 | .every((status) => status.isGranted);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/src/common/helpers/android_api_level_helper.dart:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lib/src/common/helpers/get_video_thumbnail.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:video_thumbnail/video_thumbnail.dart';
3 |
4 | Future getVideoThumbnailData(String videoPath) async {
5 | return await VideoThumbnail.thumbnailData(
6 | video: videoPath,
7 | imageFormat: ImageFormat.JPEG,
8 | quality: 50,
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/lib/src/common/helpers/show_toast.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:fluttertoast/fluttertoast.dart';
3 |
4 | void showToast(
5 | {String Function()? getMessage,
6 | String? message,
7 | Toast toastLength = Toast.LENGTH_SHORT}) {
8 | if (message == null && getMessage == null) {
9 | throw ArgumentError('Either message or getMessage is required.');
10 | }
11 | Fluttertoast.showToast(
12 | msg: message ?? (getMessage != null ? getMessage() : ""),
13 | toastLength: toastLength,
14 | gravity: ToastGravity.BOTTOM,
15 | timeInSecForIosWeb: 1,
16 | backgroundColor: Colors.greenAccent.shade200,
17 | textColor: Colors.black,
18 | fontSize: 16.0);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/src/common/helpers/statuses_helper.dart:
--------------------------------------------------------------------------------
1 | import 'package:status_saver/src/common/constants/directory_paths.dart';
2 |
3 | // List getDirectoryPaths(TabType tabType) {
4 | // return tabType == TabType.recent
5 | // ? recentDirectoryPaths
6 | // : const [savedStatusesDirectory];
7 | // }
8 |
9 | String getSavedStatusPath(String statusPath) =>
10 | "$savedStatusesDirectory/${statusPath.split('/').last}";
11 |
12 | bool isItSavedStatus(statusPath) =>
13 | getSavedStatusPath(statusPath).compareTo(statusPath) == 0;
14 |
15 | // String getThumbnailPath(String videoPath) {
16 | // return "$thumbnailsDirectoryPath/${videoPath.split("/").last.replaceAll(mp4, png)}";
17 | // }
--------------------------------------------------------------------------------
/lib/src/common/helpers/storage_helper.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:status_saver/src/home/models/whatsapp_type_enum.dart';
4 |
5 | String getStatusesPath(WhatsAppType whatsAppType, bool isAndroid11OrLater) {
6 | if (whatsAppType == WhatsAppType.whatsApp) {
7 | return isAndroid11OrLater
8 | ? "Android/media/com.whatsapp/WhatsApp/Media/.Statuses"
9 | : "";
10 | } else if (whatsAppType == WhatsAppType.w4b) {
11 | return isAndroid11OrLater
12 | ? "Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses"
13 | : "";
14 | } else {
15 | throw Exception(
16 | "Please provide statuses dir path for whatsapp type: '$whatsAppType'");
17 | }
18 | }
19 |
20 | bool isItStatusFile(String filePath) {
21 | return filePath.endsWith(".mp4") || filePath.endsWith(".jpg");
22 | }
23 |
24 | List getDirectoryFilePaths(
25 | String dirPath, {
26 | bool Function(String)? whereCallback,
27 | }) {
28 | whereCallback ??= (_) => true;
29 |
30 | try {
31 | Directory dir = Directory(dirPath);
32 | if (!dir.existsSync()) {
33 | return [];
34 | }
35 |
36 | return dir
37 | .listSync()
38 | .map((fileSystemEntity) => fileSystemEntity.path)
39 | .where(whereCallback)
40 | .toList();
41 | } catch (e) {
42 | return List.empty();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/src/common/views/circular_loader.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CircularLoader extends StatelessWidget {
4 | const CircularLoader({super.key});
5 |
6 | @override
7 | Widget build(BuildContext context) {
8 | return const Center(
9 | child: CircularProgressIndicator(),
10 | );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/lib/src/common/views/common_error_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | Widget commonErrorScreen(
4 | final Object error,
5 | final StackTrace stackTrace,
6 | ) =>
7 | Column(
8 | children: [
9 | const Text(
10 | "something went wrong, please restart app",
11 | style: TextStyle(
12 | fontSize: 18,
13 | ),
14 | ),
15 | Text(
16 | error.toString(),
17 | style: const TextStyle(fontSize: 22),
18 | )
19 | ],
20 | );
21 |
--------------------------------------------------------------------------------
/lib/src/debug/console_log.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 |
3 | void consoleLog(Object? obj, [String? message]) {
4 | debugPrint('''
5 | ----------------------------
6 | ${message == null ? obj : "$message : $obj"}
7 | ----------------------------
8 | ''');
9 | }
10 |
--------------------------------------------------------------------------------
/lib/src/debug/red_container.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class RedContainer extends StatelessWidget {
4 | const RedContainer({super.key, required this.child});
5 | final Widget child;
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return Container(
10 | decoration: BoxDecoration(
11 | border: Border.all(
12 | color: Colors.red,
13 | ),
14 | ),
15 | child: child,
16 | );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/src/home/models/android_info.dart:
--------------------------------------------------------------------------------
1 | class AndroidInfo {
2 | final int androidSdkApiLevel;
3 | final bool isAndroid11OrLater;
4 | final bool isAndroid13OrLater;
5 |
6 | const AndroidInfo({
7 | required this.androidSdkApiLevel,
8 | required this.isAndroid11OrLater,
9 | required this.isAndroid13OrLater,
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/lib/src/home/models/tab_type.dart:
--------------------------------------------------------------------------------
1 | enum StatusTabType {
2 | recent,
3 | saved,
4 | }
5 |
--------------------------------------------------------------------------------
/lib/src/home/models/whatsapp_type_enum.dart:
--------------------------------------------------------------------------------
1 | enum WhatsAppType {
2 | whatsApp,
3 | w4b,
4 | }
5 |
--------------------------------------------------------------------------------
/lib/src/home/notifiers/selected_tab_index_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_riverpod/flutter_riverpod.dart';
2 |
3 | const recentTabIndex = 0;
4 | const savedTabIndex = 1;
5 |
6 | class SelectedTabNotifier extends Notifier {
7 | @override
8 | int build() {
9 | return recentTabIndex;
10 | }
11 |
12 | void set(int selectedIndex) {
13 | state = selectedIndex;
14 | }
15 | }
16 |
17 | final selectedTabIndexProvider =
18 | NotifierProvider(SelectedTabNotifier.new);
19 |
--------------------------------------------------------------------------------
/lib/src/home/services/android_info_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:device_info_plus/device_info_plus.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:status_saver/src/home/models/android_info.dart';
4 |
5 | final androidInfoProvider = FutureProvider((ref) async {
6 | DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
7 | AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
8 | final int androidSdkApiLevel = androidInfo.version.sdkInt;
9 |
10 | final bool isAndroid11OrLater = androidSdkApiLevel >= 30;
11 | final bool isAndroid13OrLater = androidSdkApiLevel >= 33;
12 | return AndroidInfo(
13 | androidSdkApiLevel: androidSdkApiLevel,
14 | isAndroid11OrLater: isAndroid11OrLater,
15 | isAndroid13OrLater: isAndroid13OrLater,
16 | );
17 | });
18 |
--------------------------------------------------------------------------------
/lib/src/home/services/whatsapp_type_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 |
4 | import 'package:appcheck/appcheck.dart';
5 | import 'package:flutter/foundation.dart';
6 | import 'package:flutter/services.dart';
7 | import 'package:flutter_riverpod/flutter_riverpod.dart';
8 | import 'package:status_saver/src/home/models/whatsapp_type_enum.dart';
9 |
10 | class WhatsAppTypeNotifier extends AsyncNotifier {
11 | @override
12 | FutureOr build() async {
13 | final Map packagesMap = {
14 | WhatsAppType.whatsApp: "com.whatsapp",
15 | WhatsAppType.w4b: "com.whatsapp.w4b"
16 | };
17 | for (MapEntry packageMap in packagesMap.entries) {
18 | if (Platform.isAndroid) {
19 | final app = await _checkAppAvailability(packageMap.value);
20 | if (app != null) {
21 | return packageMap.key;
22 | }
23 | }
24 | }
25 | return null;
26 | }
27 |
28 | Future _checkAppAvailability(String package) async {
29 | try {
30 | final app = await AppCheck.checkAvailability(package);
31 | return app;
32 | } on PlatformException catch (e) {
33 | if (e.code == '400' && e.message?.contains('App not found') == true) {
34 | debugPrint('App not found for package $package');
35 | // Handle the app not being found (e.g., show a user message or handle gracefully)
36 | } else {
37 | debugPrint('PlatformException: ${e.message}');
38 | // Handle other platform exceptions
39 | }
40 | } catch (error) {
41 | debugPrint(
42 | 'General error checking availability for package $package: $error');
43 | // Handle other general exceptions
44 | }
45 | return null;
46 | }
47 | }
48 |
49 | final whatsAppTypeProvider =
50 | AsyncNotifierProvider(
51 | WhatsAppTypeNotifier.new);
52 |
--------------------------------------------------------------------------------
/lib/src/home/views/home_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:status_saver/src/common/extensions/async_value.dart';
4 | import 'package:status_saver/src/debug/console_log.dart';
5 | import 'package:status_saver/src/home/models/tab_type.dart';
6 | import 'package:status_saver/src/home/notifiers/selected_tab_index_notifier.dart';
7 | import 'package:status_saver/src/home/services/whatsapp_type_notifier.dart';
8 | import 'package:status_saver/src/home/views/my_drawer.dart';
9 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
10 | import 'package:status_saver/src/statuses/views/statuses_screen.dart';
11 | import 'package:status_saver/src/storage_permission/notifiers/storage_permission_notifier.dart';
12 | import 'package:status_saver/src/storage_permission/views/give_permissions_screen.dart';
13 |
14 | class HomeScreen extends ConsumerWidget {
15 | const HomeScreen({super.key});
16 |
17 | @override
18 | Widget build(BuildContext context, WidgetRef ref) {
19 | return Scaffold(
20 | appBar: AppBar(
21 | elevation: 5,
22 | title: Text(context.l10n.appTitle),
23 | ),
24 | bottomNavigationBar: _navigationBar(context, ref),
25 | body: [
26 | () => _recentStatusesScreen(ref),
27 | () => _savedStatusesScreen(ref),
28 | ][ref.watch(selectedTabIndexProvider)](),
29 | drawer: const MyDrawer(),
30 | );
31 | }
32 |
33 | Widget _recentStatusesScreen(WidgetRef ref) =>
34 | ref.watch(whatsAppTypeProvider).whenWidget(
35 | (whatsAppType) {
36 | if (whatsAppType == null) {
37 | return const Center(
38 | child: Text("No WhatsApp found on this mobile."));
39 | }
40 | final AsyncValue storagePermissionAsync =
41 | ref.watch(recentStoragePermissionProvider);
42 | return storagePermissionAsync.whenWidget(
43 | (isStoragePermitted) {
44 | return isStoragePermitted
45 | ? const StatusesScreen(tabType: StatusTabType.recent)
46 | : GivePermissionsScreen(
47 | onRequestPermission: ref
48 | .read(recentStoragePermissionProvider.notifier)
49 | .request,
50 | );
51 | },
52 | );
53 | },
54 | );
55 |
56 | Widget _savedStatusesScreen(WidgetRef ref) =>
57 | ref.watch(savedStoragePermissionProvider).whenWidget(
58 | (isStoragePermitted) {
59 | consoleLog(isStoragePermitted, "saves storage permitted?");
60 | return isStoragePermitted
61 | ? const StatusesScreen(
62 | tabType: StatusTabType.saved,
63 | )
64 | : GivePermissionsScreen(
65 | onRequestPermission:
66 | ref.read(savedStoragePermissionProvider.notifier).request,
67 | );
68 | },
69 | );
70 |
71 | NavigationBar _navigationBar(BuildContext context, WidgetRef ref) {
72 | final int selectedTabIndex = ref.watch(selectedTabIndexProvider);
73 | return NavigationBar(
74 | selectedIndex: selectedTabIndex,
75 | onDestinationSelected: (value) =>
76 | ref.read(selectedTabIndexProvider.notifier).set(value),
77 | destinations: [
78 | NavigationDestination(
79 | selectedIcon: const Icon(Icons.auto_stories_rounded),
80 | icon: const Icon(Icons.auto_stories_outlined),
81 | label: context.l10n.recentStatuses,
82 | ),
83 | NavigationDestination(
84 | selectedIcon: const Icon(Icons.save_rounded),
85 | icon: const Icon(Icons.save_outlined),
86 | label: context.l10n.savedStatuses,
87 | ),
88 | ],
89 | );
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/lib/src/home/views/my_drawer.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
4 | import 'package:status_saver/src/localization/enums/language_code.dart';
5 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
6 | import 'package:status_saver/src/localization/extensions/on_string.dart';
7 | import 'package:status_saver/src/localization/l10n/l10n.dart';
8 | import 'package:status_saver/src/localization/notifiers/locale_notifier.dart';
9 | import 'package:status_saver/src/theme/notifiers/theme_mode_notifier.dart';
10 |
11 | // TODO: re visit this
12 | const String applicationVersion = "1.0.0";
13 | String applicationName(BuildContext context) => context.l10n.appTitle;
14 |
15 | Icon applicationIcon =
16 | const Icon(FontAwesomeIcons.squareVirus); // TODO: provide application icon
17 |
18 | class MyDrawer extends ConsumerWidget {
19 | const MyDrawer({super.key});
20 |
21 | @override
22 | Widget build(BuildContext context, WidgetRef ref) {
23 | return Drawer(
24 | elevation: 2.5,
25 | child: ListView(
26 | children: [
27 | ListTile(
28 | title: Text(context.l10n.appLanguageLabel),
29 | leading: const Icon(Icons.translate),
30 | onTap: () {
31 | Navigator.of(context).pop();
32 | _showLanguageChooser(context, ref);
33 | },
34 | ),
35 | ListTile(
36 | title: Text(context.l10n.appThemeModeLabel),
37 | leading: const Icon(Icons.dark_mode_outlined),
38 | onTap: () {
39 | Navigator.of(context).pop();
40 | _showThemeModeSelector(context, ref);
41 | },
42 | ),
43 | ListTile(
44 | title: Text(context.l10n.aboutButtonLabel),
45 | leading: const Icon(Icons.info),
46 | onTap: () {
47 | Navigator.of(context).pop();
48 | showAboutDialog(
49 | context: context,
50 | applicationIcon: applicationIcon,
51 | applicationVersion: applicationVersion,
52 | applicationName: applicationName(context),
53 | children: [
54 | Text(
55 | context.l10n.howDoesItWorkTitle,
56 | style: const TextStyle(fontSize: 22),
57 | ),
58 | Text(
59 | context.l10n.howDoesItWorkDescription,
60 | style: const TextStyle(fontSize: 18),
61 | )
62 | ]);
63 | },
64 | ),
65 | ],
66 | ),
67 | );
68 | }
69 |
70 | Future _showThemeModeSelector(BuildContext context, WidgetRef ref) {
71 | return showDialog(
72 | context: context,
73 | builder: (context) {
74 | final themeModeNotifier = ref.watch(themeModeProvider.notifier);
75 | return AlertDialog(
76 | content: SizedBox(
77 | height: MediaQuery.of(context).size.height *
78 | 0.22, // FIXME: give auto height
79 | width: MediaQuery.of(context).size.width * 0.7,
80 | child: Scrollbar(
81 | child: Padding(
82 | padding: const EdgeInsets.only(
83 | right: 12,
84 | ),
85 | child: ListView.builder(
86 | itemCount: MyThemes.themeModeTypes(context).length,
87 | itemBuilder: (context, index) {
88 | return ListTile(
89 | title: Text(MyThemes.themeModeTypes(context)[index]),
90 | leading: MyThemes.themeModeIcons[index],
91 | trailing: themeModeNotifier.themeMode ==
92 | MyThemes.themeModes[index]
93 | ? const Icon(Icons.check)
94 | : null,
95 | onTap: () {
96 | themeModeNotifier.setThemeMode(
97 | MyThemes.themeModes[index], context);
98 | },
99 | );
100 | },
101 | ),
102 | ),
103 | ),
104 | ),
105 | actions: [
106 | TextButton(
107 | onPressed: () {
108 | Navigator.of(context).pop();
109 | },
110 | child: Text(context.l10n.closeButtonLabel))
111 | ],
112 | );
113 | });
114 | }
115 |
116 | void _showLanguageChooser(BuildContext context, WidgetRef ref) {
117 | final localeProviderNotifier = ref.watch(localeProvider.notifier);
118 | LanguageCode tempSelectedLanguageCode =
119 | localeProviderNotifier.locale?.languageCode.toLanguageCode() ??
120 | systemLanguageCode;
121 | showDialog(
122 | context: context,
123 | builder: (context) {
124 | return StatefulBuilder(builder: (context, setState) {
125 | return AlertDialog(
126 | contentPadding: const EdgeInsets.only(top: 4),
127 | title: Text(context.l10n.appLanguageLabel,
128 | style: const TextStyle(fontSize: 18)),
129 | content: SizedBox(
130 | height: double.maxFinite, // FIXME: give auto height
131 | width: MediaQuery.of(context).size.width * 0.85,
132 | child: Scrollbar(
133 | child: Padding(
134 | padding: const EdgeInsets.only(
135 | right: 12,
136 | ),
137 | child: ListView.builder(
138 | itemCount: LanguageCode.values.length,
139 | itemBuilder: (context, index) {
140 | final LanguageCode languageCode =
141 | LanguageCode.values[index];
142 | return RadioListTile(
143 | value: LanguageCode.values[index],
144 | groupValue: tempSelectedLanguageCode,
145 | onChanged: (value) {
146 | setState(() {
147 | tempSelectedLanguageCode = value!;
148 | });
149 | },
150 | title: Text(
151 | '${L10n.getLanguageName(languageCode, context)} ${languageCode != systemLanguageCode ? "[${languageCode.name}]" : ""}'));
152 | },
153 | ),
154 | ),
155 | ),
156 | ),
157 | actions: [
158 | TextButton(
159 | onPressed: () => Navigator.of(context).pop(),
160 | child: Text(context.l10n.cancelButtonLabel),
161 | ),
162 | TextButton(
163 | onPressed: () {
164 | Navigator.of(context).pop();
165 | localeProviderNotifier.setLocale(
166 | tempSelectedLanguageCode, context);
167 | },
168 | child: Text(context.l10n.okButtonLabel),
169 | ),
170 | ],
171 | );
172 | });
173 | });
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/lib/src/localization/enums/language_code.dart:
--------------------------------------------------------------------------------
1 | enum LanguageCode {
2 | system,
3 | en,
4 | af,
5 | ar,
6 | az,
7 | bn,
8 | es,
9 | gu,
10 | hi,
11 | ja,
12 | kn,
13 | ko,
14 | mr,
15 | pa,
16 | ta,
17 | te,
18 | ur
19 | }
--------------------------------------------------------------------------------
/lib/src/localization/extensions/on_build_context.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
3 | export 'package:flutter_gen/gen_l10n/app_localizations.dart';
4 |
5 | extension LocalizationsContext on BuildContext {
6 | AppLocalizations get l10n => AppLocalizations.of(this)!;
7 | }
8 |
--------------------------------------------------------------------------------
/lib/src/localization/extensions/on_string.dart:
--------------------------------------------------------------------------------
1 | import 'package:status_saver/src/localization/enums/language_code.dart';
2 |
3 | extension LanguageCodeExtension on String {
4 | LanguageCode toLanguageCode() {
5 | return LanguageCode.values.firstWhere((element) => element.name == this);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_af.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "Hallo Wêreld!",
3 | "appTitle": "Statusbewaarder",
4 | "recentStatuses": "Onlangs",
5 | "savedStatuses": "Bewaar",
6 | "statusSavedMessage": "Status bewaar",
7 | "noSavedStatusesMessage": "Geen bewaarde statuses",
8 | "noWhatsappFoundMessage": "Whatsapp bestaan nie op jou selfoon nie",
9 | "appLanguageLabel": "App Taal",
10 | "saveButtonLabel": "Bewaar",
11 | "shareButtonLabel": "Deel",
12 | "okButtonLabel": "OK",
13 | "cancelButtonLabel": "KANSELLEER",
14 | "closeButtonLabel": "SLUIT",
15 | "howDoesItWorkTitle": "Hoe werk dit?",
16 | "howDoesItWorkDescription": "Ons is nie geaffilieer of amptelik verbind met WhatsApp Inc op enige manier nie. En ons het geen toegang tot jou WhatsApp-boodskappe nie.\n\nHierdie toepassing is bedoel om jou 'n geriefliker manier te bied om deur, te bewaar en te deel die statusafbeeldings en -video's wat in jou toestel se opbergruimte gekasheer is.",
17 | "aboutButtonLabel": "Oor die App",
18 | "appThemeModeLabel": "App Tema-modus",
19 | "systemDefaultLabel": "Standaard Sisteem",
20 | "couldNotSaveYourLanguagePreference": "Kon jou taalvoorkeur nie stoor nie",
21 | "couldNotSaveYourThemePreference": "Kon jou temavoorkeur nie stoor nie",
22 | "giveStoragePermission": "Gee stoorregte",
23 | "needToGiveStoragePermission": "Jy moet stoorregte vir hierdie toepassing gee.",
24 | "couldNotOpenAppSettings": "Kon nie toepassingsinstellings vir stoorregte oopmaak nie.",
25 | "allowStoragePermission": "Staan stoorregte toe vir Statusbewaarder",
26 | "openWhatsAppLabel": "Maak WhatsApp oop",
27 | "openW4BLabel": "Maak WhatsApp Business oop",
28 | "doNotHaveSeenStatusesMessage": "Jy het nog geen statuses gesien nie, gaan kyk na sommige statuses",
29 | "systemThemeLabel": "Sisteemtema",
30 | "lightThemeLabel": "Ligte Tema",
31 | "darkThemeLabel": "Donker Tema",
32 | "exitButtonLabel": "SLUIT",
33 | "exitWarningTitle": "Verlaat Statusbewaarder",
34 | "exitWarningMessage": "Is jy seker dat jy wil afsluit?",
35 | "deleteButtonLabel": "VERWYDER",
36 | "deleteStatusWarningTitle": "Verwyder Status",
37 | "deleteStatusWarningMessage": "Wil jy hierdie status permanent verwyder?",
38 | "deletedStatusMessage": "Status Verwyder"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_ar.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "مرحبًا بالعالم!",
3 | "appTitle": "حفّاظ الحالة",
4 | "recentStatuses": "الأحداث الأخيرة",
5 | "savedStatuses": "الحالات المحفوظة",
6 | "statusSavedMessage": "تم حفظ الحالة",
7 | "noSavedStatusesMessage": "لا توجد حالات محفوظة",
8 | "noWhatsappFoundMessage": "لا يوجد تطبيق واتساب على جوالك",
9 | "appLanguageLabel": "لغة التطبيق",
10 | "saveButtonLabel": "حفظ",
11 | "shareButtonLabel": "مشاركة",
12 | "okButtonLabel": "موافق",
13 | "cancelButtonLabel": "إلغاء",
14 | "closeButtonLabel": "إغلاق",
15 | "howDoesItWorkTitle": "كيف يعمل؟",
16 | "howDoesItWorkDescription": "نحن لسنا مرتبطين أو متصلين رسميًا بشركة واتساب بأي شكل من الأشكال. وليس لدينا أي وصول إلى رسائل واتساب الخاصة بك.\n\nتهدف هذه التطبيق لتوفير وسيلة أكثر ملاءمة لاستكشاف وحفظ ومشاركة الصور ومقاطع الفيديو للحالات المخزنة في ذاكرة جهازك.",
17 | "aboutButtonLabel": "حول التطبيق",
18 | "appThemeModeLabel": "وضعية تصميم التطبيق",
19 | "systemDefaultLabel": "الوضعية الافتراضية للنظام",
20 | "couldNotSaveYourLanguagePreference": "تعذر حفظ تفضيلات اللغة الخاصة بك",
21 | "couldNotSaveYourThemePreference": "تعذر حفظ تفضيلات التصميم الخاصة بك",
22 | "giveStoragePermission": "منح إذن التخزين",
23 | "needToGiveStoragePermission": "يجب عليك منح إذن التخزين لهذا التطبيق.",
24 | "couldNotOpenAppSettings": "تعذر فتح إعدادات التطبيق لإذن التخزين.",
25 | "allowStoragePermission": "السماح بإذن التخزين لحفّاظ الحالة",
26 | "openWhatsAppLabel": "فتح واتساب",
27 | "openW4BLabel": "فتح واتساب بزنس",
28 | "doNotHaveSeenStatusesMessage": "لم تشاهد أي حالات حتى الآن، اذهب وشاهد بعض الحالات",
29 | "systemThemeLabel": "وضعية التصميم النظام",
30 | "lightThemeLabel": "الوضع الفاتح",
31 | "darkThemeLabel": "الوضع الداكن",
32 | "exitButtonLabel": "خروج",
33 | "exitWarningTitle": "خروج من التطبيق",
34 | "exitWarningMessage": "هل أنت متأكد من أنك تريد الخروج؟",
35 | "deleteButtonLabel": "حذف",
36 | "deleteStatusWarningTitle": "حذف الحالة",
37 | "deleteStatusWarningMessage": "هل تريد حذف هذه الحالة نهائياً؟",
38 | "deletedStatusMessage": "تم حذف الحالة"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_az.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "Salam Dünya!",
3 | "appTitle": "Status Saxlayıcı",
4 | "recentStatuses": "Sonuncular",
5 | "savedStatuses": "Saxlanılanlar",
6 | "statusSavedMessage": "Status saxlanıldı",
7 | "noSavedStatusesMessage": "Saxlanılan status yoxdur",
8 | "noWhatsappFoundMessage": "Mobilinizdə WhatsApp yoxdur",
9 | "appLanguageLabel": "Proqram Dil",
10 | "saveButtonLabel": "Saxla",
11 | "shareButtonLabel": "Paylaş",
12 | "okButtonLabel": "OK",
13 | "cancelButtonLabel": "İmtina et",
14 | "closeButtonLabel": "Bağla",
15 | "howDoesItWorkTitle": "Bu necə işləyir?",
16 | "howDoesItWorkDescription": "Biz WhatsApp Inc. ilə heç bir əlaqəsi olmayan və rəsmi şəkildə əlaqələndirilməmişik. Həmçinin, WhatsApp mesajlarınıza heç bir girişimiz yoxdur.\n\nBu tətbiq, cihazınızın saxlamağa qənaətli bir yolu təmin etmək, saxlanılan status şəkillərini və videolarını kəşf etmək və paylaşmaq üçün nəzərdə tutulmuşdur.",
17 | "aboutButtonLabel": "Proqram haqqında",
18 | "appThemeModeLabel":"Proqram Masa Üstü Üzərindəki Modu",
19 | "systemDefaultLabel": "Sistem Standartı",
20 | "couldNotSaveYourLanguagePreference": "Dil tercihinizi saxlaya bilmədik",
21 | "couldNotSaveYourThemePreference": "Tema tercihinizi saxlaya bilmədik",
22 | "giveStoragePermission": "Yaddaş icazəsi verin",
23 | "needToGiveStoragePermission": "Bu tətbiq üçün yaddaş icazəsinə ehtiyacınız var.",
24 | "couldNotOpenAppSettings": "Yaddaş icazəsi üçün tətbiq ayarlarını açmaq mümkün olmadı.",
25 | "allowStoragePermission": "Status Saxlayıcıya yaddaş icazəsi verin",
26 | "openWhatsAppLabel": "WhatsApp'ı aç",
27 | "openW4BLabel": "WhatsApp Business'ı aç",
28 | "doNotHaveSeenStatusesMessage": "Hələ heç bir status görməmisiniz, get və bir neçə status izləyin",
29 | "systemThemeLabel": "Sistem Teması",
30 | "lightThemeLabel": "Açıq Tema",
31 | "darkThemeLabel": "Tünd Tema",
32 | "exitButtonLabel": "ÇIXIŞ",
33 | "exitWarningTitle": "StatusSaver'dan Çıxmaq",
34 | "exitWarningMessage": "Çıxmağa əminsinizmi?",
35 | "deleteButtonLabel": "SİL",
36 | "deleteStatusWarningTitle": "Statusu Sil",
37 | "deleteStatusWarningMessage": "Bu statusu daimi olaraq silmək istəyirsiniz?",
38 | "deletedStatusMessage": "Status Silindi"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_bn.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "ওহে বিশ্ব!",
3 | "appTitle": "স্ট্যাটাস সেভার",
4 | "recentStatuses": "সাম্প্রতিক",
5 | "savedStatuses": "সেভ করা স্ট্যাটাস",
6 | "statusSavedMessage": "স্ট্যাটাস সেভ করা হয়েছে",
7 | "noSavedStatusesMessage": "কোন সেভ করা স্ট্যাটাস নেই",
8 | "noWhatsappFoundMessage": "আপনার মোবাইলে উইটসঅ্যাপ পাওয়া যায়নি",
9 | "appLanguageLabel": "অ্যাপ ভাষা",
10 | "saveButtonLabel": "সেভ করুন",
11 | "shareButtonLabel": "শেয়ার করুন",
12 | "okButtonLabel": "ঠিক আছে",
13 | "cancelButtonLabel": "বাতিল করুন",
14 | "closeButtonLabel": "বন্ধ করুন",
15 | "howDoesItWorkTitle": "এটি কিভাবে কাজ করে?",
16 | "howDoesItWorkDescription": "আমরা কোনও ভাবিত নথি নই বা কোনও প্রকারে ওয়াটসঅ্যাপ ইনক সংযুক্ত নই। আর আপনার ওয়াটসঅ্যাপ বার্তাগুলির কোনও অ্যাক্সেস নেই।\n\nএই অ্যাপ্লিকেশনটি আপনাকে আপনার ডিভাইসের স্টোরেজে সংরক্ষিত স্থিতির চিত্র এবং ভিডিও বেচে চলার ও শেয়ার করার একটি সুবিধায় প্রদান করার উদ্দেশ্যে তৈরি করা হয়েছে",
17 | "aboutButtonLabel": "অ্যাপ সম্পর্কে",
18 | "appThemeModeLabel": "অ্যাপ থিম মোড",
19 | "systemDefaultLabel": "সিস্টেম ডিফল্ট",
20 | "couldNotSaveYourLanguagePreference": "আপনার ভাষা পছন্দটি সংরক্ষণ করতে পারেনি",
21 | "couldNotSaveYourThemePreference": "আপনার থিম পছন্দটি সংরক্ষণ করতে পারেনি",
22 | "giveStoragePermission": "স্টোরেজ অনুমতি দিন",
23 | "needToGiveStoragePermission": "আপনাকে এই অ্যাপ্লিকেশনের জন্য স্টোরেজ অনুমতি দিতে হবে।",
24 | "couldNotOpenAppSettings": "স্টোরেজ অনুমতির জন্য অ্যাপ সেটিংস খুলতে পারা যায়নি।",
25 | "allowStoragePermission": "স্টোরেজ অনুমতি দিন স্ট্যাটাস সেভার এর জন্য",
26 | "openWhatsAppLabel": "ওয়াটসঅ্যাপ খুলুন",
27 | "openW4BLabel": "ওয়াটসঅ্যাপ ব্যবসা খুলুন",
28 | "doNotHaveSeenStatusesMessage": "আপনি এখনও কোনও স্থিতি দেখা করেননি, যান এবং কিছু স্থিতি দেখুন",
29 | "systemThemeLabel": "সিস্টেম থিম",
30 | "lightThemeLabel": "হালকা থিম",
31 | "darkThemeLabel": "ডার্ক থিম",
32 | "exitButtonLabel": "বাহির",
33 | "exitWarningTitle": "স্থিতি সংরক্ষণকারী থেকে বেরিয়ে যেতে চান",
34 | "exitWarningMessage": "আপনি কি নিশ্চিত যে আপনি বের হতে চান?",
35 | "deleteButtonLabel": "মুছে ফেলুন",
36 | "deleteStatusWarningTitle": "স্থিতি মুছুন",
37 | "deleteStatusWarningMessage": "আপনি কি এই স্থিতি স্থায়ীভাবে মুছে ফেলতে চান?",
38 | "deletedStatusMessage": "স্থিতি মুছে ফেলা হয়েছে"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_en.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "Hello World!",
3 | "appTitle": "Status Saver",
4 | "recentStatuses": "Recent",
5 | "savedStatuses": "Saved",
6 | "statusSavedMessage": "Status saved",
7 | "noSavedStatusesMessage": "No saved statuses",
8 | "noWhatsappFoundMessage": "Whatsapp does not exists on your mobile",
9 | "appLanguageLabel": "App Language",
10 | "saveButtonLabel": "Save",
11 | "shareButtonLabel": "Share",
12 | "okButtonLabel": "OK",
13 | "cancelButtonLabel": "CANCEL",
14 | "closeButtonLabel": "CLOSE",
15 | "howDoesItWorkTitle": "How does it work?",
16 | "howDoesItWorkDescription": "We are not affiliated or officially connected with WhatsApp Inc in any way. And, we do not have any access to your WhatsApp messages.\n\nThis application is intended to provide you with a more convenient way to explore, save and share the status images and videos cached in your device storage",
17 | "aboutButtonLabel": "About App",
18 | "appThemeModeLabel":"App Theme Mode",
19 | "systemDefaultLabel": "System Default",
20 | "couldNotSaveYourLanguagePreference": "Could not save your language preference",
21 | "couldNotSaveYourThemePreference": "Could not save your theme preference",
22 | "giveStoragePermission": "Give storage permission",
23 | "needToGiveStoragePermission": "You need to give storage permissions for this application.",
24 | "couldNotOpenAppSettings": "Could not open app settings for storage permission.",
25 | "allowStoragePermission": "Allow storage permission for Status Saver",
26 | "openWhatsAppLabel": "Open WhatsApp",
27 | "openW4BLabel": "Open WhatsApp Business",
28 | "doNotHaveSeenStatusesMessage": "You do not have seen any statuses yet, go and watch some statuses",
29 | "systemThemeLabel": "System Theme",
30 | "lightThemeLabel": "Light Theme",
31 | "darkThemeLabel": "Dark Theme",
32 | "exitButtonLabel": "EXIT",
33 | "exitWarningTitle": "Exit StatusSaver",
34 | "exitWarningMessage": "Are you sure you want to exit ?",
35 | "deleteButtonLabel": "DELETE",
36 | "deleteStatusWarningTitle": "Delete Status",
37 | "deleteStatusWarningMessage": "Do you want to permanently delete this status ?",
38 | "deletedStatusMessage": "Status Deleted"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_es.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "¡Hola Mundo!",
3 | "appTitle": "Ahorrador de Estados",
4 | "recentStatuses": "Recientes",
5 | "savedStatuses": "Guardados",
6 | "statusSavedMessage": "Estado guardado",
7 | "noSavedStatusesMessage": "No hay estados guardados",
8 | "noWhatsappFoundMessage": "WhatsApp no existe en tu móvil",
9 | "appLanguageLabel": "Idioma de la aplicación",
10 | "saveButtonLabel": "Guardar",
11 | "shareButtonLabel": "Compartir",
12 | "okButtonLabel": "Aceptar",
13 | "cancelButtonLabel": "Cancelar",
14 | "closeButtonLabel": "Cerrar",
15 | "howDoesItWorkTitle": "¿Cómo funciona?",
16 | "howDoesItWorkDescription": "No estamos afiliados ni conectados oficialmente de ninguna manera con WhatsApp Inc. Y no tenemos acceso a tus mensajes de WhatsApp.\n\nEsta aplicación está destinada a proporcionarte una forma más conveniente de explorar, guardar y compartir las imágenes y videos de estados almacenados en tu dispositivo.",
17 | "aboutButtonLabel": "Acerca de la aplicación",
18 | "appThemeModeLabel": "Modo de tema de la aplicación",
19 | "systemDefaultLabel": "Predeterminado del sistema",
20 | "couldNotSaveYourLanguagePreference": "No se pudo guardar tu preferencia de idioma",
21 | "couldNotSaveYourThemePreference": "No se pudo guardar tu preferencia de tema",
22 | "giveStoragePermission": "Dar permiso de almacenamiento",
23 | "needToGiveStoragePermission": "Necesitas otorgar permisos de almacenamiento para esta aplicación.",
24 | "couldNotOpenAppSettings": "No se pudo abrir la configuración de la aplicación para el permiso de almacenamiento.",
25 | "allowStoragePermission": "Permitir permiso de almacenamiento para Ahorrador de Estados",
26 | "openWhatsAppLabel": "Abrir WhatsApp",
27 | "openW4BLabel": "Abrir WhatsApp Business",
28 | "doNotHaveSeenStatusesMessage": "Aún no has visto ningún estado, ve y mira algunos estados",
29 | "systemThemeLabel": "Tema del sistema",
30 | "lightThemeLabel": "Tema claro",
31 | "darkThemeLabel": "Tema oscuro",
32 | "exitButtonLabel": "SALIR",
33 | "exitWarningTitle": "Salir de StatusSaver",
34 | "exitWarningMessage": "¿Estás seguro de que quieres salir?",
35 | "deleteButtonLabel": "ELIMINAR",
36 | "deleteStatusWarningTitle": "Eliminar Estado",
37 | "deleteStatusWarningMessage": "¿Deseas eliminar permanentemente este estado?",
38 | "deletedStatusMessage": "Estado Eliminado"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_gu.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "હેલો વર્લ્ડ!",
3 | "appTitle": "સ્ટેટસ સેવર",
4 | "recentStatuses": "તાજેતરની",
5 | "savedStatuses": "સંગ્રહિત",
6 | "statusSavedMessage": "સ્ટેટસ સંગ્રહિત થઇ ગઈ",
7 | "noSavedStatusesMessage": "કોઈ સંગ્રહિત સ્ટેટસઓ નથી",
8 | "noWhatsappFoundMessage": "તમારી મોબાઇલમાં વોટ્સએપ અસ્તિત્વમાં નથી",
9 | "appLanguageLabel": "ઍપ ભાષા",
10 | "saveButtonLabel": "સંગ્રહ કરો",
11 | "shareButtonLabel": "શેર કરો",
12 | "okButtonLabel": "ઠીક છે",
13 | "cancelButtonLabel": "રદ કરો",
14 | "closeButtonLabel": "બંધ કરો",
15 | "howDoesItWorkTitle": "તે કેમ કામ કરે છે?",
16 | "howDoesItWorkDescription": "અમે કોઈપણ રીતે વોટ્સએપ Inc સાથે સંબંધિત અથવા આધિકારિકપણે જોડાયેલ નથી. અને અમારી કોઈપણ વોટ્સએપ સંદેશો પર કોઈપણ ઍક્સેસ નથી.\n\nઆ એપ્લિકેશન તમને આપના ડિવાઇસ સ્ટોરેજમાં સંગ્રહિત સ્ટેટસ છબીઓ અને વિડિઓઝ ને અવગણવા, સંગ્રહિત કરવા અને શેર કરવાની વધારાની સાધની પૂરી કરવાની માટે છે.",
17 | "aboutButtonLabel": "ઍપ વિશે",
18 | "appThemeModeLabel":"ઍપ થીમ મોડ",
19 | "systemDefaultLabel": "સિસ્ટમ ડિફોલ્ટ",
20 | "couldNotSaveYourLanguagePreference": "તમારી ભાષાની પસંદગી સંગ્રહિત કરી શકી નથી",
21 | "couldNotSaveYourThemePreference": "તમારી થીમ પસંદગી સંગ્રહિત કરી શકી નથી",
22 | "giveStoragePermission": "સંગ્રહણ માટે પરવાનગી આપો",
23 | "needToGiveStoragePermission": "આ ઍપ્લિકેશન માટે તમને સંગ્રહણ પરવાનગી આપવી આવશ્યક છે.",
24 | "couldNotOpenAppSettings": "સંગ્રહણ પરવાનગી માટે ઍપ સેટિંગ્સ ખોલી શકાતી નથી.",
25 | "allowStoragePermission": "સ્ટેટસ સંગ્રહક માટે સંગ્રહણ પરવાનગી આપો",
26 | "openWhatsAppLabel": "વોટ્સએપ ખોલો",
27 | "openW4BLabel": "વોટ્સએપ બિઝનેસ ખોલો",
28 | "doNotHaveSeenStatusesMessage": "તમે હજી સુધી કોઈ સ્થિતિઓ જોવા નથી, થોડી સ્થિતિઓ જોવા જાઓ",
29 | "systemThemeLabel": "સિસ્ટમ થીમ",
30 | "lightThemeLabel": "લાઇટ થીમ",
31 | "darkThemeLabel": "ડાર્ક થીમ",
32 | "exitButtonLabel": "બહાર નીકળો",
33 | "exitWarningTitle": "સ્થિતિસંગ્રાહકને બંધ કરો",
34 | "exitWarningMessage": "શું તમે ખરેખર બહાર નીકળવા માંગો છો?",
35 | "deleteButtonLabel": "કાઢી નાખો",
36 | "deleteStatusWarningTitle": "સ્થિતિ કાઢી નાખો",
37 | "deleteStatusWarningMessage": "શું તમે આ સ્થિતિને કાયમરી રૂપે કાઢી નાખવા માંગો છો?",
38 | "deletedStatusMessage": "સ્થિતિ કાઢી નાખી દેવાયેલ"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_hi.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "नमस्ते दुनिया!",
3 | "appTitle": "स्टेटस सेवर",
4 | "recentStatuses": "हाल के स्टेटस",
5 | "savedStatuses": "सेव की गई स्टेटस",
6 | "statusSavedMessage": "स्टेटस सेव हो गई है",
7 | "noSavedStatusesMessage": "कोई सेव की गई स्टेटस नहीं",
8 | "noWhatsappFoundMessage": "आपके मोबाइल में व्हाट्सएप मौजूद नहीं है",
9 | "appLanguageLabel": "ऐप भाषा",
10 | "saveButtonLabel": "सेव करें",
11 | "shareButtonLabel": "शेयर करें",
12 | "okButtonLabel": "ठीक है",
13 | "cancelButtonLabel": "रद्द करें",
14 | "closeButtonLabel": "बंद करें",
15 | "howDoesItWorkTitle": "यह कैसे काम करता है?",
16 | "howDoesItWorkDescription": "हम व्हाट्सएप Inc से किसी भी तरीके से संबंधित या आधिकारिक रूप से जुड़े नहीं हैं। और, हमें आपके व्हाट्सएप संदेशों का कोई पहुंच नहीं है।\n\nयह एप्लिकेशन आपको उन स्टेटस छवियों और वीडियोज़ को खोजने, संग्रहीत करने और शेयर करने के लिए एक आसान तरीके से प्रदान करने के उद्देश्य से बनाई गई है, जो आपके डिवाइस स्टोरेज में कैश किए गए हैं।",
17 | "aboutButtonLabel": "ऐप के बारे में",
18 | "appThemeModeLabel":"ऐप थीम मोड",
19 | "systemDefaultLabel": "सिस्टम डिफ़ॉल्ट",
20 | "couldNotSaveYourLanguagePreference": "आपकी भाषा प्राथमिकता सहेजने में असमर्थ",
21 | "couldNotSaveYourThemePreference": "आपकी थीम प्राथमिकता सहेजने में असमर्थ",
22 | "giveStoragePermission": "संग्रहण अनुमति दें",
23 | "needToGiveStoragePermission": "आपको इस ऐप्लिकेशन के लिए संग्रहण अनुमतियों की आवश्यकता है।",
24 | "couldNotOpenAppSettings": "संग्रहण अनुमति के लिए ऐप सेटिंग्स नहीं खोल सका।",
25 | "allowStoragePermission": "स्टेटस सेवर के लिए संग्रहण अनुमति दें",
26 | "openWhatsAppLabel": "व्हाट्सएप खोलें",
27 | "openW4BLabel": "व्हाट्सएप बिजनेस खोलें",
28 | "doNotHaveSeenStatusesMessage": "आपने अबतक कोई स्थिति नहीं देखी है, कुछ स्थितियाँ देखें",
29 | "systemThemeLabel": "सिस्टम थीम",
30 | "lightThemeLabel": "लाइट थीम",
31 | "darkThemeLabel": "डार्क थीम",
32 | "exitButtonLabel": "बाहर निकलें",
33 | "exitWarningTitle": "स्थिति संग्रहक से बाहर निकलें",
34 | "exitWarningMessage": "क्या आप निश्चित रूप से बाहर निकलना चाहते हैं?",
35 | "deleteButtonLabel": "हटाएं",
36 | "deleteStatusWarningTitle": "स्थिति हटाएं",
37 | "deleteStatusWarningMessage": "क्या आप इस स्थिति को स्थायी रूप से हटाना चाहते हैं?",
38 | "deletedStatusMessage": "स्थिति हटा दी गई"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_ja.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "こんにちは、世界!",
3 | "appTitle": "ステータスセーバー",
4 | "recentStatuses": "最近のステータス",
5 | "savedStatuses": "保存されたステータス",
6 | "statusSavedMessage": "ステータスが保存されました",
7 | "noSavedStatusesMessage": "保存されたステータスはありません",
8 | "noWhatsappFoundMessage": "お使いのモバイルにWhatsAppが存在しません",
9 | "appLanguageLabel": "アプリの言語",
10 | "saveButtonLabel": "保存",
11 | "shareButtonLabel": "共有",
12 | "okButtonLabel": "OK",
13 | "cancelButtonLabel": "キャンセル",
14 | "closeButtonLabel": "閉じる",
15 | "howDoesItWorkTitle": "どのように機能しますか?",
16 | "howDoesItWorkDescription": "当アプリはWhatsApp Incとは関連付けられておらず、公式に接続されていません。また、WhatsAppのメッセージにアクセスする権限もありません。\n\nこのアプリは、デバイスストレージにキャッシュされたステータスの画像や動画を簡単に探索、保存、共有するための便利な方法を提供することを目的としています。",
17 | "aboutButtonLabel": "アプリについて",
18 | "appThemeModeLabel": "アプリのテーマモード",
19 | "systemDefaultLabel": "システムデフォルト",
20 | "couldNotSaveYourLanguagePreference": "言語設定を保存できませんでした",
21 | "couldNotSaveYourThemePreference": "テーマ設定を保存できませんでした",
22 | "giveStoragePermission": "ストレージの許可を与える",
23 | "needToGiveStoragePermission": "このアプリケーションにはストレージの許可が必要です。",
24 | "couldNotOpenAppSettings": "ストレージの許可のためのアプリの設定を開くことができませんでした。",
25 | "allowStoragePermission": "ステータスセーバーにストレージの許可を与える",
26 | "openWhatsAppLabel": "WhatsAppを開く",
27 | "openW4BLabel": "WhatsApp Businessを開く",
28 | "doNotHaveSeenStatusesMessage": "まだステータスを閲覧していません。いくつかのステータスを見てください",
29 | "systemThemeLabel": "システムテーマ",
30 | "lightThemeLabel": "ライトテーマ",
31 | "darkThemeLabel": "ダークテーマ",
32 | "exitButtonLabel": "終了",
33 | "exitWarningTitle": "StatusSaverを終了する",
34 | "exitWarningMessage": "本当に終了しますか?",
35 | "deleteButtonLabel": "削除",
36 | "deleteStatusWarningTitle": "ステータスの削除",
37 | "deleteStatusWarningMessage": "このステータスを永久に削除しますか?",
38 | "deletedStatusMessage": "ステータスが削除されました"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_kn.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "ಹಲೋ ವರ್ಲ್ಡ್!",
3 | "appTitle": "ಸ್ಥಿತಿ ಉಳಿಸುವಿಕೆಗಾಗಿ",
4 | "recentStatuses": "ಇತ್ತೀಚಿನ",
5 | "savedStatuses": "ಉಳಿಸಿದ ಸ್ಥಿತಿಗಳು",
6 | "statusSavedMessage": "ಸ್ಥಿತಿ ಉಳಿಸಲಾಗಿದೆ",
7 | "noSavedStatusesMessage": "ಯಾವುದೇ ಉಳಿಸಲಾಗಿದ್ದ ಸ್ಥಿತಿಗಳಿಲ್ಲ",
8 | "noWhatsappFoundMessage": "ನಿಮ್ಮ ಮೊಬೈಲ್ನಲ್ಲಿ WhatsApp ಕಂಡುಬರಲಿಲ್ಲ",
9 | "appLanguageLabel": "ಆ್ಯಪ್ ಭಾಷೆ",
10 | "saveButtonLabel": "ಉಳಿಸಿ",
11 | "shareButtonLabel": "ಹಂಚಿಕೆ ಮಾಡಿ",
12 | "okButtonLabel": "ಸರಿ",
13 | "cancelButtonLabel": "ರದ್ದುಮಾಡಿ",
14 | "closeButtonLabel": "ಮುಚ್ಚಿಕೊಳ್ಳುವುದು",
15 | "howDoesItWorkTitle": "ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ?",
16 | "howDoesItWorkDescription": "ನೀವು ನಿಮ್ಮ ಸಾಧನದ ನಂತರದ ಸ್ಥಿತಿ ಚಿತ್ರಗಳನ್ನು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಅನ್ವೇಷಿಸಲು, ಉಳಿಸಲು ಮತ್ತು ಹಂಚಿಕೆಯಾಗಲು ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮಗೆ ಇತರ ವ್ಯಾಪ್ತಿಗಳ ಜೊತೆಗೆ ಸಂಬಂಧಿಸಿದ ಸೌಲಭ್ಯವನ್ನು ನೀಡುತ್ತದೆ",
17 | "aboutButtonLabel": "ಆ್ಯಪ್ ಬಗ್ಗೆ",
18 | "appThemeModeLabel": "ಆ್ಯಪ್ ಥೀಮ್ ಮೋಡ್",
19 | "systemDefaultLabel": "ವ್ಯವಸ್ಥೆಯ ಪೂರ್ವನಿಯಮಿತ",
20 | "couldNotSaveYourLanguagePreference": "ನಿಮ್ಮ ಭಾಷಾ ಆದಾಯವನ್ನು ಉಳಿಸಲಾಗಲಿಲ್ಲ",
21 | "couldNotSaveYourThemePreference": "ನಿಮ್ಮ ಥೀಮ್ ಆದಾಯವನ್ನು ಉಳಿಸಲಾಗಲಿಲ್ಲ",
22 | "giveStoragePermission": "ಸಂಗ್ರಹ ಅನುಮತಿಯನ್ನು ನೀಡಿ",
23 | "needToGiveStoragePermission": "ಈ ಅಪ್ಲಿಕೇಶನ್ ಗೆ ನೀವು ಸಂಗ್ರಹ ಅನುಮತಿ ನೀಡಬೇಕಾಗಿದೆ.",
24 | "couldNotOpenAppSettings": "ಸಂಗ್ರಹ ಅನುಮತಿಗಾಗಿ ಆ್ಯಪ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರವಲೇರುವುದಿಲ್ಲ",
25 | "allowStoragePermission": "ಸಂಗ್ರಹ ಅನುಮತಿಯನ್ನು ನೀಡಿ Status Saver ಗೆ",
26 | "openWhatsAppLabel": "WhatsApp ತೆರವಿಗೆ",
27 | "openW4BLabel": "WhatsApp Business ತೆರವಿಗೆ",
28 | "doNotHaveSeenStatusesMessage": "ನೀವು ಯಾವುದೇ ಸ್ಥಿತಿಗಳನ್ನು ನೋಡಿಲ್ಲ, ಕೆಲವು ಸ್ಥಿತಿಗಳನ್ನು ನೋಡಲು ಹೋಗಿ",
29 | "systemThemeLabel": "ವ್ಯವಸ್ಥೆಯ ಥೀಮ್",
30 | "lightThemeLabel": "ಹೆಣ್ಣು ಥೀಮ್",
31 | "darkThemeLabel": "ಕತ್ತಲ ಥೀಮ್",
32 | "exitButtonLabel": "ನಿರ್ಗಮಿಸು",
33 | "exitWarningTitle": "ಸ್ಥಿತಿಸಂಗ್ರಹಕವನ್ನು ನಿರ್ಗಮಿಸಿ",
34 | "exitWarningMessage": "ನೀವು ನಿಶ್ಚಯವಾಗಿ ನಿರ್ಗಮಿಸಲು ಬಯಸುವಿರಾ?",
35 | "deleteButtonLabel": "ಅಳಿಸಿ",
36 | "deleteStatusWarningTitle": "ಸ್ಥಿತಿಯನ್ನು ಅಳಿಸಿ",
37 | "deleteStatusWarningMessage": "ನೀವು ಈ ಸ್ಥಿತಿಯನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸಬೇಕೆ?",
38 | "deletedStatusMessage": "ಸ್ಥಿತಿ ಅಳಿಸಲಾಗಿದೆ"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_ko.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "안녕, 세상아!",
3 | "appTitle": "상태 저장기",
4 | "recentStatuses": "최근",
5 | "savedStatuses": "저장됨",
6 | "statusSavedMessage": "상태 저장됨",
7 | "noSavedStatusesMessage": "저장된 상태가 없습니다",
8 | "noWhatsappFoundMessage": "당신의 모바일에 WhatsApp이 존재하지 않습니다",
9 | "appLanguageLabel": "앱 언어",
10 | "saveButtonLabel": "저장",
11 | "shareButtonLabel": "공유",
12 | "okButtonLabel": "확인",
13 | "cancelButtonLabel": "취소",
14 | "closeButtonLabel": "닫기",
15 | "howDoesItWorkTitle": "어떻게 작동하나요?",
16 | "howDoesItWorkDescription": "저희는 WhatsApp Inc와 어떠한 제휴 관계도 없으며 공식적으로 연결되어 있지 않습니다. 또한, WhatsApp 메시지에 대한 접근 권한이 없습니다.\n\n이 애플리케이션은 당신의 기기 저장 공간에 캐시된 상태 이미지와 동영상을 더 편리하게 찾아보고 저장하고 공유할 수 있는 방법을 제공하기 위해 만들어졌습니다.",
17 | "aboutButtonLabel": "앱 정보",
18 | "appThemeModeLabel": "앱 테마 모드",
19 | "systemDefaultLabel": "시스템 기본값",
20 | "couldNotSaveYourLanguagePreference": "언어 설정을 저장할 수 없습니다",
21 | "couldNotSaveYourThemePreference": "테마 설정을 저장할 수 없습니다",
22 | "giveStoragePermission": "저장소 권한 부여",
23 | "needToGiveStoragePermission": "이 애플리케이션에 대한 저장소 권한을 부여해야 합니다",
24 | "couldNotOpenAppSettings": "저장소 권한을 위한 앱 설정을 열 수 없습니다",
25 | "allowStoragePermission": "상태 저장기를 위해 저장소 권한 허용",
26 | "openWhatsAppLabel": "WhatsApp 열기",
27 | "openW4BLabel": "WhatsApp Business 열기",
28 | "doNotHaveSeenStatusesMessage": "아직 상태를 보지 않았습니다. 상태를 확인해보세요",
29 | "systemThemeLabel": "시스템 테마",
30 | "lightThemeLabel": "라이트 테마",
31 | "darkThemeLabel": "다크 테마",
32 | "exitButtonLabel": "종료",
33 | "exitWarningTitle": "StatusSaver 종료",
34 | "exitWarningMessage": "정말로 종료하시겠습니까?",
35 | "deleteButtonLabel": "삭제",
36 | "deleteStatusWarningTitle": "상태 삭제",
37 | "deleteStatusWarningMessage": "이 상태를 영구적으로 삭제하시겠습니까?",
38 | "deletedStatusMessage": "상태가 삭제되었습니다"
39 | }
40 |
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_mr.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "हॅलो वर्ल्ड!",
3 | "appTitle": "स्थिती सेव्हर",
4 | "recentStatuses": "नवीन",
5 | "savedStatuses": "सेव्ह केलेले स्थिती",
6 | "statusSavedMessage": "स्थिती सेव्ह केली",
7 | "noSavedStatusesMessage": "कोणतीही सेव्ह केलेली स्थिती नाहीत",
8 | "noWhatsappFoundMessage": "आपल्या मोबाइलवर व्हॉट्सऐप उपलब्ध नाही",
9 | "appLanguageLabel": "अॅप भाषा",
10 | "saveButtonLabel": "सेव्ह करा",
11 | "shareButtonLabel": "सामायिक करा",
12 | "okButtonLabel": "ठीक आहे",
13 | "cancelButtonLabel": "रद्द करा",
14 | "closeButtonLabel": "बंद करा",
15 | "howDoesItWorkTitle": "हे कसे कार्य करते?",
16 | "howDoesItWorkDescription": "आम्ही कोणत्याही प्रकारच्या व्हॉट्सऐप इंकचे अधिकारीक आणि संबद्ध नाही. आणि, आमच्याकडे आपल्या व्हॉट्सऐप संदेशांसाठी कोणतेही प्रवेश नाही.\n\nया अॅपलिकेशनमध्ये आपल्याला आपल्या डिव्हाइसवर संग्रहित केलेल्या स्थितीचे चित्र आणि व्हिडिओ अन्वेषण, सेव्ह आणि सामायिक करण्यासाठी एक सोपे मार्ग पुरविते",
17 | "aboutButtonLabel": "अॅपबद्दल",
18 | "appThemeModeLabel": "अॅप थीम मोड",
19 | "systemDefaultLabel": "सिस्टम डिफॉल्ट",
20 | "couldNotSaveYourLanguagePreference": "आपली भाषा प्राधान्य वाचवता येऊ शकली नाही",
21 | "couldNotSaveYourThemePreference": "आपली थीम प्राधान्य वाचवता येऊ शकली नाही",
22 | "giveStoragePermission": "संग्रह अनुमती द्या",
23 | "needToGiveStoragePermission": "या अॅपच्या साठी आपल्याला संग्रह अनुमती द्यावी लागेल.",
24 | "couldNotOpenAppSettings": "संग्रह अनुमतीसाठी अॅप सेटिंग्ज उघडू शकत नाहीत.",
25 | "allowStoragePermission": "स्थिती सेव्हरसाठी संग्रह अनुमती द्या",
26 | "openWhatsAppLabel": "व्हॉट्सऐप उघडा",
27 | "openW4BLabel": "व्हॉट्सऐप व्यवसाय उघडा",
28 | "doNotHaveSeenStatusesMessage": "आपण अद्याप पाहिलेल्या कोणत्याही स्थितींना नाहीत, जा आणि काही स्थिती पाहा",
29 | "systemThemeLabel": "सिस्टम थीम",
30 | "lightThemeLabel": "प्रकाश थीम",
31 | "darkThemeLabel": "डार्क थीम",
32 | "exitButtonLabel": "बंद करा",
33 | "exitWarningTitle": "बाहेर पडणे स्थितीसेव्हर",
34 | "exitWarningMessage": "तुम्ही खरंतर बाहेर पडायला आवडता आहात का?",
35 | "deleteButtonLabel": "काढून टाका",
36 | "deleteStatusWarningTitle": "स्थिती काढून टाका",
37 | "deleteStatusWarningMessage": "तुम्हाला हे स्थिती कायमच्या निर्मितीचे काढून टाकायला आवडते का?",
38 | "deletedStatusMessage": "स्थिती काढून टाकली आहे"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_pa.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "ਸਤ ਸ੍ਰੀ ਅਕਾਲ ਦੁਨਿਆ!",
3 | "appTitle": "ਸਥਿਤੀ ਸੇਵਰ",
4 | "recentStatuses": "ਤਾਜ਼ਾ",
5 | "savedStatuses": "ਸੰਭਾਲੇ ਹੋਏ ਸਥਿਤੀਆਂ",
6 | "statusSavedMessage": "ਸਥਿਤੀ ਸੰਭਾਲੀ ਗਈ",
7 | "noSavedStatusesMessage": "ਕੋਈ ਸੰਭਾਲੀ ਗਈ ਸਥਿਤੀਆਂ ਨਹੀਂ",
8 | "noWhatsappFoundMessage": "ਤੁਹਾਡੇ ਮੋਬਾਈਲ ਵਿੱਚ ਵਾਟਸਐਪ ਮੌਜੂਦ ਨਹੀਂ ਹੈ",
9 | "appLanguageLabel": "ਐਪ ਭਾਸ਼ਾ",
10 | "saveButtonLabel": "ਸੰਭਾਲੋ",
11 | "shareButtonLabel": "ਸਾਂਝਾ ਕਰੋ",
12 | "okButtonLabel": "ਠੀਕ ਹੈ",
13 | "cancelButtonLabel": "ਰੱਦ ਕਰੋ",
14 | "closeButtonLabel": "ਬੰਦ ਕਰੋ",
15 | "howDoesItWorkTitle": "ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ?",
16 | "howDoesItWorkDescription": "ਅਸੀਂ ਕਿਸੇ ਵੀ ਢੰਗ ਨਾਲ ਵਾਟਸਐਪ ਇੰਕ ਨਾਲ ਜੁੜੇ ਨਹੀਂ ਹਾਂ. ਅਤੇ ਸਾਨੂੰ ਤੁਹਾਡੇ ਵਾਟਸਐਪ ਸੁਨੇਹਾਂ ਤੱਕ ਕੋਈ ਪਹੁੰਚ ਨਹੀਂ ਹੈ।\n\nਇਹ ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਸਟੋਰੇਜ਼ ਵਿੱਚ ਕੈਸ਼ ਕੀਤੀ ਗਈ ਸਥਿਤੀ ਚਿੱਤਰ ਅਤੇ ਵੀਡੀਓ ਦੇ ਖੋਜ, ਸੰਭਾਲ ਅਤੇ ਸਾਂਝਾ ਕਰਨ ਲਈ ਤੁਹਾਨੂੰ ਇਕ ਵਧੀਆ ਤਰੀਕਾ ਪ੍ਰਦਾਨ ਕਰਨ ਦਾ ਉਦੇਸ਼ ਰੱਖਦਾ ਹੈ।",
17 | "aboutButtonLabel": "ਐਪ ਬਾਰੇ",
18 | "appThemeModeLabel":"ਐਪ ਥੀਮ ਮੋਡ",
19 | "systemDefaultLabel": "ਸਿਸਟਮ ਡਿਫਾਲਟ",
20 | "couldNotSaveYourLanguagePreference": "ਤੁਹਾਡੀ ਭਾਸ਼ਾ ਪਸੰਦ ਸੰਭਾਲਣ ਵਿੱਚ ਅਸਮਰੱਥ ਰਹੀ",
21 | "couldNotSaveYourThemePreference": "ਤੁਹਾਡੀ ਥੀਮ ਪਸੰਦ ਸੰਭਾਲਣ ਵਿੱਚ ਅਸਮਰੱਥ ਰਹੀ",
22 | "giveStoragePermission": "ਸਟੋਰੇਜ਼ ਅਨੁਮਤੀ ਦਿਓ",
23 | "needToGiveStoragePermission": "ਇਸ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਤੁਹਾਨੂੰ ਸਟੋਰੇਜ਼ ਅਨੁਮਤੀ ਦੇਣੀ ਲੋੜ ਹੈ।",
24 | "couldNotOpenAppSettings": "ਸਟੋਰੇਜ਼ ਅਨੁਮਤੀ ਲਈ ਐਪ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲਣਾ ਸਮੰਭਵ ਨਹੀਂ ਹੋਇਆ।",
25 | "allowStoragePermission": "ਸਥਿਤੀ ਸੇਵਰ ਲਈ ਸਟੋਰੇਜ਼ ਅਨੁਮਤੀ ਦਿਓ",
26 | "openWhatsAppLabel": "ਵਾਟਸਐਪ ਖੋਲੋ",
27 | "openW4BLabel": "ਵਾਟਸਐਪ ਵਾਪਾਰ ਖੋਲੋ",
28 | "doNotHaveSeenStatusesMessage": "ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਥਿਤੀਆਂ ਦੇਖੀਆਂ ਨਹੀਂ ਗਈਆਂ ਹਨ, ਜਾਓ ਅਤੇ ਕੁਝ ਸਥਿਤੀਆਂ ਵੇਖੋ",
29 | "systemThemeLabel": "ਸਿਸਟਮ ਥੀਮ",
30 | "lightThemeLabel": "ਹਲਕੀ ਥੀਮ",
31 | "darkThemeLabel": "ਅੰਧਕਾਰ ਥੀਮ",
32 | "exitButtonLabel": "ਬਾਹਰ ਜਾਓ",
33 | "exitWarningTitle": "ਸਥਿਤੀ ਸੇਵਰ ਤੋਂ ਬਾਹਰ ਜਾਓ",
34 | "exitWarningMessage": "ਕੀ ਤੁਸੀਂ ਪੁਸ਼ਟੀ ਕਰਦੇ ਹੋ ਕਿ ਤੁਸੀਂ ਬਾਹਰ ਜਾਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
35 | "deleteButtonLabel": "ਹਟਾਓ",
36 | "deleteStatusWarningTitle": "ਸਥਿਤੀ ਹਟਾਓ",
37 | "deleteStatusWarningMessage": "ਕੀ ਤੁਸੀਂ ਇਹ ਸਥਿਤੀ ਪੱਕੇ ਤੌਰ 'ਤੇ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
38 | "deletedStatusMessage": "ਸਥਿਤੀ ਹਟਾਈ ਗਈ ਹੈ"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_ta.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "ஹலோ உலகம்!",
3 | "appTitle": "ஸ்டேட்டஸ் சேவர்",
4 | "recentStatuses": "சமீபத்தியமான",
5 | "savedStatuses": "சேமித்த ஸ்டேட்டஸ்கள்",
6 | "statusSavedMessage": "ஸ்டேட்டஸ் சேமிக்கப்பட்டது",
7 | "noSavedStatusesMessage": "சேமித்த ஸ்டேட்டஸ்கள் இல்லை",
8 | "noWhatsappFoundMessage": "உங்கள் மொபைலில் WhatsApp இல்லை",
9 | "appLanguageLabel": "பயன்பாட்டின் மொழி",
10 | "saveButtonLabel": "சேமி",
11 | "shareButtonLabel": "பகிர்",
12 | "okButtonLabel": "சரி",
13 | "cancelButtonLabel": "ரத்துசெய்",
14 | "closeButtonLabel": "மூடு",
15 | "howDoesItWorkTitle": "இது எப்படி வேலை செய்கிறது?",
16 | "howDoesItWorkDescription": "மாற்றம் முடிவடைந்த நிலைப்பாடுகளைக் காண, சேமி மற்றும் பகிர்ந்துகொள்ள உங்கள் சாதாரண நிலை மொபைலின் சேமிப்புக்களில் இருக்கும் படங்களும் காட்சிகளை பாதுகாக்கும்படி இந்த பயன்பாட்டை வழங்க எங்கள் எந்தக் கைமுறையும் கையாளப்படவில்லை என்பது என்னவெனில். மேலும், உங்கள் WhatsApp செயல்பாட்டுகளுக்கு எங்கள் எந்தக் கையாளும் இல்லை.\n\nஇந்த பயன்பாட்டின் மூலம், நீங்கள் மொபைலின் சேமிப்புகளில் பதிவு செய்த ஸ்டேட்டஸ் படங்கள் மற்றும் காட்சிகளை வேர்வையிட மேலும் செமானான வழியை வழங்க மேலும் செமானான வழியை வழங்க முயற்சிக்கின்றது",
17 | "aboutButtonLabel": "பயன்பாட்டு பற்றி",
18 | "appThemeModeLabel": "பயன்பாட்டின் தீம் முறை",
19 | "systemDefaultLabel": "முக்கிய அமைப்பு",
20 | "couldNotSaveYourLanguagePreference": "உங்கள் மொழி விருப்பத்தை சேமிக்க முடியவில்லை",
21 | "couldNotSaveYourThemePreference": "உங்கள் தீம் விருப்பத்தை சேமிக்க முடியவில்லை",
22 | "giveStoragePermission": "சேமிப்பு அனுமதியைப் பயன்படுத்துக",
23 | "needToGiveStoragePermission": "இந்த பயன்பாட்டுக்கு நீங்கள் சேமிப்பு அனுமதியை அளிக்க வேண்டும்.",
24 | "couldNotOpenAppSettings": "சேமிப்பு அனுமதி மறுக்க பயன்பாட்டு அமை ப்புகளை திறக்க முடியவில்லை.",
25 | "allowStoragePermission": "ஸ்டேட்டஸ் சேவர் சேமிப்பு அனுமதியை அனுமதிக்க",
26 | "openWhatsAppLabel": "WhatsApp ஐ திறக்கவும்",
27 | "openW4BLabel": "வாட்ஸ்அப் பிரின்ஸை திறக்கவும்",
28 | "doNotHaveSeenStatusesMessage": "நீங்கள் எந்த ஸ்டேட்டஸ்களையும் பார்க்கவில்லை, சில ஸ்டேட்டஸ்களை பார்க்கவும்",
29 | "systemThemeLabel": "முக்கிய தீம்",
30 | "lightThemeLabel": "ஒளியான தீம்",
31 | "darkThemeLabel": "இருண்ட தீம்",
32 | "exitButtonLabel": "வெளியேறு",
33 | "exitWarningTitle": "நிறுவுவதை வெளியேறு",
34 | "exitWarningMessage": "நீங்கள் உறுதியாக வெளியேற விரும்புகிறீர்களா?",
35 | "deleteButtonLabel": "நீக்கு",
36 | "deleteStatusWarningTitle": "நிலையை நீக்கு",
37 | "deleteStatusWarningMessage": "இந்த நிலையை நிரந்தரமாக நீக்க விரும்புகிறீர்களா?",
38 | "deletedStatusMessage": "நிலை நீக்கப்பட்டது"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_te.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "హలో ప్రపంచం!",
3 | "appTitle": "స్థితి సేవరకు",
4 | "recentStatuses": "ఇటీవలి",
5 | "savedStatuses": "సేవ్ చేసిన స్థితులు",
6 | "statusSavedMessage": "స్థితి సేవ్ చేయబడింది",
7 | "noSavedStatusesMessage": "సేవ్ చేయబడని స్థితులు లేవు",
8 | "noWhatsappFoundMessage": "మీ మొబైల్లో WhatsApp లేదు",
9 | "appLanguageLabel": "యాప్ భాష",
10 | "saveButtonLabel": "సేవ్ చేయండి",
11 | "shareButtonLabel": "షేర్ చేయండి",
12 | "okButtonLabel": "సరే",
13 | "cancelButtonLabel": "రద్దు చేయండి",
14 | "closeButtonLabel": "మూసివేయి",
15 | "howDoesItWorkTitle": "ఇది ఎలా పని చేస్తుంది?",
16 | "howDoesItWorkDescription": "మీ పరికరంలో ఉన్న క్యాష్ చేసిన స్థితి చిత్రాలు మరియు వీడియోలను అన్వేషించడం, సేవ్ చేయడం మరియు షేర్ చేయడం కోసం మీకు ఇతర యాప్నుతో సంబంధించినందున ఏంపికలను అందిస్తుంది",
17 | "aboutButtonLabel": "యాప్ గురించి",
18 | "appThemeModeLabel": "యాప్ థీమ్ మోడ్",
19 | "systemDefaultLabel": "సిస్టమ్ డిఫాల్ట్",
20 | "couldNotSaveYourLanguagePreference": "మీ భాష ప్రాధాన్యతను సేవ్ చేయలేరు",
21 | "couldNotSaveYourThemePreference": "మీ థీమ్ ప్రాధాన్యతను సేవ్ చేయలేరు",
22 | "giveStoragePermission": "స్థిరానికి అనుమతించండి",
23 | "needToGiveStoragePermission": "ఈ అప్లికేషన్ కోసం మీకు స్థిరాన్ని అనుమతించాలి.",
24 | "couldNotOpenAppSettings": "స్థిరా అనుమతి కోసం అప్లికేషన్ సెట్టింగ్లను తెరవలేరు.",
25 | "allowStoragePermission": "స్థిరా అనుమతించండి స్థితి సేవకు",
26 | "openWhatsAppLabel": "WhatsApp తెరవండి",
27 | "openW4BLabel": "WhatsApp వ్యాపారాన్ని తెరవండి",
28 | "doNotHaveSeenStatusesMessage": "మీరు ఏమి స్థితులను చూడలేదు, కొనసాగిపోవడానికి స్థితులను చూడండి",
29 | "systemThemeLabel": "సిస్టమ్ థీమ్",
30 | "lightThemeLabel": "లైట్ థీమ్",
31 | "darkThemeLabel": "డార్క్ థీమ్",
32 | "exitButtonLabel": "నిష్క్రమించు",
33 | "exitWarningTitle": "పరిస్థితి సేవకి నిష్క్రమించండి",
34 | "exitWarningMessage": "నిజంగా నిష్క్రమించాలని మీరు ఖచ్చితంగా ఉంచారా?",
35 | "deleteButtonLabel": "తొలగించు",
36 | "deleteStatusWarningTitle": "స్థితిని తొలగించండి",
37 | "deleteStatusWarningMessage": "మీరు ఈ స్థితిని శాశ్వతంగా తొలగించాలని మీరు కోరుకుంటున్నారా?",
38 | "deletedStatusMessage": "స్థితి తొలగబడింది"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/app_ur.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "ہیلو ورلڈ!",
3 | "appTitle": "سٹیٹس سیو کرنے والا",
4 | "recentStatuses": "حالیہ",
5 | "savedStatuses": "محفوظ شدہ",
6 | "statusSavedMessage": "حالت محفوظ کر دی گئی",
7 | "noSavedStatusesMessage": "کوئی محفوظ شدہ حالتیں نہیں",
8 | "noWhatsappFoundMessage": "آپ کے موبائل پر واٹس ایپ موجود نہیں ہے",
9 | "appLanguageLabel": "اپلیکیشن کی زبان",
10 | "saveButtonLabel": "محفوظ کریں",
11 | "shareButtonLabel": "شئیر کریں",
12 | "okButtonLabel": "ٹھیک ہے",
13 | "cancelButtonLabel": "منسوخ کریں",
14 | "closeButtonLabel": "بند کریں",
15 | "howDoesItWorkTitle": "یہ کام کیسے کرتا ہے؟",
16 | "howDoesItWorkDescription": "ہم WhatsApp انک سے کسی بھی طرح تعلق نہیں رکھتے ہیں۔ اور ہمیں آپ کے واٹس ایپ پیغاموں تک رسائی کا کوئی راستہ نہیں ہے۔\n\nیہ ایپلیکیشن آپ کو آپ کی ڈیوائس میں ذخیرہ ہونے والی حالتوں کی تصاویر اور ویڈیوز کو کھولنے، محفوظ کرنے اور شئیر کرنے کا آسان ترین طریقہ فراہم کرنے کے لئے تشکیل دی گئی ہے",
17 | "aboutButtonLabel": "اے پی پر معلومات",
18 | "appThemeModeLabel": "اے پی کا تھیم موڈ",
19 | "systemDefaultLabel": "سسٹم ڈیفالٹ",
20 | "couldNotSaveYourLanguagePreference": "آپ کی زبان کی ترجیح محفوظ نہیں کی جا سکی",
21 | "couldNotSaveYourThemePreference": "آپ کی تھیم کی ترجیح محفوظ نہیں کی جا سکی",
22 | "giveStoragePermission": "ذخیرہ کی اجازت دیں",
23 | "needToGiveStoragePermission": "اس ایپلیکیشن کے لئے آپ کو ذخیرہ کی اجازت دینے کی ضرورت ہے۔",
24 | "couldNotOpenAppSettings": "ذخیرہ کی اجازت کے لئے ایپ کی ترتیبات کھولنے میں ناکامی",
25 | "allowStoragePermission": "سٹیٹس سیو کرنے والے کو ذخیرہ کی اجازت دیں",
26 | "openWhatsAppLabel": "واٹس ایپ کھولیں",
27 | "openW4BLabel": "واٹس ایپ بزنس کھولیں",
28 | "doNotHaveSeenStatusesMessage": "آپ نے ابھی تک کوئی حالت دیکھی نہیں ہے، جائیں اور کچھ حالتوں کو دیکھیں",
29 | "systemThemeLabel": "سسٹم تھیم",
30 | "lightThemeLabel": "روشنی کا تھیم",
31 | "darkThemeLabel": "تاریک تھیم",
32 | "exitButtonLabel": "بند کریں",
33 | "exitWarningTitle": "اسٹیٹس سیو کرنے والے سے باہر نکلیں",
34 | "exitWarningMessage": "کیا آپ واقعی بند کرنا چاہتے ہیں؟",
35 | "deleteButtonLabel": "حذف کریں",
36 | "deleteStatusWarningTitle": "حالت کو حذف کریں",
37 | "deleteStatusWarningMessage": "کیا آپ اس حالت کو مستقل طور پر حذف کرنا چاہتے ہیں؟",
38 | "deletedStatusMessage": "حالت حذف کردی گئی ہے"
39 | }
--------------------------------------------------------------------------------
/lib/src/localization/l10n/l10n.dart:
--------------------------------------------------------------------------------
1 |
2 | import "package:flutter/material.dart";
3 | import "package:status_saver/src/localization/enums/language_code.dart";
4 | import "package:status_saver/src/localization/extensions/on_build_context.dart";
5 |
6 | class L10n {
7 | static final allSupportedLocales = LanguageCode.values
8 | .map((languageCode) => Locale(languageCode.name))
9 | .toList();
10 |
11 | static String? getLanguageName(
12 | LanguageCode languageCode, BuildContext context) {
13 | switch (languageCode) {
14 | case LanguageCode.system:
15 | return context.l10n.systemDefaultLabel;
16 | case LanguageCode.en:
17 | return "English";
18 | case LanguageCode.hi:
19 | return "हिंदी";
20 | case LanguageCode.gu:
21 | return "ગુજરાતી";
22 | case LanguageCode.ko:
23 | return "한국어";
24 | case LanguageCode.mr:
25 | return "मराठी";
26 | case LanguageCode.pa:
27 | return "ਪੰਜਾਬੀ";
28 | case LanguageCode.ta:
29 | return "தமிழ்";
30 | case LanguageCode.te:
31 | return "తెలుగు";
32 | case LanguageCode.ja:
33 | return "日本語 (にほんご";
34 | case LanguageCode.af:
35 | return "Afrikaans";
36 | case LanguageCode.az:
37 | return "Azərbaycan dili";
38 | case LanguageCode.bn:
39 | return "বাংলা";
40 | case LanguageCode.kn:
41 | return "ಕನ್ನಡ";
42 | case LanguageCode.ur:
43 | return "اردو";
44 | case LanguageCode.es:
45 | return "Español";
46 | case LanguageCode.ar:
47 | return "العربية";
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/lib/src/localization/notifiers/locale_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:shared_preferences/shared_preferences.dart';
4 | import 'package:status_saver/src/localization/enums/language_code.dart';
5 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
6 | import 'package:status_saver/src/localization/extensions/on_string.dart';
7 | import 'package:status_saver/src/common/helpers/show_toast.dart';
8 |
9 | const languageCodeKey = "languageCode";
10 | const defaultLanguageCode = "en";
11 | const systemLanguageCode = LanguageCode.system;
12 |
13 | // TODO: visit
14 | // https://github.com/bizz84/localization_riverpod_flutter/blob/main/lib/src/localization/app_localizations_provider.dart
15 | class LocaleNotifier extends StateNotifier {
16 | LocaleNotifier() : super(null);
17 |
18 | void initialize() async {
19 | final sharedPreferences = await SharedPreferences.getInstance();
20 | final String? languageCode = sharedPreferences.getString(languageCodeKey);
21 | if (languageCode != null &&
22 | languageCode.toLanguageCode() != systemLanguageCode) {
23 | state = Locale(languageCode);
24 | }
25 | }
26 |
27 | Locale? get locale => state;
28 |
29 | void setLocale(LanguageCode languageCode, BuildContext context) {
30 | if (!LanguageCode.values.contains(languageCode)) return;
31 |
32 | state =
33 | languageCode == systemLanguageCode ? null : Locale(languageCode.name);
34 | SharedPreferences.getInstance().then((sharedPreferences) {
35 | sharedPreferences
36 | .setString(languageCodeKey, languageCode.name)
37 | .then((value) {
38 | if (!value) {
39 | showToast(message: context.l10n.couldNotSaveYourLanguagePreference);
40 | }
41 | });
42 | });
43 | }
44 | }
45 |
46 | final localeProvider = StateNotifierProvider(
47 | (ref) => LocaleNotifier()..initialize());
48 |
--------------------------------------------------------------------------------
/lib/src/statuses/notifiers/statuses_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 |
4 | import 'package:flutter/foundation.dart';
5 | import 'package:flutter_riverpod/flutter_riverpod.dart';
6 | import 'package:permission_handler/permission_handler.dart';
7 | import 'package:saf/saf.dart';
8 | import 'package:status_saver/src/common/helpers/statuses_helper.dart';
9 | import 'package:status_saver/src/common/helpers/storage_helper.dart';
10 | import 'package:status_saver/src/debug/console_log.dart';
11 | import 'package:status_saver/src/home/models/tab_type.dart';
12 | import 'package:status_saver/src/home/services/android_info_notifier.dart';
13 | import 'package:status_saver/src/storage_permission/notifiers/storage_permission_notifier.dart';
14 |
15 | class StatusesNotifier
16 | extends FamilyAsyncNotifier, StatusTabType> {
17 | @override
18 | FutureOr> build(StatusTabType arg) async {
19 | state = const AsyncValue.loading();
20 | return await getStatuses();
21 | }
22 |
23 | Future> getStatuses() async {
24 | if (arg == StatusTabType.recent) {
25 | final androidInfo = await ref.watch(androidInfoProvider.future);
26 | List statusesDirAllFiles;
27 | final recentStatusesNotifier =
28 | ref.read(recentStoragePermissionProvider.notifier);
29 | if (androidInfo.isAndroid11OrLater) {
30 | statusesDirAllFiles =
31 | await getStatusesDirFilesFromSaf(recentStatusesNotifier.saf()!);
32 | } else {
33 | statusesDirAllFiles = getDirectoryFilePaths(
34 | recentStatusesNotifier.statusesPath()!,
35 | whereCallback: isItStatusFile,
36 | );
37 | }
38 | return statusesDirAllFiles.where(isItStatusFile).toList();
39 | } else if (arg == StatusTabType.saved) {
40 | final savedStatusesNotifier =
41 | ref.read(savedStoragePermissionProvider.notifier);
42 | return getDirectoryFilePaths(
43 | savedStatusesNotifier.statusesPath()!,
44 | whereCallback: isItStatusFile,
45 | );
46 | } else {
47 | return List.empty();
48 | }
49 | }
50 |
51 | Future> getStatusesDirFilesFromSaf(Saf saf) async {
52 | try {
53 | await saf.sync();
54 | List statuses =
55 | await saf.getCachedFilesPath() ?? List.empty();
56 | return statuses;
57 | } catch (e) {
58 | await saf.releasePersistedPermission();
59 | ref.read(recentStoragePermissionProvider.notifier).releasePermissions();
60 | return List.empty();
61 | }
62 | }
63 |
64 | Future saveStatus(String statusPath) async {
65 | try {
66 | state = const AsyncLoading();
67 | final String savedStatusPath = getSavedStatusPath(statusPath);
68 | await File(savedStatusPath).create(recursive: true);
69 | await File(statusPath).copy(savedStatusPath);
70 | state = AsyncValue.data(await getStatuses());
71 | return true;
72 | } catch (_) {
73 | return false;
74 | }
75 | }
76 |
77 | Future deleteStatus(String statusPath) async {
78 | final previousState = state;
79 | try {
80 | final File status = File(statusPath);
81 | state = const AsyncLoading();
82 |
83 | bool statusFileExists = await status.exists();
84 | if (!statusFileExists) {
85 | consoleLog("File does not exist at path: $statusPath");
86 | return true;
87 | }
88 |
89 | debugPrint("file exists: $statusFileExists");
90 | debugPrint(" file exists on '$statusPath'");
91 | debugPrint("stat: ${await status.stat()}");
92 | if (await Permission.storage.request().isGranted) {
93 | await status.delete(recursive: true);
94 | }
95 | consoleLog("Deleted file at path: $statusPath");
96 |
97 | state = AsyncValue.data(await getStatuses());
98 | return true;
99 | } catch (e) {
100 | consoleLog(e, "Error deleting file at path: $statusPath");
101 | state = previousState;
102 | return false;
103 | }
104 | }
105 | }
106 |
107 | final statusesProvider =
108 | AsyncNotifierProvider.family, StatusTabType>(
109 | () => StatusesNotifier());
110 |
111 | final recentStatusesProvider = statusesProvider(StatusTabType.recent);
112 | final savedStatusesProvider = statusesProvider(StatusTabType.saved);
113 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/image_tile.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:status_saver/src/statuses/views/image_view.dart';
5 |
6 | class ImageTile extends StatelessWidget {
7 | const ImageTile({
8 | super.key,
9 | required this.imagePath,
10 | });
11 |
12 | final String imagePath;
13 | @override
14 | Widget build(BuildContext context) {
15 | File imageFile = File(imagePath);
16 | return Card(
17 | elevation: 5,
18 | clipBehavior: Clip.hardEdge,
19 | child: InkWell(
20 | onTap: () {
21 | Navigator.of(context).push(
22 | MaterialPageRoute(
23 | builder: (context) {
24 | // return Text(imagePath);
25 | return ImageView(
26 | imagePath: imagePath,
27 | );
28 | },
29 | ),
30 | );
31 | },
32 | child: Hero(
33 | tag: imagePath,
34 | child: Image.file(
35 | imageFile,
36 | fit: BoxFit.cover,
37 | ),
38 | ),
39 | ),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/image_view.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:photo_view/photo_view.dart';
5 | import 'package:status_saver/src/common/helpers/statuses_helper.dart';
6 | import 'package:status_saver/src/statuses/views/status_actions.dart';
7 |
8 | class ImageView extends StatelessWidget {
9 | final String imagePath;
10 | const ImageView({super.key, required this.imagePath});
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Scaffold(
15 | appBar: AppBar(
16 | backgroundColor: Colors.black,
17 | actions: [
18 | if (isItSavedStatus(imagePath))
19 | DeleteSavedStatusAction(
20 | statusPath: imagePath,
21 | )
22 | ],
23 | ),
24 | body: Stack(
25 | clipBehavior: Clip.none,
26 | children: [
27 | Hero(
28 | tag: imagePath,
29 | child: PhotoView(
30 | minScale: PhotoViewComputedScale.contained * 0.6,
31 | maxScale: PhotoViewComputedScale.contained * 2.5,
32 | imageProvider: FileImage(File(imagePath)),
33 | ),
34 | ),
35 | Positioned(
36 | bottom: 20,
37 | right: 10,
38 | height: MediaQuery.of(context).size.height * 0.2,
39 | child: StatusActions(
40 | statusPath: imagePath,
41 | ),
42 | ),
43 | ],
44 | ),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/status_actions.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:share_plus/share_plus.dart';
4 | import 'package:status_saver/src/common/helpers/show_toast.dart';
5 | import 'package:status_saver/src/common/helpers/statuses_helper.dart';
6 | import 'package:status_saver/src/debug/console_log.dart';
7 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
8 | import 'package:status_saver/src/statuses/notifiers/statuses_notifier.dart';
9 |
10 | class StatusActions extends ConsumerWidget {
11 | final String statusPath;
12 | final Future Function()? pauseVideoStatus;
13 | const StatusActions({
14 | super.key,
15 | required this.statusPath,
16 | this.pauseVideoStatus,
17 | });
18 |
19 | @override
20 | Widget build(BuildContext context, WidgetRef ref) {
21 | List actions = [];
22 |
23 | // Insert Save status action
24 | final String saveStatusPath = getSavedStatusPath(statusPath);
25 | if (saveStatusPath.compareTo(statusPath) != 0) {
26 | actions.add(FloatingActionButton.extended(
27 | heroTag: null,
28 | onPressed: () async {
29 | ref.read(savedStatusesProvider.notifier).saveStatus(statusPath);
30 | showToast(getMessage: () => context.l10n.statusSavedMessage);
31 | },
32 | icon: const Icon(Icons.file_download_rounded),
33 | label: Text(context.l10n.saveButtonLabel),
34 | ));
35 | }
36 |
37 | actions.addAll([
38 | // Insert Share status action
39 | FloatingActionButton.extended(
40 | heroTag: null,
41 | onPressed: () async {
42 | if (statusPath.endsWith(".mp4") && pauseVideoStatus != null) {
43 | await pauseVideoStatus!();
44 | }
45 | final res = await Share.shareXFiles(
46 | [XFile(statusPath)],
47 | subject: 'Whatsapp Status',
48 | );
49 | consoleLog(res, "result");
50 | },
51 | icon: const Icon(Icons.share_rounded),
52 | label: Text(context.l10n.shareButtonLabel),
53 | )
54 | ]);
55 |
56 | return Column(
57 | mainAxisAlignment: MainAxisAlignment.spaceAround,
58 | children: actions,
59 | );
60 | }
61 | }
62 |
63 | class DeleteSavedStatusAction extends ConsumerWidget {
64 | const DeleteSavedStatusAction(
65 | {super.key, required this.statusPath, this.onPressed});
66 | final String statusPath;
67 | final void Function(Future Function() deleteStatus)? onPressed;
68 |
69 | @override
70 | Widget build(BuildContext context, WidgetRef ref) {
71 | return IconButton(
72 | onPressed: onPressed != null
73 | ? () => onPressed!(() => deleteStatus(context, ref))
74 | : () => deleteStatus(context, ref),
75 | icon: const Icon(
76 | Icons.delete_forever,
77 | color: Colors.white,
78 | ),
79 | );
80 | }
81 |
82 | Future deleteStatus(BuildContext context, WidgetRef ref) =>
83 | showDialog(
84 | context: context,
85 | barrierDismissible: false,
86 | builder: (context) => AlertDialog(
87 | title: Text(context.l10n.deleteStatusWarningTitle),
88 | content: Text(
89 | context.l10n.deleteStatusWarningMessage,
90 | style: const TextStyle(fontSize: 18),
91 | ),
92 | actions: [
93 | TextButton(
94 | onPressed: () => Navigator.pop(context),
95 | child: Text(context.l10n.cancelButtonLabel),
96 | ),
97 | TextButton(
98 | onPressed: () {
99 | ref
100 | .read(savedStatusesProvider.notifier)
101 | .deleteStatus(statusPath)
102 | .then((isDeleted) {
103 | Navigator.pop(context);
104 | if (isDeleted) {
105 | Navigator.pop(context);
106 | showToast(
107 | message: context.l10n.deletedStatusMessage,
108 | );
109 | } else {
110 | showToast(
111 | message: "was not able to delete",
112 | );
113 | }
114 | });
115 | },
116 | child: Text(context.l10n.deleteButtonLabel),
117 | ),
118 | ],
119 | ),
120 | );
121 | }
122 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/statuses_grid_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
3 | import 'package:status_saver/src/statuses/views/image_tile.dart';
4 | import 'package:status_saver/src/statuses/views/video_tile.dart';
5 |
6 | class StatusesGridWidget extends StatelessWidget {
7 | const StatusesGridWidget({
8 | super.key,
9 | required this.scrollController,
10 | required this.statuses,
11 | required this.noStatusesFoundMessage,
12 | });
13 | final List statuses;
14 | final ScrollController scrollController;
15 | final String noStatusesFoundMessage;
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return statuses.isEmpty
20 | ? Center(
21 | child: Text(
22 | noStatusesFoundMessage,
23 | style: const TextStyle(
24 | fontSize: 18,
25 | ),
26 | ),
27 | )
28 | : MasonryGridView.count(
29 | controller: scrollController,
30 | cacheExtent: 9999,
31 | padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
32 | crossAxisCount: 2,
33 | mainAxisSpacing: 1,
34 | crossAxisSpacing: 5,
35 | itemCount: statuses.length,
36 | itemBuilder: (context, index) {
37 | final String statusPath = statuses[index];
38 | if (statusPath.endsWith(".jpg")) {
39 | return ImageTile(imagePath: statusPath);
40 | } else {
41 | return VideoTile(videoPath: statusPath);
42 | }
43 | },
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/statuses_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:status_saver/src/common/extensions/async_value.dart';
4 | import 'package:status_saver/src/home/models/tab_type.dart';
5 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
6 | import 'package:status_saver/src/statuses/notifiers/statuses_notifier.dart';
7 | import 'package:status_saver/src/statuses/views/statuses_grid_widget.dart';
8 |
9 | class StatusesScreen extends ConsumerWidget {
10 | const StatusesScreen({super.key, required this.tabType});
11 | final StatusTabType tabType;
12 |
13 | @override
14 | Widget build(BuildContext context, WidgetRef ref) {
15 | final statusesProvider = tabType == StatusTabType.recent
16 | ? recentStatusesProvider
17 | : savedStatusesProvider;
18 |
19 | final noStatusesFoundMessage = tabType == StatusTabType.recent
20 | ? context.l10n.doNotHaveSeenStatusesMessage
21 | : context.l10n.noSavedStatusesMessage;
22 |
23 | ScrollController scrollController = ScrollController();
24 | return ref.watch(statusesProvider).whenWidget(
25 | (statuses) {
26 | return Scrollbar(
27 | controller: scrollController,
28 | interactive: true,
29 | child: RefreshIndicator(
30 | onRefresh: () async => await ref.refresh(statusesProvider),
31 | child: StatusesGridWidget(
32 | scrollController: scrollController,
33 | statuses: statuses,
34 | noStatusesFoundMessage: noStatusesFoundMessage,
35 | ),
36 | ),
37 | );
38 | },
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/video_tile.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:status_saver/src/common/helpers/get_video_thumbnail.dart';
5 | import 'package:status_saver/src/statuses/views/video_view.dart';
6 |
7 | class VideoTile extends StatelessWidget {
8 | final String videoPath;
9 | const VideoTile({super.key, required this.videoPath});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return FutureBuilder(
14 | future: getVideoThumbnailData(videoPath),
15 | builder: ((_, snapshot) {
16 | if (snapshot.connectionState == ConnectionState.done &&
17 | snapshot.data != null) {
18 | return Card(
19 | elevation: 5,
20 | clipBehavior: Clip.hardEdge,
21 | child: InkWell(
22 | onTap: () => Navigator.of(context).push(
23 | MaterialPageRoute(
24 | builder: (_) => VideoView(
25 | videoPath: videoPath,
26 | // height: snapshot.data!.videoHeight,
27 | // width: snapshot.data!.videoWidth,
28 | ),
29 | ),
30 | ),
31 | child: Stack(
32 | children: [
33 | Hero(
34 | tag: videoPath,
35 | child: Image.memory(
36 | fit: BoxFit.cover,
37 | snapshot.data!,
38 | ),
39 | ),
40 | Positioned.fill(
41 | child: Container(
42 | color: Colors.black54,
43 | ),
44 | ),
45 | const Positioned.fill(
46 | child: Center(
47 | child: Icon(
48 | Icons.play_circle_fill_rounded,
49 | size: 55,
50 | color: Colors.grey,
51 | )))
52 | ],
53 | ),
54 | ),
55 | );
56 | } else {
57 | return const Center(
58 | child: CircularProgressIndicator(),
59 | );
60 | }
61 | }),
62 | );
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/lib/src/statuses/views/video_view.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:chewie/chewie.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:status_saver/src/common/helpers/statuses_helper.dart';
6 | import 'package:status_saver/src/statuses/views/status_actions.dart';
7 | import 'package:video_player/video_player.dart';
8 |
9 | class VideoView extends StatefulWidget {
10 | final String videoPath;
11 | const VideoView({
12 | super.key,
13 | required this.videoPath,
14 | });
15 |
16 | @override
17 | State createState() => _VideoViewState();
18 | }
19 |
20 | class _VideoViewState extends State {
21 | late final ChewieController? _chewieController;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | _chewieController = ChewieController(
27 | videoPlayerController:
28 | VideoPlayerController.file(File(widget.videoPath)),
29 | autoInitialize: true,
30 | autoPlay: true,
31 | showOptions: false,
32 | errorBuilder: (_, errorMessage) {
33 | return Text(errorMessage);
34 | });
35 | }
36 |
37 | @override
38 | void dispose() {
39 | _chewieController!.pause();
40 | _chewieController.dispose();
41 | super.dispose();
42 | }
43 |
44 | @override
45 | Widget build(BuildContext context) {
46 | return Scaffold(
47 | appBar: AppBar(
48 | backgroundColor: Colors.black,
49 | actions: [
50 | if (isItSavedStatus(widget.videoPath))
51 | DeleteSavedStatusAction(
52 | statusPath: widget.videoPath,
53 | onPressed: (deleteStatus) async {
54 | bool wasVideoPlaying = _chewieController?.isPlaying ?? false;
55 | if (wasVideoPlaying) {
56 | _chewieController?.pause();
57 | }
58 | await deleteStatus();
59 | if (wasVideoPlaying) {
60 | _chewieController?.play();
61 | }
62 | },
63 | ),
64 | ],
65 | ),
66 | body: Stack(
67 | clipBehavior: Clip.none,
68 | children: [
69 | Hero(
70 | tag: widget.videoPath,
71 | child: Chewie(
72 | controller: _chewieController!,
73 | ),
74 | ),
75 | Positioned(
76 | bottom: 33,
77 | right: 10,
78 | height: MediaQuery.of(context).size.height * 0.2,
79 | child: StatusActions(
80 | statusPath: widget.videoPath,
81 | pauseVideoStatus: () async {
82 | await _chewieController.pause();
83 | },
84 | ),
85 | ),
86 | ],
87 | ),
88 | );
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/src/storage_permission/notifiers/storage_permission_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 | import 'package:permission_handler/permission_handler.dart';
5 | import 'package:saf/saf.dart';
6 | import 'package:status_saver/src/common/constants/directory_paths.dart';
7 | import 'package:status_saver/src/common/helpers/storage_helper.dart';
8 | import 'package:status_saver/src/debug/console_log.dart';
9 | import 'package:status_saver/src/home/models/tab_type.dart';
10 | import 'package:status_saver/src/home/services/android_info_notifier.dart';
11 | import 'package:status_saver/src/home/services/whatsapp_type_notifier.dart';
12 | import 'package:status_saver/src/common/extensions/permission_handler.dart';
13 |
14 | class StoragePermissionNotifier
15 | extends FamilyAsyncNotifier {
16 | Saf? _saf;
17 | late final String? _statusesPath;
18 |
19 | @override
20 | FutureOr build(StatusTabType arg) async {
21 | state = const AsyncValue.loading();
22 | _statusesPath = await _getStatusesDirPath();
23 | await _initPlatformSpecificMembers();
24 | return await isStoragePermitted();
25 | }
26 |
27 | Saf? saf() => _saf;
28 | String? statusesPath() => _statusesPath;
29 |
30 | Future request() async {
31 | state = const AsyncValue.loading();
32 | final bool isPermitted = await _requestStoragePermission(_saf);
33 | state = AsyncData(isPermitted);
34 | }
35 |
36 | Future isStoragePermitted() async {
37 | try {
38 | if (arg == StatusTabType.recent) {
39 | if (_saf != null) {
40 | return await _saf!.getDirectoryPermission(isDynamic: true) ?? false;
41 | } else {
42 | return await Permission.storage.isGranted;
43 | }
44 | } else if (arg == StatusTabType.saved) {
45 | final androidInfoNotifier = await ref.read(androidInfoProvider.future);
46 | return androidInfoNotifier.isAndroid13OrLater
47 | ? await [
48 | Permission.photos,
49 | Permission.videos,
50 | ].isGranted
51 | : await Permission.storage.isGranted;
52 | } else {
53 | return false;
54 | }
55 | } catch (e) {
56 | return false;
57 | }
58 | }
59 |
60 | Future _requestStoragePermission(Saf? saf) async {
61 | if (arg == StatusTabType.recent) {
62 | try {
63 | if (saf != null) {
64 | return await saf.getDirectoryPermission(isDynamic: true) ?? false;
65 | } else {
66 | return await Permission.storage.request().isGranted;
67 | }
68 | } catch (e) {
69 | consoleLog("error in storage_helper/requestStoragePermission: $e");
70 | return false;
71 | }
72 | } else if (arg == StatusTabType.saved) {
73 | consoleLog("in saved request ok");
74 |
75 | final androidInfoNotifier = await ref.read(androidInfoProvider.future);
76 | return androidInfoNotifier.isAndroid13OrLater
77 | ? await [
78 | Permission.photos,
79 | Permission.videos,
80 | ].requestAndHandle()
81 | : await Permission.storage.requestAndHandle();
82 | } else {
83 | return false;
84 | }
85 | }
86 |
87 | Future _initPlatformSpecificMembers() async {
88 | final androidInfo = await ref.watch(androidInfoProvider.future);
89 |
90 | if (arg == StatusTabType.recent && androidInfo.isAndroid11OrLater) {
91 | final whatsAppType = await ref.watch(whatsAppTypeProvider.future);
92 |
93 | if (whatsAppType == null) {
94 | state = AsyncError("Whats app not found", StackTrace.current);
95 | return;
96 | }
97 | _saf = Saf(_statusesPath!);
98 | }
99 | }
100 |
101 | void releasePermissions() {
102 | state = const AsyncValue.data(false);
103 | }
104 |
105 | Future _getStatusesDirPath() async {
106 | if (arg == StatusTabType.recent) {
107 | return getStatusesPath(
108 | (await ref.read(whatsAppTypeProvider.future))!,
109 | (await ref.read(androidInfoProvider.future)).isAndroid11OrLater,
110 | );
111 | } else if (arg == StatusTabType.saved) {
112 | return savedStatusesDirectory;
113 | } else {
114 | return "";
115 | }
116 | }
117 | }
118 |
119 | final storagePermissionProvider = AsyncNotifierProvider.family<
120 | StoragePermissionNotifier,
121 | bool,
122 | StatusTabType>(StoragePermissionNotifier.new);
123 |
124 | final recentStoragePermissionProvider =
125 | storagePermissionProvider(StatusTabType.recent);
126 |
127 | final savedStoragePermissionProvider =
128 | storagePermissionProvider(StatusTabType.saved);
129 |
--------------------------------------------------------------------------------
/lib/src/storage_permission/views/give_permissions_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
3 |
4 | class GivePermissionsScreen extends StatelessWidget {
5 | const GivePermissionsScreen({
6 | super.key,
7 | required this.onRequestPermission,
8 | });
9 | final void Function() onRequestPermission;
10 | @override
11 | Widget build(BuildContext context) {
12 | return Column(
13 | crossAxisAlignment: CrossAxisAlignment.center,
14 | mainAxisAlignment: MainAxisAlignment.center,
15 | children: [
16 | Padding(
17 | padding: const EdgeInsets.all(8.0),
18 | child: Text(
19 | context.l10n
20 | .needToGiveStoragePermission, // FIXME: give better message using GPT
21 | textAlign: TextAlign.center,
22 | style: const TextStyle(
23 | fontSize: 18,
24 | ),
25 | ),
26 | ),
27 | ElevatedButton(
28 | onPressed: onRequestPermission,
29 | child: Text(context.l10n.giveStoragePermission),
30 | ),
31 | ],
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/src/theme/app_theme.dart:
--------------------------------------------------------------------------------
1 | import 'package:dynamic_color/dynamic_color.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:material_color_utilities/palettes/core_palette.dart';
4 |
5 | class AppTheme {
6 | static ThemeData themeData(CorePalette? corePalette, Brightness brightness) {
7 | ColorScheme scheme = corePalette?.toColorScheme(brightness: brightness) ?? defaultColorScheme(brightness);
8 | return ThemeData(
9 | useMaterial3: true,
10 | colorScheme: scheme,
11 | );
12 | }
13 |
14 | static ColorScheme defaultColorScheme(Brightness brightness) {
15 | return ColorScheme.fromSeed(
16 | seedColor: const Color(0xFF00FF00), brightness: brightness);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/src/theme/colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | const MaterialColor videoPlayIconColor = Colors.grey;
4 | final Color statusBorderColor = Colors.green.shade400;
--------------------------------------------------------------------------------
/lib/src/theme/notifiers/theme_mode_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:shared_preferences/shared_preferences.dart';
4 | import 'package:status_saver/src/localization/extensions/on_build_context.dart';
5 | import 'package:status_saver/src/common/helpers/show_toast.dart';
6 |
7 | const themeModeTypeKey = "themeData";
8 |
9 | class ThemeModeNotifier extends StateNotifier {
10 | ThemeModeNotifier() : super(null);
11 |
12 | void initialize() async {
13 | final sharedPreferences = await SharedPreferences.getInstance();
14 | String? themeModeType = sharedPreferences.getString(themeModeTypeKey);
15 | state = _getThemeMode(themeModeType);
16 | }
17 |
18 | void setThemeMode(ThemeMode? themeMode, BuildContext context) {
19 | SharedPreferences.getInstance().then((sharedPreferences) {
20 | final themeModeType = _getThemeModeType(themeMode);
21 | sharedPreferences
22 | .setString(themeModeTypeKey, themeModeType)
23 | .then((value) {
24 | if (!value) {
25 | showToast(message: context.l10n.couldNotSaveYourThemePreference);
26 | }
27 | });
28 | });
29 | state = themeMode;
30 | }
31 |
32 | static ThemeMode _getThemeMode(String? themeModeType) {
33 | switch (themeModeType) {
34 | case 'light':
35 | return ThemeMode.light;
36 | case 'dark':
37 | return ThemeMode.dark;
38 | }
39 | return ThemeMode.system;
40 | }
41 |
42 | static String _getThemeModeType(ThemeMode? themeMode) {
43 | switch (themeMode) {
44 | case ThemeMode.light:
45 | return "light";
46 | case ThemeMode.dark:
47 | return "dark";
48 | case ThemeMode.system:
49 | default:
50 | return "system";
51 | }
52 | }
53 |
54 | ThemeMode? get themeMode => state;
55 | }
56 |
57 | class MyThemes {
58 | static List themeModes = [
59 | ThemeMode.system,
60 | ThemeMode.light,
61 | ThemeMode.dark,
62 | ];
63 |
64 | static List themeModeTypes(BuildContext context) => [
65 | context.l10n.systemThemeLabel,
66 | context.l10n.lightThemeLabel,
67 | context.l10n.darkThemeLabel
68 | ];
69 |
70 | static List themeModeIcons = const [
71 | Icon(Icons.hotel_class),
72 | Icon(Icons.light_mode),
73 | Icon(Icons.dark_mode),
74 | ];
75 | }
76 |
77 | final themeModeProvider = StateNotifierProvider(
78 | (ref) => ThemeModeNotifier()..initialize());
79 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | _fe_analyzer_shared:
5 | dependency: transitive
6 | description:
7 | name: _fe_analyzer_shared
8 | sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "67.0.0"
12 | analyzer:
13 | dependency: transitive
14 | description:
15 | name: analyzer
16 | sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "6.4.1"
20 | analyzer_plugin:
21 | dependency: transitive
22 | description:
23 | name: analyzer_plugin
24 | sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "0.11.3"
28 | ansicolor:
29 | dependency: transitive
30 | description:
31 | name: ansicolor
32 | sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880"
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "2.0.2"
36 | appcheck:
37 | dependency: "direct main"
38 | description:
39 | name: appcheck
40 | sha256: "2682c9c270c28d83f8d87d68bb607a83882778b14c6a8da19df423be1b386520"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.1.0"
44 | archive:
45 | dependency: transitive
46 | description:
47 | name: archive
48 | sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "3.5.1"
52 | args:
53 | dependency: transitive
54 | description:
55 | name: args
56 | sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "2.5.0"
60 | async:
61 | dependency: transitive
62 | description:
63 | name: async
64 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "2.11.0"
68 | boolean_selector:
69 | dependency: transitive
70 | description:
71 | name: boolean_selector
72 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
73 | url: "https://pub.dev"
74 | source: hosted
75 | version: "2.1.1"
76 | characters:
77 | dependency: transitive
78 | description:
79 | name: characters
80 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
81 | url: "https://pub.dev"
82 | source: hosted
83 | version: "1.3.0"
84 | checked_yaml:
85 | dependency: transitive
86 | description:
87 | name: checked_yaml
88 | sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
89 | url: "https://pub.dev"
90 | source: hosted
91 | version: "2.0.3"
92 | chewie:
93 | dependency: "direct main"
94 | description:
95 | name: chewie
96 | sha256: e53da939709efb9aad0f3d72a69a8d05f889168b7a138af60ce78bab5c94b135
97 | url: "https://pub.dev"
98 | source: hosted
99 | version: "1.8.1"
100 | ci:
101 | dependency: transitive
102 | description:
103 | name: ci
104 | sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13"
105 | url: "https://pub.dev"
106 | source: hosted
107 | version: "0.1.0"
108 | cli_util:
109 | dependency: transitive
110 | description:
111 | name: cli_util
112 | sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
113 | url: "https://pub.dev"
114 | source: hosted
115 | version: "0.4.1"
116 | clock:
117 | dependency: transitive
118 | description:
119 | name: clock
120 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
121 | url: "https://pub.dev"
122 | source: hosted
123 | version: "1.1.1"
124 | collection:
125 | dependency: transitive
126 | description:
127 | name: collection
128 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
129 | url: "https://pub.dev"
130 | source: hosted
131 | version: "1.18.0"
132 | convert:
133 | dependency: transitive
134 | description:
135 | name: convert
136 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
137 | url: "https://pub.dev"
138 | source: hosted
139 | version: "3.1.1"
140 | cross_file:
141 | dependency: transitive
142 | description:
143 | name: cross_file
144 | sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
145 | url: "https://pub.dev"
146 | source: hosted
147 | version: "0.3.4+1"
148 | crypto:
149 | dependency: transitive
150 | description:
151 | name: crypto
152 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
153 | url: "https://pub.dev"
154 | source: hosted
155 | version: "3.0.3"
156 | csslib:
157 | dependency: transitive
158 | description:
159 | name: csslib
160 | sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
161 | url: "https://pub.dev"
162 | source: hosted
163 | version: "1.0.0"
164 | cupertino_icons:
165 | dependency: "direct main"
166 | description:
167 | name: cupertino_icons
168 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
169 | url: "https://pub.dev"
170 | source: hosted
171 | version: "1.0.8"
172 | custom_lint:
173 | dependency: "direct dev"
174 | description:
175 | name: custom_lint
176 | sha256: "7c0aec12df22f9082146c354692056677f1e70bc43471644d1fdb36c6fdda799"
177 | url: "https://pub.dev"
178 | source: hosted
179 | version: "0.6.4"
180 | custom_lint_builder:
181 | dependency: transitive
182 | description:
183 | name: custom_lint_builder
184 | sha256: d7dc41e709dde223806660268678be7993559e523eb3164e2a1425fd6f7615a9
185 | url: "https://pub.dev"
186 | source: hosted
187 | version: "0.6.4"
188 | custom_lint_core:
189 | dependency: transitive
190 | description:
191 | name: custom_lint_core
192 | sha256: a85e8f78f4c52f6c63cdaf8c872eb573db0231dcdf3c3a5906d493c1f8bc20e6
193 | url: "https://pub.dev"
194 | source: hosted
195 | version: "0.6.3"
196 | dart_style:
197 | dependency: transitive
198 | description:
199 | name: dart_style
200 | sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
201 | url: "https://pub.dev"
202 | source: hosted
203 | version: "2.3.6"
204 | dbus:
205 | dependency: transitive
206 | description:
207 | name: dbus
208 | sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
209 | url: "https://pub.dev"
210 | source: hosted
211 | version: "0.7.10"
212 | device_info_plus:
213 | dependency: "direct main"
214 | description:
215 | name: device_info_plus
216 | sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91
217 | url: "https://pub.dev"
218 | source: hosted
219 | version: "10.1.0"
220 | device_info_plus_platform_interface:
221 | dependency: transitive
222 | description:
223 | name: device_info_plus_platform_interface
224 | sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
225 | url: "https://pub.dev"
226 | source: hosted
227 | version: "7.0.0"
228 | dynamic_color:
229 | dependency: "direct main"
230 | description:
231 | name: dynamic_color
232 | sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d
233 | url: "https://pub.dev"
234 | source: hosted
235 | version: "1.7.0"
236 | fake_async:
237 | dependency: transitive
238 | description:
239 | name: fake_async
240 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
241 | url: "https://pub.dev"
242 | source: hosted
243 | version: "1.3.1"
244 | ffi:
245 | dependency: transitive
246 | description:
247 | name: ffi
248 | sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
249 | url: "https://pub.dev"
250 | source: hosted
251 | version: "2.1.2"
252 | file:
253 | dependency: transitive
254 | description:
255 | name: file
256 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
257 | url: "https://pub.dev"
258 | source: hosted
259 | version: "7.0.0"
260 | fixnum:
261 | dependency: transitive
262 | description:
263 | name: fixnum
264 | sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
265 | url: "https://pub.dev"
266 | source: hosted
267 | version: "1.1.0"
268 | flutter:
269 | dependency: "direct main"
270 | description: flutter
271 | source: sdk
272 | version: "0.0.0"
273 | flutter_lints:
274 | dependency: "direct dev"
275 | description:
276 | name: flutter_lints
277 | sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
278 | url: "https://pub.dev"
279 | source: hosted
280 | version: "3.0.2"
281 | flutter_localizations:
282 | dependency: "direct main"
283 | description: flutter
284 | source: sdk
285 | version: "0.0.0"
286 | flutter_native_splash:
287 | dependency: "direct main"
288 | description:
289 | name: flutter_native_splash
290 | sha256: edf39bcf4d74aca1eb2c1e43c3e445fd9f494013df7f0da752fefe72020eedc0
291 | url: "https://pub.dev"
292 | source: hosted
293 | version: "2.4.0"
294 | flutter_riverpod:
295 | dependency: "direct main"
296 | description:
297 | name: flutter_riverpod
298 | sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d"
299 | url: "https://pub.dev"
300 | source: hosted
301 | version: "2.5.1"
302 | flutter_staggered_grid_view:
303 | dependency: "direct main"
304 | description:
305 | name: flutter_staggered_grid_view
306 | sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395"
307 | url: "https://pub.dev"
308 | source: hosted
309 | version: "0.7.0"
310 | flutter_test:
311 | dependency: "direct dev"
312 | description: flutter
313 | source: sdk
314 | version: "0.0.0"
315 | flutter_web_plugins:
316 | dependency: transitive
317 | description: flutter
318 | source: sdk
319 | version: "0.0.0"
320 | fluttertoast:
321 | dependency: "direct main"
322 | description:
323 | name: fluttertoast
324 | sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
325 | url: "https://pub.dev"
326 | source: hosted
327 | version: "8.2.5"
328 | font_awesome_flutter:
329 | dependency: "direct main"
330 | description:
331 | name: font_awesome_flutter
332 | sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f"
333 | url: "https://pub.dev"
334 | source: hosted
335 | version: "10.7.0"
336 | freezed_annotation:
337 | dependency: transitive
338 | description:
339 | name: freezed_annotation
340 | sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d
341 | url: "https://pub.dev"
342 | source: hosted
343 | version: "2.4.1"
344 | glob:
345 | dependency: transitive
346 | description:
347 | name: glob
348 | sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
349 | url: "https://pub.dev"
350 | source: hosted
351 | version: "2.1.2"
352 | hotreloader:
353 | dependency: transitive
354 | description:
355 | name: hotreloader
356 | sha256: ed56fdc1f3a8ac924e717257621d09e9ec20e308ab6352a73a50a1d7a4d9158e
357 | url: "https://pub.dev"
358 | source: hosted
359 | version: "4.2.0"
360 | html:
361 | dependency: transitive
362 | description:
363 | name: html
364 | sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
365 | url: "https://pub.dev"
366 | source: hosted
367 | version: "0.15.4"
368 | http:
369 | dependency: transitive
370 | description:
371 | name: http
372 | sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
373 | url: "https://pub.dev"
374 | source: hosted
375 | version: "1.2.1"
376 | http_parser:
377 | dependency: transitive
378 | description:
379 | name: http_parser
380 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
381 | url: "https://pub.dev"
382 | source: hosted
383 | version: "4.0.2"
384 | image:
385 | dependency: transitive
386 | description:
387 | name: image
388 | sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
389 | url: "https://pub.dev"
390 | source: hosted
391 | version: "4.1.7"
392 | intl:
393 | dependency: "direct main"
394 | description:
395 | name: intl
396 | sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
397 | url: "https://pub.dev"
398 | source: hosted
399 | version: "0.18.1"
400 | json_annotation:
401 | dependency: transitive
402 | description:
403 | name: json_annotation
404 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
405 | url: "https://pub.dev"
406 | source: hosted
407 | version: "4.9.0"
408 | leak_tracker:
409 | dependency: transitive
410 | description:
411 | name: leak_tracker
412 | sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
413 | url: "https://pub.dev"
414 | source: hosted
415 | version: "10.0.0"
416 | leak_tracker_flutter_testing:
417 | dependency: transitive
418 | description:
419 | name: leak_tracker_flutter_testing
420 | sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
421 | url: "https://pub.dev"
422 | source: hosted
423 | version: "2.0.1"
424 | leak_tracker_testing:
425 | dependency: transitive
426 | description:
427 | name: leak_tracker_testing
428 | sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
429 | url: "https://pub.dev"
430 | source: hosted
431 | version: "2.0.1"
432 | lints:
433 | dependency: transitive
434 | description:
435 | name: lints
436 | sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
437 | url: "https://pub.dev"
438 | source: hosted
439 | version: "3.0.0"
440 | logging:
441 | dependency: transitive
442 | description:
443 | name: logging
444 | sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
445 | url: "https://pub.dev"
446 | source: hosted
447 | version: "1.2.0"
448 | matcher:
449 | dependency: transitive
450 | description:
451 | name: matcher
452 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
453 | url: "https://pub.dev"
454 | source: hosted
455 | version: "0.12.16+1"
456 | material_color_utilities:
457 | dependency: "direct main"
458 | description:
459 | name: material_color_utilities
460 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
461 | url: "https://pub.dev"
462 | source: hosted
463 | version: "0.8.0"
464 | meta:
465 | dependency: transitive
466 | description:
467 | name: meta
468 | sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
469 | url: "https://pub.dev"
470 | source: hosted
471 | version: "1.11.0"
472 | mime:
473 | dependency: transitive
474 | description:
475 | name: mime
476 | sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
477 | url: "https://pub.dev"
478 | source: hosted
479 | version: "1.0.5"
480 | nested:
481 | dependency: transitive
482 | description:
483 | name: nested
484 | sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
485 | url: "https://pub.dev"
486 | source: hosted
487 | version: "1.0.0"
488 | package_config:
489 | dependency: transitive
490 | description:
491 | name: package_config
492 | sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
493 | url: "https://pub.dev"
494 | source: hosted
495 | version: "2.1.0"
496 | package_info_plus:
497 | dependency: transitive
498 | description:
499 | name: package_info_plus
500 | sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0
501 | url: "https://pub.dev"
502 | source: hosted
503 | version: "8.0.0"
504 | package_info_plus_platform_interface:
505 | dependency: transitive
506 | description:
507 | name: package_info_plus_platform_interface
508 | sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e
509 | url: "https://pub.dev"
510 | source: hosted
511 | version: "3.0.0"
512 | path:
513 | dependency: transitive
514 | description:
515 | name: path
516 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
517 | url: "https://pub.dev"
518 | source: hosted
519 | version: "1.9.0"
520 | path_provider:
521 | dependency: transitive
522 | description:
523 | name: path_provider
524 | sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
525 | url: "https://pub.dev"
526 | source: hosted
527 | version: "2.1.3"
528 | path_provider_android:
529 | dependency: transitive
530 | description:
531 | name: path_provider_android
532 | sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
533 | url: "https://pub.dev"
534 | source: hosted
535 | version: "2.2.4"
536 | path_provider_foundation:
537 | dependency: transitive
538 | description:
539 | name: path_provider_foundation
540 | sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
541 | url: "https://pub.dev"
542 | source: hosted
543 | version: "2.4.0"
544 | path_provider_linux:
545 | dependency: transitive
546 | description:
547 | name: path_provider_linux
548 | sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
549 | url: "https://pub.dev"
550 | source: hosted
551 | version: "2.2.1"
552 | path_provider_platform_interface:
553 | dependency: transitive
554 | description:
555 | name: path_provider_platform_interface
556 | sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
557 | url: "https://pub.dev"
558 | source: hosted
559 | version: "2.1.2"
560 | path_provider_windows:
561 | dependency: transitive
562 | description:
563 | name: path_provider_windows
564 | sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
565 | url: "https://pub.dev"
566 | source: hosted
567 | version: "2.2.1"
568 | permission_handler:
569 | dependency: "direct main"
570 | description:
571 | name: permission_handler
572 | sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5
573 | url: "https://pub.dev"
574 | source: hosted
575 | version: "10.4.5"
576 | permission_handler_android:
577 | dependency: transitive
578 | description:
579 | name: permission_handler_android
580 | sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47"
581 | url: "https://pub.dev"
582 | source: hosted
583 | version: "10.3.6"
584 | permission_handler_apple:
585 | dependency: transitive
586 | description:
587 | name: permission_handler_apple
588 | sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
589 | url: "https://pub.dev"
590 | source: hosted
591 | version: "9.1.4"
592 | permission_handler_platform_interface:
593 | dependency: transitive
594 | description:
595 | name: permission_handler_platform_interface
596 | sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
597 | url: "https://pub.dev"
598 | source: hosted
599 | version: "3.12.0"
600 | permission_handler_windows:
601 | dependency: transitive
602 | description:
603 | name: permission_handler_windows
604 | sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
605 | url: "https://pub.dev"
606 | source: hosted
607 | version: "0.1.3"
608 | petitparser:
609 | dependency: transitive
610 | description:
611 | name: petitparser
612 | sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
613 | url: "https://pub.dev"
614 | source: hosted
615 | version: "6.0.2"
616 | photo_view:
617 | dependency: "direct main"
618 | description:
619 | name: photo_view
620 | sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e"
621 | url: "https://pub.dev"
622 | source: hosted
623 | version: "0.15.0"
624 | platform:
625 | dependency: transitive
626 | description:
627 | name: platform
628 | sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
629 | url: "https://pub.dev"
630 | source: hosted
631 | version: "3.1.4"
632 | plugin_platform_interface:
633 | dependency: transitive
634 | description:
635 | name: plugin_platform_interface
636 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
637 | url: "https://pub.dev"
638 | source: hosted
639 | version: "2.1.8"
640 | provider:
641 | dependency: transitive
642 | description:
643 | name: provider
644 | sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
645 | url: "https://pub.dev"
646 | source: hosted
647 | version: "6.1.2"
648 | pub_semver:
649 | dependency: transitive
650 | description:
651 | name: pub_semver
652 | sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
653 | url: "https://pub.dev"
654 | source: hosted
655 | version: "2.1.4"
656 | pubspec_parse:
657 | dependency: transitive
658 | description:
659 | name: pubspec_parse
660 | sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
661 | url: "https://pub.dev"
662 | source: hosted
663 | version: "1.2.3"
664 | riverpod:
665 | dependency: transitive
666 | description:
667 | name: riverpod
668 | sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d
669 | url: "https://pub.dev"
670 | source: hosted
671 | version: "2.5.1"
672 | riverpod_analyzer_utils:
673 | dependency: transitive
674 | description:
675 | name: riverpod_analyzer_utils
676 | sha256: "8b71f03fc47ae27d13769496a1746332df4cec43918aeba9aff1e232783a780f"
677 | url: "https://pub.dev"
678 | source: hosted
679 | version: "0.5.1"
680 | riverpod_lint:
681 | dependency: "direct dev"
682 | description:
683 | name: riverpod_lint
684 | sha256: "3c67c14ccd16f0c9d53e35ef70d06cd9d072e2fb14557326886bbde903b230a5"
685 | url: "https://pub.dev"
686 | source: hosted
687 | version: "2.3.10"
688 | rxdart:
689 | dependency: transitive
690 | description:
691 | name: rxdart
692 | sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
693 | url: "https://pub.dev"
694 | source: hosted
695 | version: "0.27.7"
696 | saf:
697 | dependency: "direct main"
698 | description:
699 | name: saf
700 | sha256: "3b7565638bc155801dc2b1b948ee0545f8cf9310da6e0f4ded45f62ee83f1321"
701 | url: "https://pub.dev"
702 | source: hosted
703 | version: "1.0.3+4"
704 | share_plus:
705 | dependency: "direct main"
706 | description:
707 | name: share_plus
708 | sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
709 | url: "https://pub.dev"
710 | source: hosted
711 | version: "9.0.0"
712 | share_plus_platform_interface:
713 | dependency: transitive
714 | description:
715 | name: share_plus_platform_interface
716 | sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
717 | url: "https://pub.dev"
718 | source: hosted
719 | version: "4.0.0"
720 | shared_preferences:
721 | dependency: "direct main"
722 | description:
723 | name: shared_preferences
724 | sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
725 | url: "https://pub.dev"
726 | source: hosted
727 | version: "2.2.3"
728 | shared_preferences_android:
729 | dependency: transitive
730 | description:
731 | name: shared_preferences_android
732 | sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
733 | url: "https://pub.dev"
734 | source: hosted
735 | version: "2.2.2"
736 | shared_preferences_foundation:
737 | dependency: transitive
738 | description:
739 | name: shared_preferences_foundation
740 | sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
741 | url: "https://pub.dev"
742 | source: hosted
743 | version: "2.3.5"
744 | shared_preferences_linux:
745 | dependency: transitive
746 | description:
747 | name: shared_preferences_linux
748 | sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
749 | url: "https://pub.dev"
750 | source: hosted
751 | version: "2.3.2"
752 | shared_preferences_platform_interface:
753 | dependency: transitive
754 | description:
755 | name: shared_preferences_platform_interface
756 | sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
757 | url: "https://pub.dev"
758 | source: hosted
759 | version: "2.3.2"
760 | shared_preferences_web:
761 | dependency: transitive
762 | description:
763 | name: shared_preferences_web
764 | sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
765 | url: "https://pub.dev"
766 | source: hosted
767 | version: "2.3.0"
768 | shared_preferences_windows:
769 | dependency: transitive
770 | description:
771 | name: shared_preferences_windows
772 | sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
773 | url: "https://pub.dev"
774 | source: hosted
775 | version: "2.3.2"
776 | sky_engine:
777 | dependency: transitive
778 | description: flutter
779 | source: sdk
780 | version: "0.0.99"
781 | source_span:
782 | dependency: transitive
783 | description:
784 | name: source_span
785 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
786 | url: "https://pub.dev"
787 | source: hosted
788 | version: "1.10.0"
789 | sprintf:
790 | dependency: transitive
791 | description:
792 | name: sprintf
793 | sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
794 | url: "https://pub.dev"
795 | source: hosted
796 | version: "7.0.0"
797 | stack_trace:
798 | dependency: transitive
799 | description:
800 | name: stack_trace
801 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
802 | url: "https://pub.dev"
803 | source: hosted
804 | version: "1.11.1"
805 | state_notifier:
806 | dependency: transitive
807 | description:
808 | name: state_notifier
809 | sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb
810 | url: "https://pub.dev"
811 | source: hosted
812 | version: "1.0.0"
813 | stream_channel:
814 | dependency: transitive
815 | description:
816 | name: stream_channel
817 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
818 | url: "https://pub.dev"
819 | source: hosted
820 | version: "2.1.2"
821 | stream_transform:
822 | dependency: transitive
823 | description:
824 | name: stream_transform
825 | sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
826 | url: "https://pub.dev"
827 | source: hosted
828 | version: "2.1.0"
829 | string_scanner:
830 | dependency: transitive
831 | description:
832 | name: string_scanner
833 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
834 | url: "https://pub.dev"
835 | source: hosted
836 | version: "1.2.0"
837 | term_glyph:
838 | dependency: transitive
839 | description:
840 | name: term_glyph
841 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
842 | url: "https://pub.dev"
843 | source: hosted
844 | version: "1.2.1"
845 | test_api:
846 | dependency: transitive
847 | description:
848 | name: test_api
849 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
850 | url: "https://pub.dev"
851 | source: hosted
852 | version: "0.6.1"
853 | typed_data:
854 | dependency: transitive
855 | description:
856 | name: typed_data
857 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
858 | url: "https://pub.dev"
859 | source: hosted
860 | version: "1.3.2"
861 | universal_io:
862 | dependency: transitive
863 | description:
864 | name: universal_io
865 | sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
866 | url: "https://pub.dev"
867 | source: hosted
868 | version: "2.2.2"
869 | url_launcher_linux:
870 | dependency: transitive
871 | description:
872 | name: url_launcher_linux
873 | sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
874 | url: "https://pub.dev"
875 | source: hosted
876 | version: "3.1.1"
877 | url_launcher_platform_interface:
878 | dependency: transitive
879 | description:
880 | name: url_launcher_platform_interface
881 | sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
882 | url: "https://pub.dev"
883 | source: hosted
884 | version: "2.3.2"
885 | url_launcher_web:
886 | dependency: transitive
887 | description:
888 | name: url_launcher_web
889 | sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
890 | url: "https://pub.dev"
891 | source: hosted
892 | version: "2.3.1"
893 | url_launcher_windows:
894 | dependency: transitive
895 | description:
896 | name: url_launcher_windows
897 | sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
898 | url: "https://pub.dev"
899 | source: hosted
900 | version: "3.1.1"
901 | uuid:
902 | dependency: transitive
903 | description:
904 | name: uuid
905 | sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
906 | url: "https://pub.dev"
907 | source: hosted
908 | version: "4.4.0"
909 | vector_math:
910 | dependency: transitive
911 | description:
912 | name: vector_math
913 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
914 | url: "https://pub.dev"
915 | source: hosted
916 | version: "2.1.4"
917 | video_player:
918 | dependency: "direct main"
919 | description:
920 | name: video_player
921 | sha256: aced48e701e24c02b0b7f881a8819e4937794e46b5a5821005e2bf3b40a324cc
922 | url: "https://pub.dev"
923 | source: hosted
924 | version: "2.8.7"
925 | video_player_android:
926 | dependency: transitive
927 | description:
928 | name: video_player_android
929 | sha256: "134e1ad410d67e18a19486ed9512c72dfc6d8ffb284d0e8f2e99e903d1ba8fa3"
930 | url: "https://pub.dev"
931 | source: hosted
932 | version: "2.4.14"
933 | video_player_avfoundation:
934 | dependency: transitive
935 | description:
936 | name: video_player_avfoundation
937 | sha256: d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c
938 | url: "https://pub.dev"
939 | source: hosted
940 | version: "2.6.1"
941 | video_player_platform_interface:
942 | dependency: transitive
943 | description:
944 | name: video_player_platform_interface
945 | sha256: "236454725fafcacf98f0f39af0d7c7ab2ce84762e3b63f2cbb3ef9a7e0550bc6"
946 | url: "https://pub.dev"
947 | source: hosted
948 | version: "6.2.2"
949 | video_player_web:
950 | dependency: transitive
951 | description:
952 | name: video_player_web
953 | sha256: ff4d69a6614b03f055397c27a71c9d3ddea2b2a23d71b2ba0164f59ca32b8fe2
954 | url: "https://pub.dev"
955 | source: hosted
956 | version: "2.3.1"
957 | video_thumbnail:
958 | dependency: "direct main"
959 | description:
960 | name: video_thumbnail
961 | sha256: "3455c189d3f0bb4e3fc2236475aa84fe598b9b2d0e08f43b9761f5bc44210016"
962 | url: "https://pub.dev"
963 | source: hosted
964 | version: "0.5.3"
965 | vm_service:
966 | dependency: transitive
967 | description:
968 | name: vm_service
969 | sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
970 | url: "https://pub.dev"
971 | source: hosted
972 | version: "13.0.0"
973 | wakelock_plus:
974 | dependency: transitive
975 | description:
976 | name: wakelock_plus
977 | sha256: "14758533319a462ffb5aa3b7ddb198e59b29ac3b02da14173a1715d65d4e6e68"
978 | url: "https://pub.dev"
979 | source: hosted
980 | version: "1.2.5"
981 | wakelock_plus_platform_interface:
982 | dependency: transitive
983 | description:
984 | name: wakelock_plus_platform_interface
985 | sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
986 | url: "https://pub.dev"
987 | source: hosted
988 | version: "1.2.1"
989 | watcher:
990 | dependency: transitive
991 | description:
992 | name: watcher
993 | sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
994 | url: "https://pub.dev"
995 | source: hosted
996 | version: "1.1.0"
997 | web:
998 | dependency: transitive
999 | description:
1000 | name: web
1001 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
1002 | url: "https://pub.dev"
1003 | source: hosted
1004 | version: "0.5.1"
1005 | win32:
1006 | dependency: transitive
1007 | description:
1008 | name: win32
1009 | sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
1010 | url: "https://pub.dev"
1011 | source: hosted
1012 | version: "5.5.0"
1013 | win32_registry:
1014 | dependency: transitive
1015 | description:
1016 | name: win32_registry
1017 | sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb"
1018 | url: "https://pub.dev"
1019 | source: hosted
1020 | version: "1.1.3"
1021 | xdg_directories:
1022 | dependency: transitive
1023 | description:
1024 | name: xdg_directories
1025 | sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
1026 | url: "https://pub.dev"
1027 | source: hosted
1028 | version: "1.0.4"
1029 | xml:
1030 | dependency: transitive
1031 | description:
1032 | name: xml
1033 | sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
1034 | url: "https://pub.dev"
1035 | source: hosted
1036 | version: "6.5.0"
1037 | yaml:
1038 | dependency: transitive
1039 | description:
1040 | name: yaml
1041 | sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
1042 | url: "https://pub.dev"
1043 | source: hosted
1044 | version: "3.1.2"
1045 | sdks:
1046 | dart: ">=3.3.1 <4.0.0"
1047 | flutter: ">=3.19.0"
1048 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: status_saver
2 | description: "Open Source Status Saver application"
3 |
4 | publish_to: "none"
5 |
6 | version: 1.0.0+1
7 |
8 | environment:
9 | sdk: ">=3.3.1 <4.0.0"
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 | flutter_localizations:
15 | sdk: flutter
16 | intl: any
17 |
18 | cupertino_icons: ^1.0.6
19 | flutter_native_splash: ^2.4.0
20 | flutter_riverpod: ^2.5.1
21 | dynamic_color: ^1.7.0
22 | material_color_utilities: ^0.8.0
23 | shared_preferences: ^2.2.3
24 | fluttertoast: ^8.2.5
25 | permission_handler: ^10.2.0
26 | font_awesome_flutter: ^10.7.0
27 | device_info_plus: ^10.1.0
28 | saf: ^1.0.3+4
29 | flutter_staggered_grid_view: ^0.7.0
30 | appcheck: ^1.1.0
31 | chewie: ^1.8.1
32 | photo_view: ^0.15.0
33 | video_thumbnail: ^0.5.3
34 | video_player: ^2.8.7
35 | share_plus: ^9.0.0
36 |
37 | dev_dependencies:
38 | flutter_test:
39 | sdk: flutter
40 |
41 | flutter_lints: ^3.0.0
42 | custom_lint: ^0.6.4
43 | riverpod_lint: ^2.3.10
44 |
45 | flutter:
46 | uses-material-design: true
47 | generate: true
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility in the flutter_test package. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:status_saver/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------