stuff
12
.metadata
|
|
@ -4,7 +4,7 @@
|
||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e"
|
revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
|
@ -13,11 +13,11 @@ project_type: app
|
||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
|
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
|
||||||
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
|
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
|
||||||
- platform: macos
|
- platform: android
|
||||||
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
|
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
|
||||||
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
|
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,29 @@ plugins {
|
||||||
id "com.android.application"
|
id "com.android.application"
|
||||||
// START: FlutterFire Configuration
|
// START: FlutterFire Configuration
|
||||||
id 'com.google.gms.google-services'
|
id 'com.google.gms.google-services'
|
||||||
|
id 'com.google.firebase.crashlytics'
|
||||||
// END: FlutterFire Configuration
|
// END: FlutterFire Configuration
|
||||||
id "kotlin-android"
|
id "kotlin-android"
|
||||||
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
id "dev.flutter.flutter-gradle-plugin"
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
}
|
}
|
||||||
|
|
||||||
def localProperties = new Properties()
|
def localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file("local.properties")
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
localPropertiesFile.withReader("UTF-8") { reader ->
|
||||||
localProperties.load(reader)
|
localProperties.load(reader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||||
if (flutterVersionName == null) {
|
if (flutterVersionName == null) {
|
||||||
flutterVersionName = '1.0'
|
flutterVersionName = "1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
|
|
@ -31,34 +33,25 @@ if (keystorePropertiesFile.exists()) {
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace "com.cinnabarflower.mnemo_cards"
|
namespace = "com.cinnabarflower.mnemo_cards"
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = '1.8'
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.cinnabarflower.mnemo_cards"
|
applicationId = "com.cinnabarflower.mnemo_cards"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||||
minSdkVersion 25
|
minSdk = 25
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode = flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName = flutterVersionName
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
|
@ -69,6 +62,7 @@ android {
|
||||||
storePassword keystoreProperties['storePassword']
|
storePassword keystoreProperties['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
|
|
@ -77,7 +71,5 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
source '../..'
|
source = "../.."
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {}
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,14 @@
|
||||||
"certificate_hash": "6df4f259b9c53ac01472c17df69e8c91494f3947"
|
"certificate_hash": "6df4f259b9c53ac01472c17df69e8c91494f3947"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"client_id": "701767851968-5e6v0b5humhj0iu22t21nb9dtgt4tjus.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "com.cinnabarflower.mnemo_cards",
|
||||||
|
"certificate_hash": "49bb5b6863c9e6d8db43e7eb4d54796a300d87fe"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"client_id": "701767851968-vqvjgf1u79jg924inm25bfuv4dg41t2u.apps.googleusercontent.com",
|
"client_id": "701767851968-vqvjgf1u79jg924inm25bfuv4dg41t2u.apps.googleusercontent.com",
|
||||||
"client_type": 1,
|
"client_type": 1,
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,5 @@
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<application
|
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
|
||||||
/>
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
|
android:taskAffinity=""
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
|
|
@ -35,9 +36,15 @@
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</application>
|
||||||
|
<!-- Required to query activities that can process text, see:
|
||||||
|
https://developer.android.com/training/package-visibility and
|
||||||
|
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||||
|
|
||||||
|
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.intent.action.TTS_SERVICE" />
|
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||||
|
<data android:mimeType="text/plain"/>
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,4 @@ package com.cinnabarflower.mnemo_cards
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
class MainActivity: FlutterActivity()
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
|
@ -1,20 +1,3 @@
|
||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.8.20'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
|
||||||
// START: FlutterFire Configuration
|
|
||||||
classpath 'com.google.gms:google-services:4.3.14'
|
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
|
|
||||||
// END: FlutterFire Configuration
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
|
@ -22,12 +5,12 @@ allprojects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.buildDir = '../build'
|
rootProject.buildDir = "../build"
|
||||||
subprojects {
|
subprojects {
|
||||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
}
|
}
|
||||||
subprojects {
|
subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(":app")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register("clean", Delete) {
|
tasks.register("clean", Delete) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
org.gradle.jvmargs=-Xmx4608M
|
org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
|
|
||||||
4
android/key.properties
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
storePassword=345234
|
||||||
|
keyPassword=345234
|
||||||
|
keyAlias=upload
|
||||||
|
storeFile=../../../../upload-keystore.jks
|
||||||
BIN
android/pepk.jar
Normal file
|
|
@ -5,18 +5,14 @@ pluginManagement {
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
return flutterSdkPath
|
return flutterSdkPath
|
||||||
}
|
}()
|
||||||
settings.ext.flutterSdkPath = flutterSdkPath()
|
|
||||||
|
|
||||||
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
|
|
||||||
plugins {
|
repositories {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
google()
|
||||||
id "com.android.application" version "7.3.0" apply false
|
mavenCentral()
|
||||||
// START: FlutterFire Configuration
|
gradlePluginPortal()
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
|
||||||
// END: FlutterFire Configuration
|
|
||||||
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For yoo kassa
|
// For yoo kassa
|
||||||
|
|
@ -33,6 +29,14 @@ pluginManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include ":app"
|
plugins {
|
||||||
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
|
id "com.android.application" version "7.3.0" apply false
|
||||||
|
// START: FlutterFire Configuration
|
||||||
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
|
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
||||||
|
// END: FlutterFire Configuration
|
||||||
|
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
|
||||||
|
}
|
||||||
|
|
||||||
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
include ":app"
|
||||||
|
|
|
||||||
BIN
cerdo_1024x512.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
cerdo_512.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
|
|
@ -203,6 +203,7 @@
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
10510DEBDDA8DED725BA2250 /* [CP] Copy Pods Resources */,
|
10510DEBDDA8DED725BA2250 /* [CP] Copy Pods Resources */,
|
||||||
EAA1E3F7E6B26606E42D1048 /* [CP] Embed Pods Frameworks */,
|
EAA1E3F7E6B26606E42D1048 /* [CP] Embed Pods Frameworks */,
|
||||||
|
CDC7B89EEA6C1D8D4DC3C75E /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
|
@ -345,6 +346,24 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||||
};
|
};
|
||||||
|
CDC7B89EEA6C1D8D4DC3C75E /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\n#!/bin/bash\nPATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=$PODS_ROOT/FirebaseCrashlytics/upload-symbols --platform=ios --apple-project-path=${SRCROOT} --env-platform-name=${PLATFORM_NAME} --env-configuration=${CONFIGURATION} --env-project-dir=${PROJECT_DIR} --env-built-products-dir=${BUILT_PRODUCTS_DIR} --env-dwarf-dsym-folder-path=${DWARF_DSYM_FOLDER_PATH} --env-dwarf-dsym-file-name=${DWARF_DSYM_FILE_NAME} --env-infoplist-path=${INFOPLIST_PATH} --default-config=default\n";
|
||||||
|
};
|
||||||
EAA1E3F7E6B26606E42D1048 /* [CP] Embed Pods Frameworks */ = {
|
EAA1E3F7E6B26606E42D1048 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,10 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:mnemo_cards/admin/admin_api.dart';
|
import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
import '../widgets/image_fade.dart';
|
|
||||||
|
|
||||||
class EditCard {
|
class EditCard {
|
||||||
GameCardDto gameCardDto;
|
GameCardDto gameCardDto;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
import 'package:mnemo_cards/admin/admin_api.dart';
|
import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/api.dart';
|
import 'package:mnemo_cards/managers/repository/api.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import '../utils/string_helper.dart';
|
import '../utils/string_helper.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
import '../widgets/image_fade.dart';
|
|
||||||
|
|
||||||
class AddPackage with Api {
|
class AddPackage with Api {
|
||||||
EditCardPackDto cardPackDto;
|
EditCardPackDto cardPackDto;
|
||||||
|
|
@ -132,6 +131,13 @@ class AddPackage with Api {
|
||||||
cardPackDto = cardPackDto.copyWith.googlePlayId(v);
|
cardPackDto = cardPackDto.copyWith.googlePlayId(v);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
_TextParam(
|
||||||
|
'Rustore id',
|
||||||
|
cardPackDto.rustoreId,
|
||||||
|
(v) {
|
||||||
|
cardPackDto = cardPackDto.copyWith.rustoreId(v);
|
||||||
|
},
|
||||||
|
),
|
||||||
_TextParam(
|
_TextParam(
|
||||||
'Appstore id',
|
'Appstore id',
|
||||||
cardPackDto.appStoreId,
|
cardPackDto.appStoreId,
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:mnemo_cards/admin/admin_api.dart';
|
import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/di/injector.dart';
|
import 'package:mnemo_cards/di/injector.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
||||||
import 'package:mnemo_cards/theme/themes.dart';
|
import 'package:mnemo_cards/theme/themes.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
import 'add_package.dart';
|
import 'add_package.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/di/injector.dart';
|
import 'package:mnemo_cards/di/injector.dart';
|
||||||
import 'package:mnemo_cards/di/locator.dart';
|
import 'package:mnemo_cards/di/locator.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@ import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_rustore_billing/pigeons/rustore.dart';
|
||||||
import 'package:in_app_purchase/in_app_purchase.dart';
|
import 'package:in_app_purchase/in_app_purchase.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
import '../../di/injector.dart';
|
import '../../di/injector.dart';
|
||||||
import '../../di/locator.dart';
|
import '../../di/locator.dart';
|
||||||
|
import '../../flags.dart';
|
||||||
import '../../main.dart';
|
import '../../main.dart';
|
||||||
import '../analytics/analytics.dart';
|
import '../analytics/analytics.dart';
|
||||||
|
import 'rustore/mnemo_rustore.dart';
|
||||||
|
|
||||||
enum StoreItemType {
|
enum StoreItemType {
|
||||||
ads,
|
ads,
|
||||||
|
|
@ -26,14 +29,18 @@ class InAppPurchaseService {
|
||||||
|
|
||||||
Future<bool> buyPack(CardPackBuyDto dto) async {
|
Future<bool> buyPack(CardPackBuyDto dto) async {
|
||||||
try {
|
try {
|
||||||
final pack = await getPackStoreProduct(dto);
|
if (RUSTORE_BUILD) {
|
||||||
final result = await buyItemInStore(pack.first);
|
return RustorePurchaseService().buyPack(dto);
|
||||||
return result;
|
} else {
|
||||||
|
final pack = await _getPackStoreProduct(dto);
|
||||||
|
final result = await _buyItemInStore(pack.first);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log('err', error: e, stackTrace: s);
|
log('err', error: e, stackTrace: s);
|
||||||
Analytics.buyError(
|
Analytics.buyError(
|
||||||
dto,
|
dto,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
data: {
|
data: {
|
||||||
'e': e.toString(),
|
'e': e.toString(),
|
||||||
's': s.toString(),
|
's': s.toString(),
|
||||||
|
|
@ -92,12 +99,12 @@ class InAppPurchaseService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ProductDetails>> getPackStoreProduct(CardPackBuyDto dto) async {
|
Future<List<ProductDetails>> _getPackStoreProduct(CardPackBuyDto dto) async {
|
||||||
final bool isAvailable = await _inAppPurchase.isAvailable();
|
final bool isAvailable = await _inAppPurchase.isAvailable();
|
||||||
if (!isAvailable) {
|
if (!isAvailable) {
|
||||||
Analytics.buyError(
|
Analytics.buyError(
|
||||||
dto,
|
dto,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
message: 'in app purchase not available',
|
message: 'in app purchase not available',
|
||||||
);
|
);
|
||||||
return [];
|
return [];
|
||||||
|
|
@ -109,7 +116,7 @@ class InAppPurchaseService {
|
||||||
if (ids.isEmpty) {
|
if (ids.isEmpty) {
|
||||||
Analytics.buyError(
|
Analytics.buyError(
|
||||||
dto,
|
dto,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
message: 'product id not set',
|
message: 'product id not set',
|
||||||
);
|
);
|
||||||
return [];
|
return [];
|
||||||
|
|
@ -122,7 +129,7 @@ class InAppPurchaseService {
|
||||||
productDetailResponse.productDetails.isEmpty) {
|
productDetailResponse.productDetails.isEmpty) {
|
||||||
Analytics.buyError(
|
Analytics.buyError(
|
||||||
dto,
|
dto,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
data: {
|
data: {
|
||||||
'msg': 'cant get product details ${productDetailResponse.error}',
|
'msg': 'cant get product details ${productDetailResponse.error}',
|
||||||
'not_found': productDetailResponse.notFoundIDs.join(','),
|
'not_found': productDetailResponse.notFoundIDs.join(','),
|
||||||
|
|
@ -134,7 +141,7 @@ class InAppPurchaseService {
|
||||||
return productDetailResponse.productDetails;
|
return productDetailResponse.productDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> buyItemInStore(ProductDetails product) async {
|
Future<bool> _buyItemInStore(ProductDetails product) async {
|
||||||
final PurchaseParam purchaseParam = PurchaseParam(productDetails: product);
|
final PurchaseParam purchaseParam = PurchaseParam(productDetails: product);
|
||||||
return InAppPurchase.instance
|
return InAppPurchase.instance
|
||||||
.buyNonConsumable(purchaseParam: purchaseParam);
|
.buyNonConsumable(purchaseParam: purchaseParam);
|
||||||
|
|
@ -152,7 +159,7 @@ class PurchaseDetailsStreamSubscription {
|
||||||
try {
|
try {
|
||||||
Analytics.buyEvent(
|
Analytics.buyEvent(
|
||||||
null,
|
null,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
message: 'onPurchased',
|
message: 'onPurchased',
|
||||||
data: {
|
data: {
|
||||||
'status': purchaseDetails.status.name,
|
'status': purchaseDetails.status.name,
|
||||||
|
|
@ -163,12 +170,12 @@ class PurchaseDetailsStreamSubscription {
|
||||||
final result = await locator.repository.checkPayment(
|
final result = await locator.repository.checkPayment(
|
||||||
purchaseDetails.productID,
|
purchaseDetails.productID,
|
||||||
purchaseDetails.verificationData.serverVerificationData,
|
purchaseDetails.verificationData.serverVerificationData,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
Analytics.buyComplete(
|
Analytics.buyComplete(
|
||||||
null,
|
null,
|
||||||
PaymentSystem.google,
|
androidPaymentSystem,
|
||||||
message: purchaseDetails.productID,
|
message: purchaseDetails.productID,
|
||||||
);
|
);
|
||||||
log('Purchased');
|
log('Purchased');
|
||||||
|
|
|
||||||
50
lib/features/purchase/rustore/mnemo_rustore.dart
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import 'package:flutter_rustore_billing/flutter_rustore_billing.dart';
|
||||||
|
import 'package:mnemo_cards/flags.dart';
|
||||||
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
|
||||||
|
import '../../../di/locator.dart';
|
||||||
|
|
||||||
|
class RustorePurchaseService {
|
||||||
|
Future<bool> init() async {
|
||||||
|
return RustoreBillingClient.initialize(
|
||||||
|
"2063563896",
|
||||||
|
"mnemocards://iamback",
|
||||||
|
true,
|
||||||
|
).then((value) {
|
||||||
|
print("initialize success: $value");
|
||||||
|
return true;
|
||||||
|
}, onError: (err) {
|
||||||
|
print("initialize err: $err");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> buyPack(CardPackBuyDto dto) async {
|
||||||
|
if (dto.rustoreId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!await init()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final product = (await RustoreBillingClient.products([dto.rustoreId]))
|
||||||
|
.products
|
||||||
|
.firstOrNull;
|
||||||
|
if (product == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final result = await RustoreBillingClient.purchase(dto.rustoreId!, null);
|
||||||
|
if (result.successPurchase == null && result.successInvoice == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result.successPurchase != null) {
|
||||||
|
final purchase = result.successPurchase!;
|
||||||
|
final success = await locator.repository.checkPayment(
|
||||||
|
purchase.productId,
|
||||||
|
purchase.subscriptionToken ?? '',
|
||||||
|
androidPaymentSystem,
|
||||||
|
);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,10 @@ import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/utils/color_helper.dart';
|
import 'package:mnemo_cards/utils/color_helper.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
import '../../di/locator.dart';
|
import '../../di/locator.dart';
|
||||||
import '../../widgets/big_back_button.dart';
|
|
||||||
import '../../widgets/horizontal_progress.dart';
|
|
||||||
import 'question_states/test_question_state.dart';
|
import 'question_states/test_question_state.dart';
|
||||||
|
|
||||||
class TestCompleteWidget extends StatelessWidget {
|
class TestCompleteWidget extends StatelessWidget {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
import 'package:mnemo_cards/main.dart';
|
import 'package:mnemo_cards/main.dart';
|
||||||
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
const ADMIN_BUILD = false;
|
const ADMIN_BUILD = CommonPrefs.ADMIN_BUILD;
|
||||||
|
const RUSTORE_BUILD = CommonPrefs.RUSTORE_BUILD;
|
||||||
|
|
||||||
|
final androidPaymentSystem = CommonPrefs.androidPaymentSystem;
|
||||||
|
|
||||||
bool get SHOW_ADMIN =>
|
bool get SHOW_ADMIN =>
|
||||||
ADMIN_BUILD && (globalSharedPreferences.getBool('show_admin') ?? false);
|
ADMIN_BUILD && (globalSharedPreferences.getBool('show_admin') ?? true);
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,17 @@ class MyApp extends StatelessWidget with WidgetsBindingObserver {
|
||||||
theme: theme2,
|
theme: theme2,
|
||||||
darkTheme: darkTheme2,
|
darkTheme: darkTheme2,
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
routerConfig: appRouter.config(),
|
routerConfig: appRouter.config(
|
||||||
|
deepLinkBuilder: (link) {
|
||||||
|
// if(link.path.contains('/ru/reset-password')) {
|
||||||
|
// return const DeepLink(
|
||||||
|
// [ResetPassRoute()]
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
return DeepLink.defaultPath;
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
),
|
||||||
scaffoldMessengerKey: scaffoldMessengerKey,
|
scaffoldMessengerKey: scaffoldMessengerKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
);
|
);
|
||||||
|
|
@ -199,6 +209,13 @@ class _MainTabsPageState extends State<MainTabsPage> {
|
||||||
|
|
||||||
_Tabs _currentTab = _Tabs.home;
|
_Tabs _currentTab = _Tabs.home;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
print('CHANGE DEPS');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
|
||||||
|
|
@ -171,5 +171,3 @@ class UserManager {
|
||||||
_subscription = null;
|
_subscription = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ExternalIdType { google, device }
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class AuthPage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (ADMIN_BUILD)
|
if (ADMIN_BUILD)
|
||||||
SharedPrefButton<bool>(
|
MobileSharedPrefButton<bool>(
|
||||||
builder: (v, _) => (v ?? false) ? Text('PROD') : Text('TEST'),
|
builder: (v, _) => (v ?? false) ? Text('PROD') : Text('TEST'),
|
||||||
spKey: 'env',
|
spKey: 'env',
|
||||||
setOnTap: (v) => !(v ?? false),
|
setOnTap: (v) => !(v ?? false),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import 'package:mnemo_cards/domain/router/app_router.dart';
|
||||||
import 'package:mnemo_cards/domain/router/app_router.gr.dart';
|
import 'package:mnemo_cards/domain/router/app_router.gr.dart';
|
||||||
import 'package:mnemo_cards/flags.dart';
|
import 'package:mnemo_cards/flags.dart';
|
||||||
import 'package:mnemo_cards/main.dart';
|
import 'package:mnemo_cards/main.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
|
@ -16,11 +16,8 @@ import '../admin/all_users.dart';
|
||||||
import '../di/locator.dart';
|
import '../di/locator.dart';
|
||||||
import '../features/analytics/analytics.dart';
|
import '../features/analytics/analytics.dart';
|
||||||
import '../theme/themes.dart';
|
import '../theme/themes.dart';
|
||||||
import '../widgets/big_back_button.dart';
|
|
||||||
import '../widgets/enter_promo_code_widget.dart';
|
import '../widgets/enter_promo_code_widget.dart';
|
||||||
import '../widgets/shared_pref_button.dart';
|
import '../widgets/shared_pref_button.dart';
|
||||||
import '../widgets/simple_tile.dart';
|
|
||||||
import '../widgets/user_statistics.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ProfilePage extends StatelessWidget {
|
class ProfilePage extends StatelessWidget {
|
||||||
|
|
@ -106,7 +103,7 @@ class ProfilePage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SharedPrefButton<bool>(
|
child: MobileSharedPrefButton<bool>(
|
||||||
builder: (v, _) =>
|
builder: (v, _) =>
|
||||||
(v ?? false) ? Text('PROD') : Text('TEST'),
|
(v ?? false) ? Text('PROD') : Text('TEST'),
|
||||||
spKey: 'env',
|
spKey: 'env',
|
||||||
|
|
@ -140,7 +137,7 @@ class ProfilePage extends StatelessWidget {
|
||||||
height: 5,
|
height: 5,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
const EnterPromoCodeWidget(),
|
const MobileEnterPromoCodeWidget(),
|
||||||
Divider(
|
Divider(
|
||||||
height: 5,
|
height: 5,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,14 @@ import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/flags.dart';
|
import 'package:mnemo_cards/flags.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../di/locator.dart';
|
import '../di/locator.dart';
|
||||||
import '../features/analytics/analytics.dart';
|
import '../features/analytics/analytics.dart';
|
||||||
import '../theme/themes.dart';
|
import '../theme/themes.dart';
|
||||||
import '../widgets/big_back_button.dart';
|
|
||||||
import '../widgets/shared_pref_button.dart';
|
import '../widgets/shared_pref_button.dart';
|
||||||
import '../widgets/simple_tile.dart';
|
|
||||||
import '../widgets/slider.dart';
|
|
||||||
import '../widgets/switch_tile.dart';
|
|
||||||
import '../widgets/text_button.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
|
|
@ -45,7 +40,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
height: 1,
|
height: 1,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
SharedPrefButton<bool>.builder(
|
MobileSharedPrefButton<bool>.builder(
|
||||||
spKey: 'dark_theme',
|
spKey: 'dark_theme',
|
||||||
builder: (enabled, _) => AbsorbPointer(
|
builder: (enabled, _) => AbsorbPointer(
|
||||||
child: SwitchTile(
|
child: SwitchTile(
|
||||||
|
|
@ -64,7 +59,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
height: 1,
|
height: 1,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
SharedPrefButton<bool>.builder(
|
MobileSharedPrefButton<bool>.builder(
|
||||||
spKey: 'sound_on',
|
spKey: 'sound_on',
|
||||||
builder: (enabled, _) => AbsorbPointer(
|
builder: (enabled, _) => AbsorbPointer(
|
||||||
child: SwitchTile(
|
child: SwitchTile(
|
||||||
|
|
@ -78,7 +73,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
height: 1,
|
height: 1,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
SharedPrefButton<bool>.builder(
|
MobileSharedPrefButton<bool>.builder(
|
||||||
spKey: 'auto_play_sound_view',
|
spKey: 'auto_play_sound_view',
|
||||||
builder: (enabled, _) => AbsorbPointer(
|
builder: (enabled, _) => AbsorbPointer(
|
||||||
child: SwitchTile(
|
child: SwitchTile(
|
||||||
|
|
@ -92,7 +87,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
height: 1,
|
height: 1,
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
SharedPrefButton<bool>.builder(
|
MobileSharedPrefButton<bool>.builder(
|
||||||
spKey: 'auto_play_sound_tests',
|
spKey: 'auto_play_sound_tests',
|
||||||
builder: (enabled, _) => AbsorbPointer(
|
builder: (enabled, _) => AbsorbPointer(
|
||||||
child: SwitchTile(
|
child: SwitchTile(
|
||||||
|
|
@ -108,7 +103,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
SimpleTile.text(
|
SimpleTile.text(
|
||||||
text: 'Скорость чтения',
|
text: 'Скорость чтения',
|
||||||
trail: SharedPrefButton<double>.builder(
|
trail: MobileSharedPrefButton<double>.builder(
|
||||||
spKey: 'sound_speed',
|
spKey: 'sound_speed',
|
||||||
builder: (v, s) => MnemoSlider(
|
builder: (v, s) => MnemoSlider(
|
||||||
onChanged: (value) => s(value),
|
onChanged: (value) => s(value),
|
||||||
|
|
@ -122,7 +117,7 @@ class SettingsPage extends StatelessWidget {
|
||||||
color: borderGray.withOpacity(0.2),
|
color: borderGray.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
if (ADMIN_BUILD)
|
if (ADMIN_BUILD)
|
||||||
SharedPrefButton<bool>.builder(
|
MobileSharedPrefButton<bool>.builder(
|
||||||
spKey: 'show_admin',
|
spKey: 'show_admin',
|
||||||
builder: (enabled, _) => AbsorbPointer(
|
builder: (enabled, _) => AbsorbPointer(
|
||||||
child: SwitchTile(
|
child: SwitchTile(
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:mnemo_cards/main.dart';
|
|
||||||
|
|
||||||
import '../theme/themes.dart';
|
|
||||||
|
|
||||||
class BigBackButton extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.0.w, vertical: 10.0.h),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: appRouter.maybePop,
|
|
||||||
child: Container(
|
|
||||||
height: 90.h,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
border: Border.all(color: borderGray),
|
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.all(10.0.w),
|
|
||||||
child: Text(
|
|
||||||
'Назад',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25.sp,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 0.85,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const BigBackButton();
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../../features/card_swiper/src/card_swiper_controller.dart';
|
import '../../features/card_swiper/src/card_swiper_controller.dart';
|
||||||
import '../header.dart';
|
|
||||||
|
|
||||||
class CardGameHeader extends StatelessWidget {
|
class CardGameHeader extends StatelessWidget {
|
||||||
final CardSwiperController controller;
|
final CardSwiperController controller;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/main.dart';
|
import 'package:mnemo_cards/main.dart';
|
||||||
import 'package:mnemo_cards/widgets/fade_in_widget.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:yandex_mobileads/mobile_ads.dart';
|
import 'package:yandex_mobileads/mobile_ads.dart';
|
||||||
import '../../domain/router/app_router.gr.dart';
|
import '../../domain/router/app_router.gr.dart';
|
||||||
import '../../features/analytics/analytics.dart';
|
import '../../features/analytics/analytics.dart';
|
||||||
|
|
@ -14,7 +14,6 @@ import '../../features/yandex_ads/yandex_ads.dart';
|
||||||
|
|
||||||
import '../../di/locator.dart';
|
import '../../di/locator.dart';
|
||||||
import '../../theme/themes.dart';
|
import '../../theme/themes.dart';
|
||||||
import '../horizontal_progress.dart';
|
|
||||||
import 'card_pack_header.dart';
|
import 'card_pack_header.dart';
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
import 'package:mnemo_cards/flags.dart';
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
@ -164,7 +165,7 @@ class _BuyButton extends StatelessWidget {
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (locator.userManager.hasUser) {
|
if (locator.userManager.hasUser) {
|
||||||
Analytics.buyPackPressed(dto, PaymentSystem.google);
|
Analytics.buyPackPressed(dto, androidPaymentSystem);
|
||||||
final result = await locator.purchaseService.buyPack(dto);
|
final result = await locator.purchaseService.buyPack(dto);
|
||||||
if (result) {
|
if (result) {
|
||||||
_updatePack();
|
_updatePack();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||||||
import '../header.dart';
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
class CardPackHeader extends StatelessWidget {
|
class CardPackHeader extends StatelessWidget {
|
||||||
final String? title;
|
final String? title;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/features/packs/images_holder.dart';
|
import 'package:mnemo_cards/features/packs/images_holder.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart'
|
||||||
|
as frontend;
|
||||||
import 'package:reorderables/reorderables.dart';
|
import 'package:reorderables/reorderables.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
import '../../utils/string_helper.dart';
|
import '../../utils/string_helper.dart';
|
||||||
import '../../domain/router/app_router.gr.dart';
|
import '../../domain/router/app_router.gr.dart';
|
||||||
import '../../main.dart';
|
import '../../main.dart';
|
||||||
import '../feedback_builder.dart';
|
|
||||||
import '../game_card_widget.dart';
|
import '../game_card_widget.dart';
|
||||||
import 'cards_view_controller.dart';
|
import 'cards_view_controller.dart';
|
||||||
|
|
||||||
|
|
@ -157,7 +157,8 @@ class _CardsViewState extends State<CardsView>
|
||||||
onReorder: (int from, int to) {
|
onReorder: (int from, int to) {
|
||||||
controller.onOrderChanged(from, to);
|
controller.onOrderChanged(from, to);
|
||||||
},
|
},
|
||||||
buildDraggableFeedback: FeedbackBuilder.simple,
|
buildDraggableFeedback:
|
||||||
|
frontend.FeedbackBuilder.simple,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: (cardWidth - imageWidth - 1),
|
horizontal: (cardWidth - imageWidth - 1),
|
||||||
vertical: (cardWidth - imageWidth - 1),
|
vertical: (cardWidth - imageWidth - 1),
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,21 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:mnemo_cards/di/locator.dart';
|
|
||||||
import 'package:mnemo_cards/theme/themes.dart';
|
|
||||||
import 'package:mnemo_cards/widgets/simple_tile.dart';
|
|
||||||
|
|
||||||
class EnterPromoCodeWidget extends StatefulWidget {
|
import '../di/locator.dart';
|
||||||
const EnterPromoCodeWidget();
|
|
||||||
|
|
||||||
@override
|
class MobileEnterPromoCodeWidget extends StatelessWidget {
|
||||||
State<StatefulWidget> createState() => _EnterPromoCodeState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EnterPromoCodeState extends State<EnterPromoCodeWidget> {
|
|
||||||
final TextEditingController controller = TextEditingController();
|
|
||||||
|
|
||||||
String? message;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return EnterPromoCodeWidget(onApplyPromoCode: onApplyPromoCode);
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
SimpleTile(
|
|
||||||
title: Row(
|
|
||||||
children: [
|
|
||||||
Text('Промокод'),
|
|
||||||
SizedBox(
|
|
||||||
width: 16.w,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: TextField(
|
|
||||||
// cursorHeight: 17.h,
|
|
||||||
controller: controller,
|
|
||||||
textAlignVertical: TextAlignVertical.center,
|
|
||||||
style: TextStyle(fontSize: 17.sp),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
contentPadding: EdgeInsets.all(8.0),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 8.w,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
trail: GestureDetector(
|
|
||||||
onTap: () async {
|
|
||||||
final result = await locator.userManager.applyPromocode(
|
|
||||||
controller.text,
|
|
||||||
);
|
|
||||||
if (result.success == true) {
|
|
||||||
controller.clear();
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
message = result.message;
|
|
||||||
});
|
|
||||||
FocusScope.of(context).unfocus();
|
|
||||||
},
|
|
||||||
child: AspectRatio(
|
|
||||||
aspectRatio: 1.0,
|
|
||||||
child: Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: progressBlue,
|
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
|
||||||
),
|
|
||||||
child: Image.asset(
|
|
||||||
'icons/gift.png',
|
|
||||||
width: 17.w,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (message != null && message!.isNotEmpty)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
|
||||||
child: Text(message!),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Future<(bool, String?)> onApplyPromoCode(String code) async {
|
||||||
|
final result = await locator.userManager.applyPromocode(code);
|
||||||
|
return (result.success ?? false, result.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MobileEnterPromoCodeWidget();
|
||||||
|
}
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
|
|
||||||
class FadeInWidget extends StatelessWidget {
|
|
||||||
final Widget child;
|
|
||||||
final Duration? delay;
|
|
||||||
final Future? future;
|
|
||||||
final Duration animationDuration;
|
|
||||||
|
|
||||||
FadeInWidget({
|
|
||||||
required this.child,
|
|
||||||
this.delay = const Duration(milliseconds: 200),
|
|
||||||
this.future,
|
|
||||||
this.animationDuration = const Duration(milliseconds: 200),
|
|
||||||
super.key,
|
|
||||||
}) : assert(future != null || delay != null);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return FutureBuilder(
|
|
||||||
future: future ?? Future.delayed(delay!),
|
|
||||||
builder: (context, s) {
|
|
||||||
return AnimatedOpacity(
|
|
||||||
duration: animationDuration,
|
|
||||||
opacity: s.connectionState == ConnectionState.done ? 1.0 : 0.0,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class FeedbackBuilder {
|
|
||||||
static Widget tests(Widget child, int index, Animation<double> animation) =>
|
|
||||||
Transform(
|
|
||||||
transform: new Matrix4.rotationZ(0),
|
|
||||||
child: Material(
|
|
||||||
child: child,
|
|
||||||
elevation: 1.0,
|
|
||||||
color: Colors.transparent,
|
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
static Widget simple(
|
|
||||||
BuildContext context,
|
|
||||||
BoxConstraints constraints,
|
|
||||||
Widget child,
|
|
||||||
) {
|
|
||||||
return Transform(
|
|
||||||
transform: new Matrix4.rotationZ(0.05),
|
|
||||||
// alignment: FractionalOffset.topLeft,
|
|
||||||
child: Material(
|
|
||||||
child: child,
|
|
||||||
elevation: 6.0,
|
|
||||||
color: Colors.transparent,
|
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,14 +7,13 @@ import 'package:mnemo_cards/features/yandex_ads/yandex_ads.dart';
|
||||||
import 'package:mnemo_cards/managers/audio_player.dart';
|
import 'package:mnemo_cards/managers/audio_player.dart';
|
||||||
import 'package:mnemo_cards/utils/color_helper.dart';
|
import 'package:mnemo_cards/utils/color_helper.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:yandex_mobileads/mobile_ads.dart';
|
import 'package:yandex_mobileads/mobile_ads.dart';
|
||||||
|
|
||||||
import '../features/card_flipper/flip_card.dart';
|
import '../features/card_flipper/flip_card.dart';
|
||||||
import '../features/card_flipper/flip_card_controllers.dart';
|
import '../features/card_flipper/flip_card_controllers.dart';
|
||||||
import '../features/card_flipper/flip_side.dart';
|
import '../features/card_flipper/flip_side.dart';
|
||||||
import '../theme/themes.dart';
|
import '../theme/themes.dart';
|
||||||
import 'image_fade.dart';
|
|
||||||
import 'mnemo_text.dart';
|
|
||||||
|
|
||||||
class GameCardWidget extends StatefulWidget {
|
class GameCardWidget extends StatefulWidget {
|
||||||
static const borderRadius = 32.0;
|
static const borderRadius = 32.0;
|
||||||
|
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
|
|
||||||
class Header extends StatelessWidget {
|
|
||||||
final String? title;
|
|
||||||
final String? subtitle;
|
|
||||||
|
|
||||||
final bool hasPopButton;
|
|
||||||
final String? popText;
|
|
||||||
final Widget? trail;
|
|
||||||
final Color? color;
|
|
||||||
|
|
||||||
Header(
|
|
||||||
this.title, {
|
|
||||||
this.subtitle,
|
|
||||||
this.hasPopButton = false,
|
|
||||||
this.popText,
|
|
||||||
this.trail,
|
|
||||||
this.color,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final topPadding = 74.h -
|
|
||||||
MediaQuery.of(context).padding.top -
|
|
||||||
(hasPopButton ? 30.0.h : 0.0);
|
|
||||||
return Container(
|
|
||||||
color: color,
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
height: max(
|
|
||||||
topPadding / 2,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (hasPopButton)
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(left: 10.0.w),
|
|
||||||
child: TapRegion(
|
|
||||||
onTapInside: AutoRouter.of(context).maybePop,
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 30.h,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Image.asset(
|
|
||||||
'icons/back.png',
|
|
||||||
color:
|
|
||||||
Theme.of(context).buttonTheme.colorScheme!.primary,
|
|
||||||
width: 17,
|
|
||||||
height: 23.h,
|
|
||||||
),
|
|
||||||
if (popText != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 4.0),
|
|
||||||
child: Text(
|
|
||||||
popText!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: max(
|
|
||||||
topPadding / 2,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(left: 20.0.w, right: 24.w),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
if (title != null)
|
|
||||||
Text(
|
|
||||||
title!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 36.sp,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 0.85,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.start,
|
|
||||||
),
|
|
||||||
if (trail != null) trail!,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (subtitle != null)
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(top: 4.0.h, left: 22.0.w, bottom: 4.0.h),
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Text(
|
|
||||||
subtitle!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20.sp,
|
|
||||||
fontWeight: FontWeight.w300,
|
|
||||||
height: 0.85,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
|
|
||||||
import '../theme/themes.dart';
|
|
||||||
|
|
||||||
class HorizontalProgressWidget extends StatelessWidget {
|
|
||||||
final int value;
|
|
||||||
final int length;
|
|
||||||
final Color color;
|
|
||||||
final Color? borderColor;
|
|
||||||
final double? height;
|
|
||||||
|
|
||||||
HorizontalProgressWidget(
|
|
||||||
this.value,
|
|
||||||
this.length,
|
|
||||||
this.color, {
|
|
||||||
this.borderColor,
|
|
||||||
this.height,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
height: height ?? 16.h,
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: white,
|
|
||||||
border: borderColor != null ? Border.all(color: borderColor!) : null,
|
|
||||||
borderRadius: BorderRadius.circular(16.h),
|
|
||||||
),
|
|
||||||
child: AnimatedFractionallySizedBox(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
widthFactor: length == 0 ? 0 : value.toDouble() / length,
|
|
||||||
duration: Duration(milliseconds: 600),
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(16.h),
|
|
||||||
color: color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,356 +0,0 @@
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'dart:ui' as ui;
|
|
||||||
|
|
||||||
/// Signature used by [ImageFade.errorBuilder] to build the widget that will be displayed
|
|
||||||
/// if an error occurs while loading an image.
|
|
||||||
typedef ImageFadeErrorBuilder = Widget Function(
|
|
||||||
BuildContext context,
|
|
||||||
Object exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Signature used by [ImageFade.loadingBuilder] to build the widget that will be displayed
|
|
||||||
/// while an image is loading. `progress` returns a value between 0 and 1 indicating load progress.
|
|
||||||
typedef ImageFadeLoadingBuilder = Widget Function(
|
|
||||||
BuildContext context,
|
|
||||||
double progress,
|
|
||||||
ImageChunkEvent? chunkEvent,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// A widget that displays a [placeholder] widget while a specified [image] loads,
|
|
||||||
/// then cross-fades to the loaded image. Can optionally display loading progress
|
|
||||||
/// and errors.
|
|
||||||
///
|
|
||||||
/// If [image] is subsequently changed, it will cross-fade to the new image once it
|
|
||||||
/// finishes loading.
|
|
||||||
///
|
|
||||||
/// Setting [image] to null will cross-fade back to the [placeholder].
|
|
||||||
///
|
|
||||||
/// ```dart
|
|
||||||
/// ImageFade(
|
|
||||||
/// placeholder: Image.asset('assets/myPlaceholder.png'),
|
|
||||||
/// image: NetworkImage('https://backend.example.com/image.png'),
|
|
||||||
/// )
|
|
||||||
/// ```
|
|
||||||
class ImageFade extends StatefulWidget {
|
|
||||||
/// Creates a widget that displays a [placeholder] widget while a specified [image] loads,
|
|
||||||
/// then cross-fades to the loaded image.
|
|
||||||
const
|
|
||||||
ImageFade({
|
|
||||||
Key? key,
|
|
||||||
this.placeholder,
|
|
||||||
this.image,
|
|
||||||
this.curve = Curves.linear,
|
|
||||||
this.duration = const Duration(milliseconds: 300),
|
|
||||||
this.syncDuration,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.scale = 1,
|
|
||||||
this.fit = BoxFit.scaleDown,
|
|
||||||
this.alignment = Alignment.center,
|
|
||||||
this.repeat = ImageRepeat.noRepeat,
|
|
||||||
this.matchTextDirection = false,
|
|
||||||
this.excludeFromSemantics = false,
|
|
||||||
this.semanticLabel,
|
|
||||||
this.loadingBuilder,
|
|
||||||
this.errorBuilder,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
/// Widget layered behind the loaded images. Displayed when [image] is null or is loading initially.
|
|
||||||
final Widget? placeholder;
|
|
||||||
|
|
||||||
/// The image to display. Subsequently changing the image will fade the new image over the previous one.
|
|
||||||
final ImageProvider? image;
|
|
||||||
|
|
||||||
/// The curve of the fade-in animation.
|
|
||||||
final Curve curve;
|
|
||||||
|
|
||||||
/// The duration of the fade-in animation.
|
|
||||||
final Duration duration;
|
|
||||||
|
|
||||||
/// An optional duration for fading in a synchronously loaded image (ex. from memory), error, or placeholder.
|
|
||||||
/// For example, you could set this to `Duration.zero` to immediately display images that are already loaded.
|
|
||||||
/// If omitted, [duration] will be used.
|
|
||||||
final Duration? syncDuration;
|
|
||||||
|
|
||||||
/// The width to display at. See [Image.width] for more information.
|
|
||||||
final double? width;
|
|
||||||
|
|
||||||
/// The height to display at. See [Image.height] for more information.
|
|
||||||
final double? height;
|
|
||||||
|
|
||||||
/// The scale factor for drawing this image at its intended size. See [RawImage.scale] for more information.
|
|
||||||
final double scale;
|
|
||||||
|
|
||||||
/// How to draw the image within its bounds. Defaults to [BoxFit.scaleDown]. See [Image.fit] for more information.
|
|
||||||
final BoxFit fit;
|
|
||||||
|
|
||||||
/// How to align the image within its bounds. See [Image.alignment] for more information.
|
|
||||||
final Alignment alignment;
|
|
||||||
|
|
||||||
/// How to paint any portions of the layout bounds not covered by the image. See [Image.repeat] for more information.
|
|
||||||
final ImageRepeat repeat;
|
|
||||||
|
|
||||||
/// Whether to paint the image in the direction of the [TextDirection]. See [Image.matchTextDirection] for more information.
|
|
||||||
final bool matchTextDirection;
|
|
||||||
|
|
||||||
/// Whether to exclude this image from semantics. See [Image.excludeFromSemantics] for more information.
|
|
||||||
final bool excludeFromSemantics;
|
|
||||||
|
|
||||||
/// A Semantic description of the image. See [Image.semanticLabel] for more information.
|
|
||||||
final String? semanticLabel;
|
|
||||||
|
|
||||||
/// A builder that specifies the widget to display while an image is loading.
|
|
||||||
/// See [ImageFadeLoadingBuilder] for more information.
|
|
||||||
final ImageFadeLoadingBuilder? loadingBuilder;
|
|
||||||
|
|
||||||
/// A builder that specifies the widget to display if an error occurs while an image is loading.
|
|
||||||
/// This will be faded in over previous content, so you may want to set an opaque background on it.
|
|
||||||
final ImageFadeErrorBuilder? errorBuilder;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _ImageFadeState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ImageFadeState extends State<ImageFade> with TickerProviderStateMixin {
|
|
||||||
_ImageResolver? _resolver;
|
|
||||||
Widget? _front;
|
|
||||||
Widget? _back;
|
|
||||||
|
|
||||||
late final AnimationController _controller;
|
|
||||||
Widget? _fadeFront;
|
|
||||||
Widget? _fadeBack;
|
|
||||||
|
|
||||||
bool? _sync; // could use onImage synchronousCall, but this is more forgiving
|
|
||||||
bool _shouldBuildFront = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_controller = AnimationController(vsync: this);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
// Can't call this in initState because createLocalImageConfiguration throws errors:
|
|
||||||
_update(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(ImageFade old) {
|
|
||||||
// not called on init
|
|
||||||
super.didUpdateWidget(old);
|
|
||||||
_update(context, old);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _update(BuildContext context, [ImageFade? old]) {
|
|
||||||
final ImageProvider? image = widget.image;
|
|
||||||
final ImageProvider? oldImage = old?.image;
|
|
||||||
if (image == oldImage) return;
|
|
||||||
|
|
||||||
_back = null;
|
|
||||||
_shouldBuildFront = false;
|
|
||||||
|
|
||||||
if (_resolver != null) {
|
|
||||||
// move previous loaded image to back & cancel any active loads.
|
|
||||||
if (_resolver!.complete) _back = _fadeBack = _front;
|
|
||||||
_resolver!.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the new image:
|
|
||||||
_front = _sync = null;
|
|
||||||
_resolver = image == null
|
|
||||||
? null
|
|
||||||
: _ImageResolver(
|
|
||||||
image,
|
|
||||||
context,
|
|
||||||
onError: _handleComplete,
|
|
||||||
onComplete: _handleComplete,
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
);
|
|
||||||
|
|
||||||
// start transition to placeholder if there's no new image:
|
|
||||||
if (_back != null && _resolver == null) _buildTransition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleComplete(_ImageResolver resolver) {
|
|
||||||
if (_sync == null) _sync = true;
|
|
||||||
// defer building the front content until build so we have an active context.
|
|
||||||
setState(() => _shouldBuildFront = true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _buildFront(BuildContext context) {
|
|
||||||
_shouldBuildFront = false;
|
|
||||||
_ImageResolver resolver = _resolver!;
|
|
||||||
_front = resolver.error
|
|
||||||
? widget.errorBuilder?.call(context, resolver.exception!)
|
|
||||||
: _getImage(resolver.image);
|
|
||||||
_buildTransition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _buildTransition() {
|
|
||||||
final bool out = _front == null; // no new image
|
|
||||||
|
|
||||||
// use the "fast" duration if sync load, error, or placeholder:
|
|
||||||
bool fast = (_sync != false || _resolver?.error == true || out);
|
|
||||||
Duration duration = (fast ? widget.syncDuration : null) ?? widget.duration;
|
|
||||||
|
|
||||||
// Fade in for duration, out for 1/2 as long:
|
|
||||||
_controller.duration = duration * (out ? 1 : 3 / 2);
|
|
||||||
|
|
||||||
_fadeFront = _buildFade(
|
|
||||||
child: _front,
|
|
||||||
opacity: CurvedAnimation(
|
|
||||||
parent: _controller,
|
|
||||||
curve: Interval(0.0, 2 / 3, curve: widget.curve),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
_fadeBack = _buildFade(
|
|
||||||
child: _back,
|
|
||||||
opacity: Tween<double>(begin: 1.0, end: 0).animate(
|
|
||||||
CurvedAnimation(
|
|
||||||
parent: _controller,
|
|
||||||
curve: Interval(out ? 0.0 : 2 / 3, 1.0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (_front != null || _back != null) _controller.forward(from: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget? _buildFade({Widget? child, required Animation<double> opacity}) {
|
|
||||||
if (child == null) return null;
|
|
||||||
// if the child is a loaded image, we can fade its opacity directly for better performance:
|
|
||||||
return (child is RawImage)
|
|
||||||
? _getImage(child.image, opacity: opacity)
|
|
||||||
: FadeTransition(child: child, opacity: opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawImage _getImage(ui.Image? image, {Animation<double>? opacity}) {
|
|
||||||
return RawImage(
|
|
||||||
image: image,
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
scale: widget.scale,
|
|
||||||
fit: widget.fit,
|
|
||||||
alignment: widget.alignment,
|
|
||||||
repeat: widget.repeat,
|
|
||||||
matchTextDirection: widget.matchTextDirection,
|
|
||||||
opacity: opacity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (_sync == null) _sync = false;
|
|
||||||
if (_shouldBuildFront) _buildFront(context);
|
|
||||||
Widget? front = _fadeFront, back = _fadeBack;
|
|
||||||
|
|
||||||
bool inLoad = _resolver != null && !_resolver!.complete;
|
|
||||||
if (inLoad && widget.loadingBuilder != null) {
|
|
||||||
_ImageResolver resolver = _resolver!;
|
|
||||||
front = AnimatedBuilder(
|
|
||||||
animation: resolver.notifier,
|
|
||||||
builder: (_, __) => widget.loadingBuilder!(
|
|
||||||
context,
|
|
||||||
resolver.notifier.value,
|
|
||||||
resolver.chunkEvent,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> kids = [];
|
|
||||||
if (widget.placeholder != null) kids.add(widget.placeholder!);
|
|
||||||
if (back != null) kids.add(back);
|
|
||||||
if (front != null) kids.add(front);
|
|
||||||
|
|
||||||
Widget content = Container(
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
child: kids.isEmpty
|
|
||||||
? null
|
|
||||||
: Stack(fit: StackFit.passthrough, children: kids),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (widget.excludeFromSemantics) return content;
|
|
||||||
|
|
||||||
String? label = widget.semanticLabel;
|
|
||||||
return Semantics(
|
|
||||||
container: label != null,
|
|
||||||
image: true,
|
|
||||||
label: label ?? "",
|
|
||||||
child: content,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_resolver?.dispose();
|
|
||||||
_controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplifies working with image loading events and states.
|
|
||||||
class _ImageResolver {
|
|
||||||
_ImageResolver(
|
|
||||||
ImageProvider provider,
|
|
||||||
BuildContext context, {
|
|
||||||
required this.onComplete,
|
|
||||||
required this.onError,
|
|
||||||
double? width,
|
|
||||||
double? height,
|
|
||||||
}) {
|
|
||||||
Size? size = width != null && height != null ? Size(width, height) : null;
|
|
||||||
ImageConfiguration config =
|
|
||||||
createLocalImageConfiguration(context, size: size);
|
|
||||||
_listener = ImageStreamListener(_handleComplete,
|
|
||||||
onChunk: _handleProgress, onError: _handleError);
|
|
||||||
_stream = provider.resolve(config);
|
|
||||||
_stream.addListener(_listener); // Called sync if already completed.
|
|
||||||
notifier = ValueNotifier(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object? exception;
|
|
||||||
ImageChunkEvent? chunkEvent;
|
|
||||||
late final ValueNotifier<double> notifier;
|
|
||||||
|
|
||||||
final Function(_ImageResolver resolver) onComplete;
|
|
||||||
final Function(_ImageResolver resolver) onError;
|
|
||||||
|
|
||||||
late final ImageStream _stream;
|
|
||||||
late final ImageStreamListener _listener;
|
|
||||||
ImageInfo? _imageInfo;
|
|
||||||
bool _complete = false;
|
|
||||||
|
|
||||||
ui.Image? get image => _imageInfo?.image;
|
|
||||||
|
|
||||||
bool get complete => _complete;
|
|
||||||
|
|
||||||
bool get error => exception != null;
|
|
||||||
|
|
||||||
void _handleComplete(ImageInfo imageInfo, bool sync) {
|
|
||||||
_imageInfo = imageInfo;
|
|
||||||
_complete = true;
|
|
||||||
onComplete(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleProgress(ImageChunkEvent event) {
|
|
||||||
chunkEvent = event;
|
|
||||||
notifier.value = event.expectedTotalBytes != null
|
|
||||||
? event.cumulativeBytesLoaded / event.expectedTotalBytes!
|
|
||||||
: 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleError(Object exc, StackTrace? _) {
|
|
||||||
exception = exc;
|
|
||||||
_complete = true;
|
|
||||||
onError(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_stream.removeListener(_listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import 'package:auto_size_text/auto_size_text.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
|
||||||
|
|
||||||
class MnemoText extends StatelessWidget {
|
|
||||||
final String? mnemo;
|
|
||||||
final TextStyle? textStyle;
|
|
||||||
final TextAlign? textAlign;
|
|
||||||
final Color? color;
|
|
||||||
final AutoSizeGroup? group;
|
|
||||||
final int? maxLines;
|
|
||||||
final bool? softWrap;
|
|
||||||
|
|
||||||
const MnemoText(
|
|
||||||
this.mnemo, {
|
|
||||||
this.textStyle,
|
|
||||||
this.textAlign,
|
|
||||||
this.color,
|
|
||||||
this.group,
|
|
||||||
this.maxLines,
|
|
||||||
this.softWrap,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (mnemo == null) return SizedBox.shrink();
|
|
||||||
final matches = RegExp(r'\{(.*?)\}').allMatches(mnemo!);
|
|
||||||
Color? color = this.color;
|
|
||||||
color ??= Colors.red;
|
|
||||||
|
|
||||||
List<TextSpan> spans = [];
|
|
||||||
|
|
||||||
RegExpMatch? lastMatch;
|
|
||||||
|
|
||||||
for (final match in matches) {
|
|
||||||
var mnemoText = matches.isEmpty
|
|
||||||
? ''
|
|
||||||
: mnemo!
|
|
||||||
.substring(match.start, match.end)
|
|
||||||
.replaceAll(RegExp(r'[\}\{]'), '');
|
|
||||||
if (mnemoText.startsWith('#')) {
|
|
||||||
// #123456mnemo
|
|
||||||
color = mnemoText.substring(0, 7).asColor;
|
|
||||||
mnemoText = mnemoText.substring(7);
|
|
||||||
}
|
|
||||||
spans.addAll([
|
|
||||||
if (lastMatch == null)
|
|
||||||
TextSpan(text: mnemo!.substring(0, match.start), style: textStyle)
|
|
||||||
else
|
|
||||||
TextSpan(
|
|
||||||
text: mnemo!.substring(lastMatch.end, match.start),
|
|
||||||
style: textStyle),
|
|
||||||
TextSpan(
|
|
||||||
text: mnemoText,
|
|
||||||
style: textStyle?.copyWith(color: color) ?? TextStyle(color: color),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
lastMatch = match;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastMatch == null) {
|
|
||||||
spans.add(
|
|
||||||
TextSpan(text: mnemo, style: textStyle),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
spans.add(TextSpan(
|
|
||||||
text: mnemo!.substring(lastMatch.end),
|
|
||||||
style: textStyle,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return AutoSizeText.rich(
|
|
||||||
maxLines: maxLines,
|
|
||||||
softWrap: softWrap,
|
|
||||||
TextSpan(
|
|
||||||
children: spans,
|
|
||||||
),
|
|
||||||
textAlign: textAlign ?? TextAlign.center,
|
|
||||||
group: group,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,8 +7,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/features/packs/pack_manager.dart';
|
import 'package:mnemo_cards/features/packs/pack_manager.dart';
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
|
|
||||||
import '../di/locator.dart';
|
import '../di/locator.dart';
|
||||||
import '../domain/router/app_router.dart';
|
import '../domain/router/app_router.dart';
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,17 @@ import 'dart:async';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:mnemo_cards/main.dart';
|
import 'package:mnemo_cards/main.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class SharedPrefButton<T> extends StatefulWidget {
|
class MobileSharedPrefButton<T> extends StatelessWidget {
|
||||||
final Function(T)? onClick;
|
final Function(T)? onClick;
|
||||||
final String spKey;
|
final String spKey;
|
||||||
final T Function(T? current)? setOnTap;
|
final T Function(T? current)? setOnTap;
|
||||||
final bool Function(T? current)? shouldRebuild;
|
final bool Function(T? current)? shouldRebuild;
|
||||||
final Widget Function(T? value, ValueSetter<T> setValue)? builder;
|
final Widget Function(T? value, ValueSetter<T> setValue)? builder;
|
||||||
|
|
||||||
SharedPrefButton({
|
MobileSharedPrefButton({
|
||||||
this.builder,
|
this.builder,
|
||||||
required this.spKey,
|
required this.spKey,
|
||||||
this.setOnTap,
|
this.setOnTap,
|
||||||
|
|
@ -20,7 +21,7 @@ class SharedPrefButton<T> extends StatefulWidget {
|
||||||
this.shouldRebuild,
|
this.shouldRebuild,
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedPrefButton.builder({
|
MobileSharedPrefButton.builder({
|
||||||
this.builder,
|
this.builder,
|
||||||
required this.spKey,
|
required this.spKey,
|
||||||
this.setOnTap,
|
this.setOnTap,
|
||||||
|
|
@ -29,89 +30,12 @@ class SharedPrefButton<T> extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _SharedPrefButtonState<T>();
|
Widget build(BuildContext context) => SharedPrefButton(
|
||||||
}
|
sharedPreferences: globalSharedPreferences,
|
||||||
|
spKey: spKey,
|
||||||
class _SharedPrefButtonState<T> extends State<SharedPrefButton<T>> {
|
setOnTap: setOnTap,
|
||||||
SharedPreferences? _sp;
|
onClick: onClick,
|
||||||
T? value;
|
shouldRebuild: shouldRebuild,
|
||||||
|
builder: builder,
|
||||||
StreamSubscription? _streamSubscription;
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_streamSubscription?.cancel();
|
|
||||||
_streamSubscription = null;
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_sp = globalSharedPreferences;
|
|
||||||
value = valueFromSp;
|
|
||||||
_streamSubscription =
|
|
||||||
Stream.periodic(const Duration(milliseconds: 500), (_) => valueFromSp)
|
|
||||||
.distinct()
|
|
||||||
.listen((v) {
|
|
||||||
if (value != v) {
|
|
||||||
value = v;
|
|
||||||
if (mounted && widget.shouldRebuild?.call(value) != false) {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
T? get valueFromSp {
|
|
||||||
if (T == bool) {
|
|
||||||
return (_sp?.getBool(widget.spKey) ?? false).as<T?>();
|
|
||||||
} else if (T == int) {
|
|
||||||
return _sp?.getInt(widget.spKey).as<T?>();
|
|
||||||
} else if (T == num || T == double) {
|
|
||||||
return _sp?.getDouble(widget.spKey).as<T?>();
|
|
||||||
} else if (T == String) {
|
|
||||||
return _sp?.getString(widget.spKey).as<T?>();
|
|
||||||
} else if (T == Iterable<String>) {
|
|
||||||
return _sp?.getStringList(widget.spKey).as<T?>();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setValue(T value) async {
|
|
||||||
if (T == bool) {
|
|
||||||
_sp?.setBool(widget.spKey, value as bool);
|
|
||||||
} else if (T == int) {
|
|
||||||
_sp?.setInt(widget.spKey, value as int);
|
|
||||||
} else if (T == num || T == double) {
|
|
||||||
_sp?.setDouble(widget.spKey, value as double);
|
|
||||||
} else if (T == String) {
|
|
||||||
_sp?.setString(widget.spKey, value as String);
|
|
||||||
} else if (T == Iterable<String>) {
|
|
||||||
_sp?.setStringList(widget.spKey, (value as Iterable<String>).toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
onTap: widget.setOnTap != null
|
|
||||||
? () async {
|
|
||||||
value = widget.setOnTap!.call(value);
|
|
||||||
if (value != null) {
|
|
||||||
_setValue(value!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
child: widget.builder?.call(value, _setValue),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _setValue(T value) async {
|
|
||||||
await setValue(value!);
|
|
||||||
if (widget.shouldRebuild?.call(value) != false) {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
|
|
||||||
class SimpleTile extends StatelessWidget {
|
|
||||||
final Widget? trail;
|
|
||||||
final Widget title;
|
|
||||||
final VoidCallback? onTap;
|
|
||||||
|
|
||||||
SimpleTile({
|
|
||||||
required this.title,
|
|
||||||
this.trail,
|
|
||||||
this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
SimpleTile.text({
|
|
||||||
required String text,
|
|
||||||
this.trail,
|
|
||||||
this.onTap,
|
|
||||||
}) : title = Text(text);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Container(
|
|
||||||
height: 50.h,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4.h),
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(child: title),
|
|
||||||
if (trail != null) trail!,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:mnemo_cards/theme/themes.dart';
|
|
||||||
|
|
||||||
class MnemoSlider extends StatelessWidget {
|
|
||||||
final double value;
|
|
||||||
final void Function(double)? onChanged;
|
|
||||||
final double min;
|
|
||||||
final double max;
|
|
||||||
|
|
||||||
MnemoSlider({
|
|
||||||
required this.value,
|
|
||||||
this.onChanged,
|
|
||||||
this.min = 0.2,
|
|
||||||
this.max = 2.0,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var v = this.value;
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(color: borderGray),
|
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 2.0),
|
|
||||||
child: SliderTheme(
|
|
||||||
data: SliderTheme.of(context).copyWith(
|
|
||||||
activeTrackColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
inactiveTrackColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
thumbColor: progressBlue,
|
|
||||||
thumbShape: _RectSliderThumbShape(
|
|
||||||
enabledThumbRadius: 19.0,
|
|
||||||
borderRadius: Radius.circular(10),
|
|
||||||
textBuilder: (v) {
|
|
||||||
final value = ((v * (max - min) + min) * 10).toInt();
|
|
||||||
if (value % 10 == 0) {
|
|
||||||
return '${(value / 10).toStringAsFixed(0)}x';
|
|
||||||
} else {
|
|
||||||
return (value / 10).toStringAsFixed(1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
trackShape: RoundedRectSliderTrackShape(),
|
|
||||||
trackHeight: 1.h,
|
|
||||||
overlayColor: Colors.transparent,
|
|
||||||
overlappingShapeStrokeColor: Colors.transparent,
|
|
||||||
overlayShape: RoundSliderOverlayShape(overlayRadius: 2.0),
|
|
||||||
),
|
|
||||||
child: StatefulBuilder(builder: (context, setState) {
|
|
||||||
return Slider(
|
|
||||||
min: min,
|
|
||||||
max: max,
|
|
||||||
value: v,
|
|
||||||
onChanged: (updated) {
|
|
||||||
setState(() {
|
|
||||||
v = updated;
|
|
||||||
});
|
|
||||||
onChanged?.call((updated * 100).toInt() / 100.0);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RectSliderThumbShape extends SliderComponentShape {
|
|
||||||
/// Create a slider thumb that draws a Rect.
|
|
||||||
const _RectSliderThumbShape({
|
|
||||||
this.enabledThumbRadius = 10.0,
|
|
||||||
this.disabledThumbRadius,
|
|
||||||
this.elevation = 1.0,
|
|
||||||
this.pressedElevation = 6.0,
|
|
||||||
this.borderRadius,
|
|
||||||
this.textBuilder,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String Function(double v)? textBuilder;
|
|
||||||
|
|
||||||
/// The preferred radius of the round thumb shape when the slider is enabled.
|
|
||||||
///
|
|
||||||
/// If it is not provided, then the Material Design default of 10 is used.
|
|
||||||
final double enabledThumbRadius;
|
|
||||||
|
|
||||||
/// The preferred radius of the round thumb shape when the slider is disabled.
|
|
||||||
///
|
|
||||||
/// If no disabledRadius is provided, then it is equal to the
|
|
||||||
/// [enabledThumbRadius]
|
|
||||||
final double? disabledThumbRadius;
|
|
||||||
final Radius? borderRadius;
|
|
||||||
|
|
||||||
double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius;
|
|
||||||
|
|
||||||
/// The resting elevation adds shadow to the unpressed thumb.
|
|
||||||
///
|
|
||||||
/// The default is 1.
|
|
||||||
///
|
|
||||||
/// Use 0 for no shadow. The higher the value, the larger the shadow. For
|
|
||||||
/// example, a value of 12 will create a very large shadow.
|
|
||||||
///
|
|
||||||
final double elevation;
|
|
||||||
|
|
||||||
/// The pressed elevation adds shadow to the pressed thumb.
|
|
||||||
///
|
|
||||||
/// The default is 6.
|
|
||||||
///
|
|
||||||
/// Use 0 for no shadow. The higher the value, the larger the shadow. For
|
|
||||||
/// example, a value of 12 will create a very large shadow.
|
|
||||||
final double pressedElevation;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
|
|
||||||
return Size.fromRadius(
|
|
||||||
isEnabled == true ? enabledThumbRadius : _disabledThumbRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void paint(
|
|
||||||
PaintingContext context,
|
|
||||||
Offset center, {
|
|
||||||
required Animation<double> activationAnimation,
|
|
||||||
required Animation<double> enableAnimation,
|
|
||||||
required bool isDiscrete,
|
|
||||||
required TextPainter labelPainter,
|
|
||||||
required RenderBox parentBox,
|
|
||||||
required SliderThemeData sliderTheme,
|
|
||||||
required TextDirection textDirection,
|
|
||||||
required double value,
|
|
||||||
required double textScaleFactor,
|
|
||||||
required Size sizeWithOverflow,
|
|
||||||
}) {
|
|
||||||
final Canvas canvas = context.canvas;
|
|
||||||
final Tween<double> radiusTween = Tween<double>(
|
|
||||||
begin: _disabledThumbRadius,
|
|
||||||
end: enabledThumbRadius,
|
|
||||||
);
|
|
||||||
final ColorTween colorTween = ColorTween(
|
|
||||||
begin: sliderTheme.disabledThumbColor,
|
|
||||||
end: sliderTheme.thumbColor,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Color color = colorTween.evaluate(enableAnimation)!;
|
|
||||||
final double radius = radiusTween.evaluate(enableAnimation);
|
|
||||||
|
|
||||||
final Tween<double> elevationTween = Tween<double>(
|
|
||||||
begin: elevation,
|
|
||||||
end: pressedElevation,
|
|
||||||
);
|
|
||||||
|
|
||||||
final double evaluatedElevation =
|
|
||||||
elevationTween.evaluate(activationAnimation);
|
|
||||||
final Path path = Path()
|
|
||||||
..addArc(
|
|
||||||
Rect.fromCenter(
|
|
||||||
center: center, width: 2 * radius, height: 2 * radius),
|
|
||||||
0,
|
|
||||||
pi * 2);
|
|
||||||
|
|
||||||
bool paintShadows = false;
|
|
||||||
assert(() {
|
|
||||||
if (debugDisableShadows) {
|
|
||||||
paintShadows = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}());
|
|
||||||
|
|
||||||
if (paintShadows) {
|
|
||||||
canvas.drawShadow(path, Colors.black, evaluatedElevation, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
final TextPainter textPainter =
|
|
||||||
TextPainter(textDirection: TextDirection.rtl);
|
|
||||||
textPainter.text = TextSpan(
|
|
||||||
text: textBuilder?.call(value) ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: radius,
|
|
||||||
color: Colors.black,
|
|
||||||
));
|
|
||||||
textPainter.layout();
|
|
||||||
|
|
||||||
final Offset textCenter = Offset(center.dx - (textPainter.width / 2),
|
|
||||||
center.dy - (textPainter.height / 2));
|
|
||||||
|
|
||||||
// Use drawRect instead of drawCircle
|
|
||||||
canvas.drawRRect(
|
|
||||||
RRect.fromRectAndRadius(
|
|
||||||
Rect.fromCircle(center: center, radius: radius),
|
|
||||||
borderRadius ?? Radius.zero,
|
|
||||||
),
|
|
||||||
Paint()..color = borderGray,
|
|
||||||
);
|
|
||||||
// Use drawRect instead of drawCircle
|
|
||||||
canvas.drawRRect(
|
|
||||||
RRect.fromRectAndRadius(
|
|
||||||
Rect.fromCircle(center: center, radius: radius - 1),
|
|
||||||
borderRadius ?? Radius.zero,
|
|
||||||
),
|
|
||||||
Paint()..color = color,
|
|
||||||
);
|
|
||||||
|
|
||||||
textPainter.paint(canvas, textCenter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mnemo_cards/theme/themes.dart';
|
|
||||||
|
|
||||||
class SwitchButton extends StatelessWidget {
|
|
||||||
final bool value;
|
|
||||||
final void Function(bool)? onChanged;
|
|
||||||
|
|
||||||
SwitchButton({
|
|
||||||
required this.value,
|
|
||||||
required this.onChanged,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Switch(
|
|
||||||
value: value,
|
|
||||||
onChanged: onChanged,
|
|
||||||
activeColor: progressBlue,
|
|
||||||
activeTrackColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
inactiveTrackColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
trackOutlineColor: WidgetStatePropertyAll(borderGray),
|
|
||||||
inactiveThumbColor: borderGray,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mnemo_cards/widgets/switch_button.dart';
|
|
||||||
|
|
||||||
class SwitchTile extends StatelessWidget {
|
|
||||||
final bool value;
|
|
||||||
final void Function(bool)? onChanged;
|
|
||||||
final String text;
|
|
||||||
|
|
||||||
SwitchTile({
|
|
||||||
required this.text,
|
|
||||||
required this.value,
|
|
||||||
this.onChanged,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Expanded(child: Text(text, overflow: TextOverflow.ellipsis,)),
|
|
||||||
SwitchButton(
|
|
||||||
value: value,
|
|
||||||
onChanged: onChanged ?? (v) {},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
|
|
||||||
class LinkButton extends StatelessWidget {
|
|
||||||
final VoidCallback? onPressed;
|
|
||||||
final String text;
|
|
||||||
|
|
||||||
LinkButton(this.text, this.onPressed);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onPressed,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.only(top: 2.0.h, bottom: 2.0.h),
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
fontSize: 16,
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
import 'package:auto_size_text/auto_size_text.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
|
||||||
|
|
||||||
import '../theme/themes.dart';
|
|
||||||
import 'horizontal_progress.dart';
|
|
||||||
|
|
||||||
class UserStatistics extends StatelessWidget {
|
|
||||||
final UserDataDto? userDataDto;
|
|
||||||
|
|
||||||
UserStatistics(this.userDataDto);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final words = userDataDto?.allWordsStatistics?.words ?? [];
|
|
||||||
words.sort(
|
|
||||||
(p, n) => (n.correct / n.total).compareTo(p.correct / p.total),
|
|
||||||
);
|
|
||||||
final learnedWords = words
|
|
||||||
.where((w) => w.correct > 10 && w.correct / w.total > 0.9)
|
|
||||||
.map((e) => e.word)
|
|
||||||
.toSet();
|
|
||||||
final learnedWordsLength = learnedWords.length;
|
|
||||||
final lastDigit = learnedWordsLength % 10;
|
|
||||||
final String? totalWordsText;
|
|
||||||
if (learnedWordsLength == 0) {
|
|
||||||
totalWordsText = 'Словарик';
|
|
||||||
} else if (lastDigit == 0 || lastDigit >= 5) {
|
|
||||||
totalWordsText = 'Ты уже знаешь $learnedWordsLength слов!';
|
|
||||||
} else if (lastDigit == 1) {
|
|
||||||
totalWordsText = 'Ты уже знаешь $learnedWordsLength слово!';
|
|
||||||
} else {
|
|
||||||
totalWordsText = 'Ты уже знаешь $learnedWordsLength слова!';
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 8.0.h, top: 8.0.h),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
totalWordsText,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
maxLines: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(color: borderGray),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8.0.w),
|
|
||||||
child: words.isEmpty
|
|
||||||
? Center(
|
|
||||||
child: AutoSizeText('Тут будут все пройденные слова'),
|
|
||||||
)
|
|
||||||
: ListView.builder(
|
|
||||||
itemCount: words.length,
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final word = words[index];
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 2.0.h),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'${word.word}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width / 2.5,
|
|
||||||
child: HorizontalProgressWidget(
|
|
||||||
(word.correct * 100).floor(),
|
|
||||||
(word.total * 100).floor(),
|
|
||||||
learnedWords.contains(word.word)
|
|
||||||
? golden
|
|
||||||
: progressBlue,
|
|
||||||
borderColor: borderGray,
|
|
||||||
height: 20.h,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
229
pubspec.lock
|
|
@ -37,10 +37,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265
|
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.5.1"
|
version: "3.6.1"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -61,18 +61,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: auto_route
|
name: auto_route
|
||||||
sha256: "6cad3f408863ffff2b5757967c802b18415dac4acb1b40c5cdd45d0a26e5080f"
|
sha256: a9001a90539ca3effc168f7e1029a5885c7326b9032c09ac895e303c1d137704
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.3"
|
version: "8.3.0"
|
||||||
auto_route_generator:
|
auto_route_generator:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: auto_route_generator
|
name: auto_route_generator
|
||||||
sha256: ba28133d3a3bf0a66772bcc98dade5843753cd9f1a8fb4802b842895515b67d3
|
sha256: a21d7a936c917488653c972f62d884d8adcf8c5d37acc7cd24da33cf784546c0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0"
|
version: "8.1.0"
|
||||||
auto_size_text:
|
auto_size_text:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -109,10 +109,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -125,18 +125,18 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.11"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
|
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.3.0"
|
version: "7.3.1"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -189,26 +189,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cloud_firestore
|
name: cloud_firestore
|
||||||
sha256: e461ea9ab23959102a780efcbccfe33c2ac46269928bc57093bbc0b526afc801
|
sha256: a0f161b92610e078b4962d7e6ebeb66dc9cce0ada3514aeee442f68165d78185
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.17.3"
|
version: "4.17.5"
|
||||||
cloud_firestore_platform_interface:
|
cloud_firestore_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cloud_firestore_platform_interface
|
name: cloud_firestore_platform_interface
|
||||||
sha256: "2e0b8db9a759ffc71086019f1bd27237e5e888ab1e99c507067ff8616acdfa24"
|
sha256: "6a55b319f8d33c307396b9104512e8130a61904528ab7bd8b5402678fca54b81"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.3"
|
version: "6.2.5"
|
||||||
cloud_firestore_web:
|
cloud_firestore_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cloud_firestore_web
|
name: cloud_firestore_web
|
||||||
sha256: "37b6974bef5b0a7ecd31037ffb7d7bfe6bb9d2ac6c064fbea395411ef0a64d55"
|
sha256: "89dfa1304d3da48b3039abbb2865e3d30896ef858e569a16804a99f4362283a9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.12.3"
|
version: "3.12.5"
|
||||||
code_builder:
|
code_builder:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -309,10 +309,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: dio
|
name: dio
|
||||||
sha256: "11e40df547d418cc0c4900a9318b26304e665da6fa4755399a9ff9efd09034b5"
|
sha256: e17f6b3097b8c51b72c74c9f071a605c47bcc8893839bd66732457a5ebe73714
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.4.3+1"
|
version: "5.5.0+1"
|
||||||
|
dio_web_adapter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dio_web_adapter
|
||||||
|
sha256: "36c5b2d79eb17cdae41e974b7a8284fec631651d2a6f39a8a2ff22327e90aeac"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
dot_navigation_bar:
|
dot_navigation_bar:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -357,10 +365,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a"
|
sha256: "824f5b9f389bfc4dddac3dea76cd70c51092d9dff0b2ece7ef4f53db8547d258"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.3"
|
version: "8.0.6"
|
||||||
firebase_analytics:
|
firebase_analytics:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -397,18 +405,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_platform_interface
|
name: firebase_core_platform_interface
|
||||||
sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63
|
sha256: "1003a5a03a61fc9a22ef49f37cbcb9e46c86313a7b2e7029b9390cf8c6fc32cb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.1.0"
|
||||||
firebase_core_web:
|
firebase_core_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_web
|
name: firebase_core_web
|
||||||
sha256: "43d9e951ac52b87ae9cc38ecdcca1e8fa7b52a1dd26a96085ba41ce5108db8e9"
|
sha256: "23509cb3cddfb3c910c143279ac3f07f06d3120f7d835e4a5d4b42558e978712"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.17.0"
|
version: "2.17.3"
|
||||||
firebase_crashlytics:
|
firebase_crashlytics:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -466,34 +474,42 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
|
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "4.0.0"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_native_splash
|
name: flutter_native_splash
|
||||||
sha256: edf39bcf4d74aca1eb2c1e43c3e445fd9f494013df7f0da752fefe72020eedc0
|
sha256: aa06fec78de2190f3db4319dd60fdc8d12b2626e93ef9828633928c2dcaea840
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_plugin_android_lifecycle
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
|
sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.19"
|
version: "2.0.20"
|
||||||
|
flutter_rustore_billing:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_rustore_billing
|
||||||
|
sha256: "95905fec5ab46f7d0e798469c847423aa4dac07461a6111892be3f34c48a5b75"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.1"
|
||||||
flutter_screenutil:
|
flutter_screenutil:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_screenutil
|
name: flutter_screenutil
|
||||||
sha256: "8cf100b8e4973dc570b6415a2090b0bfaa8756ad333db46939efc3e774ee100d"
|
sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.9.0"
|
version: "5.9.3"
|
||||||
flutter_secure_storage:
|
flutter_secure_storage:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -572,10 +588,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d
|
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.4"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -600,6 +616,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
|
go_router:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: go_router
|
||||||
|
sha256: b465e99ce64ba75e61c8c0ce3d87b66d8ac07f0b35d0a7e0263fcfc10f99e836
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "13.2.5"
|
||||||
google_identity_services_web:
|
google_identity_services_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -620,10 +644,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: google_sign_in_android
|
name: google_sign_in_android
|
||||||
sha256: "7647893c65e6720973f0e579051c8f84b877b486614d9f70a404259c41a4632e"
|
sha256: d30fb34b659679ea74397e9748b4ab5d720720d57dcc79538f1b3c4a68654cb3
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.23"
|
version: "6.1.27"
|
||||||
google_sign_in_ios:
|
google_sign_in_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -644,18 +668,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: google_sign_in_web
|
name: google_sign_in_web
|
||||||
sha256: fc0f14ed45ea616a6cfb4d1c7534c2221b7092cc4f29a709f0c3053cc3e821bd
|
sha256: d606264c7a1a526a3aa79d938b85a601d8589731a478bd4a3dcbdeb14a572228
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.4"
|
version: "0.12.4+1"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.2"
|
||||||
html:
|
html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -668,12 +692,12 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.2"
|
||||||
http_certificate_pinning:
|
http_certificate_pinning:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_certificate_pinning
|
name: http_certificate_pinning
|
||||||
sha256: "12b4848113d50c570af93e94bed64004caba14dde87719310d1e4556686c0afa"
|
sha256: "12b4848113d50c570af93e94bed64004caba14dde87719310d1e4556686c0afa"
|
||||||
|
|
@ -700,10 +724,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
|
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.7"
|
version: "4.2.0"
|
||||||
in_app_purchase:
|
in_app_purchase:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -716,10 +740,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: in_app_purchase_android
|
name: in_app_purchase_android
|
||||||
sha256: "25b4bc74d4d990c18a889ea9486cb9029285955f38ca81ff335c8936edf9e66d"
|
sha256: f3f3ded26d08d13383b8c9952d1cf1422f0a3440b04d27f9838adee86f2ce899
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.5"
|
version: "0.3.6+2"
|
||||||
in_app_purchase_platform_interface:
|
in_app_purchase_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -732,18 +756,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: in_app_purchase_storekit
|
name: in_app_purchase_storekit
|
||||||
sha256: c13e4fee493dff3e956ebd24f80656f5ddbf876a8d12817d6fbe52d90e7c2068
|
sha256: "187f12ba8030993d117d11d1a16d3607734140d572ce1ede088bfcec960b65df"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.15"
|
version: "0.3.17+1"
|
||||||
injectable:
|
injectable:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: injectable
|
name: injectable
|
||||||
sha256: fb722c86cf8233008e4db41c696a6145721f45dc8aeba91103e3128c3d63c9c6
|
sha256: "3c8355a29d11ff28c0311bed754649761f345ef7a13ff66a714380954af51226"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.2"
|
||||||
injectable_generator:
|
injectable_generator:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
|
@ -764,10 +788,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: jailbreak_root_detection
|
name: jailbreak_root_detection
|
||||||
sha256: "03c7bb8ba1c12ea2b75400b152e89ae8cf50abf0c88777a5e564af4a04aeebf2"
|
sha256: "7dd3418d1784892dbcb6cc25df53679aa7717a2d007b34f59d570ae2ec6edfa6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.4"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -820,10 +844,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "4.0.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -871,6 +895,13 @@ packages:
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
mnemo_cards_frontend_common:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "../mnemo_cards_frontend_common"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.0.1"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -883,10 +914,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: no_screenshot
|
name: no_screenshot
|
||||||
sha256: c8621208e3e01e5b9c6d8f4611241465436618ffd3da8340bd533f8241a33fc5
|
sha256: "8415601932f84d103edda5378cacd0e10c8d8ca40de4dd8ad0496d1eee71107a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1+6"
|
version: "0.0.1+7"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -931,10 +962,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
|
sha256: "30c5aa827a6ae95ce2853cdc5fe3971daaac00f6f081c419c013f7f57bff2f5e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.2.7"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -963,10 +994,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.0"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -979,10 +1010,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.4"
|
version: "3.1.5"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1019,10 +1050,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.3.0"
|
||||||
recase:
|
recase:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1051,10 +1082,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: rxdart
|
name: rxdart
|
||||||
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
|
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.7"
|
version: "0.28.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1067,10 +1098,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
|
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.3"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1091,10 +1122,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_platform_interface
|
name: shared_preferences_platform_interface
|
||||||
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
sha256: "034650b71e73629ca08a0bd789fd1d83cc63c2d1e405946f7cef7bc37432f93a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.0"
|
||||||
shared_preferences_web:
|
shared_preferences_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1123,10 +1154,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
shimmer:
|
shimmer:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1248,26 +1279,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
|
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.6"
|
version: "6.3.0"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
|
sha256: "95d8027db36a0e52caf55680f91e33ea6aa12a3ce608c90b06f4e429a21067ac"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.1"
|
version: "6.3.5"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
|
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.3.1"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1348,30 +1379,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.5.1"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.5"
|
version: "3.0.1"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: webview_flutter
|
name: webview_flutter
|
||||||
sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932"
|
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.7.0"
|
version: "4.8.0"
|
||||||
webview_flutter_android:
|
webview_flutter_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webview_flutter_android
|
name: webview_flutter_android
|
||||||
sha256: dad3313c9ead95517bb1cae5e1c9d20ba83729d5a59e5e83c0a2d66203f27f91
|
sha256: f42447ca49523f11d8f70abea55ea211b3cafe172dd7a0e7ac007bb35dd356dc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.16.1"
|
version: "3.16.4"
|
||||||
webview_flutter_platform_interface:
|
webview_flutter_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1384,18 +1423,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webview_flutter_wkwebview
|
name: webview_flutter_wkwebview
|
||||||
sha256: f12f8d8a99784b863e8b85e4a9a5e3cf1839d6803d2c0c3e0533a8f3c5a992a7
|
sha256: "9c62cc46fa4f2d41e10ab81014c1de470a6c6f26051a2de32111b2ee55287feb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.13.0"
|
version: "3.14.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.5.0"
|
version: "5.5.1"
|
||||||
win32_registry:
|
win32_registry:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1432,10 +1471,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: yandex_mobileads
|
name: yandex_mobileads
|
||||||
sha256: "3c98919a96edb1c30f6407df1f599cf6ca24eb8e45e88477117d71ff3ee73147"
|
sha256: "836d886d1eab1e42dee819415e0d5320bb3003632b879a470a2190ec0b940e36"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "7.1.0"
|
||||||
yookassa_client:
|
yookassa_client:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1445,5 +1484,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.4.0 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.22.0"
|
||||||
|
|
|
||||||
16
pubspec.yaml
|
|
@ -2,7 +2,7 @@ name: mnemo_cards
|
||||||
description: Mnemo
|
description: Mnemo
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 1.0.1
|
version: 1.0.1+11
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.1.3 <4.0.0'
|
sdk: '>=3.1.3 <4.0.0'
|
||||||
|
|
@ -14,6 +14,11 @@ dependencies:
|
||||||
mnemo_cards_common:
|
mnemo_cards_common:
|
||||||
path: ../mnemo_cards_common
|
path: ../mnemo_cards_common
|
||||||
|
|
||||||
|
mnemo_cards_frontend_common:
|
||||||
|
path: ../mnemo_cards_frontend_common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
get_it:
|
get_it:
|
||||||
shared_preferences: ^2.2.3
|
shared_preferences: ^2.2.3
|
||||||
flutter_secure_storage: ^9.2.2
|
flutter_secure_storage: ^9.2.2
|
||||||
|
|
@ -37,7 +42,7 @@ dependencies:
|
||||||
google_sign_in:
|
google_sign_in:
|
||||||
device_info_plus: ^9.1.2
|
device_info_plus: ^9.1.2
|
||||||
package_info_plus: ^8.0.0
|
package_info_plus: ^8.0.0
|
||||||
yandex_mobileads: ^6.1.0
|
yandex_mobileads: ^7.1.0
|
||||||
firebase_crashlytics: ^3.5.7
|
firebase_crashlytics: ^3.5.7
|
||||||
firebase_analytics: ^10.10.7
|
firebase_analytics: ^10.10.7
|
||||||
in_app_purchase: ^3.2.0
|
in_app_purchase: ^3.2.0
|
||||||
|
|
@ -56,11 +61,10 @@ dependencies:
|
||||||
no_screenshot: ^0.0.1+6
|
no_screenshot: ^0.0.1+6
|
||||||
|
|
||||||
file_picker:
|
file_picker:
|
||||||
http_certificate_pinning: ^2.1.3
|
|
||||||
url_launcher: ^6.2.6
|
url_launcher: ^6.2.6
|
||||||
|
|
||||||
# requests_inspector: ^4.0.3
|
# RUSTORE
|
||||||
|
flutter_rustore_billing: ^6.0.1
|
||||||
|
|
||||||
collection: any
|
collection: any
|
||||||
freezed_annotation: any
|
freezed_annotation: any
|
||||||
|
|
@ -71,7 +75,7 @@ dev_dependencies:
|
||||||
auto_route_generator:
|
auto_route_generator:
|
||||||
build_runner:
|
build_runner:
|
||||||
injectable_generator:
|
injectable_generator:
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
|
||||||
flutter_launcher_icons: ^0.13.1
|
flutter_launcher_icons: ^0.13.1
|
||||||
flutter_native_splash: ^2.4.0
|
flutter_native_splash: ^2.4.0
|
||||||
|
|
|
||||||