Merge branch 'dev' into 'test'
merge test from dev See merge request Didvan/didvan-app!3
|
|
@ -1,6 +1,7 @@
|
|||
cache:
|
||||
paths:
|
||||
- build/web
|
||||
|
||||
stages:
|
||||
- build
|
||||
- push
|
||||
|
|
@ -11,9 +12,10 @@ build:
|
|||
image: cirrusci/flutter:latest
|
||||
script:
|
||||
- flutter clean
|
||||
- flutter build web --web-renderer canvaskit
|
||||
- flutter build web --web-renderer html
|
||||
only:
|
||||
- test
|
||||
- dev
|
||||
|
||||
push:
|
||||
stage: push
|
||||
|
|
@ -26,8 +28,9 @@ push:
|
|||
- docker push registry.gitlab.com/didvan/didvan-app/api:latest
|
||||
only:
|
||||
- test
|
||||
- dev
|
||||
|
||||
deploy:
|
||||
deploy-test:
|
||||
stage: deploy
|
||||
image: python:3.10.2
|
||||
variables:
|
||||
|
|
@ -35,6 +38,18 @@ deploy:
|
|||
script:
|
||||
- pip install fandogh_cli --upgrade
|
||||
- fandogh login --username=$FAN_USR --password=$FAN_PASS
|
||||
- fandogh service apply -f ./deployment/config.yaml -p SEC_NAME
|
||||
- fandogh service apply -f ./deployment/test.yaml -p SEC_NAME
|
||||
only:
|
||||
- test
|
||||
|
||||
deploy-dev:
|
||||
stage: deploy
|
||||
image: python:3.10.2
|
||||
variables:
|
||||
COLLECT_ERROR: 1
|
||||
script:
|
||||
- pip install fandogh_cli --upgrade
|
||||
- fandogh login --username=$FAN_USR --password=$FAN_PASS
|
||||
- fandogh service apply -f ./deployment/dev.yaml -p SEC_NAME
|
||||
only:
|
||||
- dev
|
||||
|
|
@ -22,7 +22,6 @@ if (flutterVersionName == null) {
|
|||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
|
|
@ -66,7 +65,5 @@ flutter {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation platform('com.google.firebase:firebase-bom:29.0.4')
|
||||
implementation 'com.google.firebase:firebase-analytics'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"project_info": {
|
||||
"project_number": "935017686266",
|
||||
"project_id": "didvan-9b7da",
|
||||
"storage_bucket": "didvan-9b7da.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:935017686266:android:f9cbc9aba8e3d65ed2d543",
|
||||
"android_client_info": {
|
||||
"package_name": "com.didvan.didvanapp"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
|
|
@ -5,8 +5,10 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application
|
||||
android:label="Didvan"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
|
|
@ -17,6 +19,9 @@
|
|||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
|
|
@ -31,10 +36,11 @@
|
|||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.3.50'
|
||||
ext.kotlin_version = '1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
kind: ExternalService
|
||||
name: app-dev
|
||||
spec:
|
||||
allow_http: false
|
||||
disable_default_domains: true
|
||||
image: registry.gitlab.com/didvan/didvan-app/api:latest
|
||||
image_pull_policy: Always
|
||||
image_pull_secret: $SEC_NAME
|
||||
path: /
|
||||
replicas: 1
|
||||
resources:
|
||||
memory: 100Mi
|
||||
domains:
|
||||
- name: dev.didvan.app
|
||||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '9.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
PODS:
|
||||
- audio_session (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_secure_storage (3.3.1):
|
||||
- Flutter
|
||||
- flutter_vibrate (0.0.1):
|
||||
- Flutter
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- image_cropper (0.0.4):
|
||||
- Flutter
|
||||
- TOCropViewController (~> 2.6.1)
|
||||
- image_picker (0.0.1):
|
||||
- Flutter
|
||||
- just_audio (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_ios (0.0.1):
|
||||
- Flutter
|
||||
- record (0.0.1):
|
||||
- Flutter
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
- TOCropViewController (2.6.1)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`)
|
||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
- record (from `.symlinks/plugins/record/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- FMDB
|
||||
- TOCropViewController
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_secure_storage:
|
||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||
flutter_vibrate:
|
||||
:path: ".symlinks/plugins/flutter_vibrate/ios"
|
||||
image_cropper:
|
||||
:path: ".symlinks/plugins/image_cropper/ios"
|
||||
image_picker:
|
||||
:path: ".symlinks/plugins/image_picker/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/ios"
|
||||
path_provider_ios:
|
||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||
record:
|
||||
:path: ".symlinks/plugins/record/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
audio_session: 4f3e461722055d21515cf3261b64c973c062f345
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||
flutter_vibrate: 9f4c2ab57008965f78969472367c329dd77eb801
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
|
||||
image_picker: 9aa50e1d8cdacdbed739e925b7eea16d014367e6
|
||||
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
||||
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
|
||||
record: 7ee2393532f8553bbb09fa19e95478323b7c0a99
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||
url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
|
||||
|
||||
PODFILE CHECKSUM: a75497545d4391e2d394c3668e20cfb1c2bbd4aa
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
E870A5F479A60D6704DD5DF2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75DBECA488F412614712FB74 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
|
@ -31,9 +32,11 @@
|
|||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
1CDA6531AC975E620DBA1134 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
75DBECA488F412614712FB74 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
|
|
@ -42,6 +45,8 @@
|
|||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
98ACB01D5FA5A78DB2686183 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
C97DED20C4A171F16FB949CD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -49,12 +54,31 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E870A5F479A60D6704DD5DF2 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
650C3E9A238A953E4E8E6AED /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
75DBECA488F412614712FB74 /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8170350417391B7E9B77985B /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C97DED20C4A171F16FB949CD /* Pods-Runner.debug.xcconfig */,
|
||||
98ACB01D5FA5A78DB2686183 /* Pods-Runner.release.xcconfig */,
|
||||
1CDA6531AC975E620DBA1134 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -72,6 +96,8 @@
|
|||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
8170350417391B7E9B77985B /* Pods */,
|
||||
650C3E9A238A953E4E8E6AED /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
|
@ -105,12 +131,14 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
9F9C99F59A6A1134B656560D /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
AE20B55CEF8506DDEEBE3543 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -127,7 +155,7 @@
|
|||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1020;
|
||||
LastUpgradeCheck = 1300;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
|
|
@ -197,6 +225,45 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
9F9C99F59A6A1134B656560D /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
AE20B55CEF8506DDEEBE3543 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
|
@ -287,12 +354,19 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = W2PAW454F9;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.didvan.didvanapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
@ -411,12 +485,19 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = W2PAW454F9;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.didvan.didvanapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
|
@ -430,12 +511,19 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = W2PAW454F9;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.didvan.didvanapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1300"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -4,4 +4,7 @@
|
|||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 516 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 974 B |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 564 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
|
@ -26,6 +26,12 @@
|
|||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need to access to the microphone to record audio file</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need to access to the user gallery to add user profile photo</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need to access to the user gallery to add user profile photo</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
|
@ -36,9 +36,9 @@ class LightThemeConfig {
|
|||
|
||||
static const ColorScheme _colorScheme = ColorScheme(
|
||||
primary: _primary,
|
||||
primaryVariant: _white,
|
||||
primaryContainer: _white,
|
||||
secondary: Color(0xFFD61515),
|
||||
secondaryVariant: _white,
|
||||
secondaryContainer: _white,
|
||||
surface: _white,
|
||||
background: _background,
|
||||
error: Color(0xFFF00505),
|
||||
|
|
@ -116,9 +116,9 @@ class DarkThemeConfig {
|
|||
|
||||
static const ColorScheme _colorScheme = ColorScheme(
|
||||
primary: _primary,
|
||||
primaryVariant: _white,
|
||||
primaryContainer: _white,
|
||||
secondary: Color(0xFFE53939),
|
||||
secondaryVariant: _white,
|
||||
secondaryContainer: _white,
|
||||
surface: Color(0xFF181B1F),
|
||||
background: _background,
|
||||
error: Color(0xFFF53B3B),
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ class Assets {
|
|||
static const String _baseEmptyStatesPath = _basePath + '/images/empty_states';
|
||||
static const String _baseAnimationsPath = _basePath + '/animations';
|
||||
static const String _baseRecordsPath = _basePath + '/images/records';
|
||||
static const String _baseLogosPath = _basePath + '/images/logos';
|
||||
|
||||
static String get verticalLogoWithText =>
|
||||
_baseImagesPath + '/logos/logo-vertical-$_themeSuffix.svg';
|
||||
_baseLogosPath + '/logo-vertical-$_themeSuffix.svg';
|
||||
static String get horizontalLogoWithText =>
|
||||
_baseImagesPath + '/logos/logo-horizontal-$_themeSuffix.svg';
|
||||
_baseLogosPath + '/logo-horizontal-$_themeSuffix.svg';
|
||||
static String get studioLogo => _baseLogosPath + '/studio-$_themeSuffix.svg';
|
||||
|
||||
static String get logoLoadingAnimation =>
|
||||
_baseAnimationsPath + '/indicator-$_themeSuffix.riv';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/providers/server_data_provider.dart';
|
||||
import 'package:didvan/providers/theme_provider.dart';
|
||||
import 'package:didvan/providers/user_provider.dart';
|
||||
import 'package:didvan/routes/route_generator.dart';
|
||||
|
|
@ -24,9 +23,6 @@ class Didvan extends StatelessWidget {
|
|||
ChangeNotifierProvider<UserProvider>(
|
||||
create: (context) => UserProvider(),
|
||||
),
|
||||
ChangeNotifierProvider<ServerDataProvider>(
|
||||
create: (context) => ServerDataProvider(),
|
||||
),
|
||||
ChangeNotifierProvider<ThemeProvider>(
|
||||
create: (context) => ThemeProvider(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
class Category {
|
||||
class CategoryData {
|
||||
final int id;
|
||||
final String label;
|
||||
|
||||
const Category({required this.id, required this.label});
|
||||
const CategoryData({required this.id, required this.label});
|
||||
|
||||
factory Category.fromJson(Map<String, dynamic> json) => Category(
|
||||
factory CategoryData.fromJson(Map<String, dynamic> json) => CategoryData(
|
||||
id: json['id'],
|
||||
label: json['label'],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ class ChatRoom {
|
|||
final int id;
|
||||
final String type;
|
||||
final String updatedAt;
|
||||
final int unread;
|
||||
int unread;
|
||||
final LastMessage lastMessage;
|
||||
|
||||
const ChatRoom({
|
||||
ChatRoom({
|
||||
required this.id,
|
||||
required this.type,
|
||||
required this.updatedAt,
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
class OverviewData {
|
||||
final int id;
|
||||
final String title;
|
||||
final String image;
|
||||
final String description;
|
||||
final String createdAt;
|
||||
final String? type;
|
||||
|
||||
const OverviewData({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.image,
|
||||
required this.description,
|
||||
required this.createdAt,
|
||||
required this.type,
|
||||
});
|
||||
|
||||
factory OverviewData.fromJson(Map<String, dynamic> json) => OverviewData(
|
||||
id: json['id'],
|
||||
title: json['title'],
|
||||
image: json['image'],
|
||||
description: json['description'],
|
||||
createdAt: json['createdAt'],
|
||||
type: json['type'],
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'radar_attachment.dart';
|
||||
|
||||
class MessageData {
|
||||
|
|
@ -8,15 +11,19 @@ class MessageData {
|
|||
final bool readed;
|
||||
final String createdAt;
|
||||
final RadarAttachment? radar;
|
||||
final File? audioFile;
|
||||
final int? audioDuration;
|
||||
|
||||
const MessageData({
|
||||
required this.id,
|
||||
required this.writedByAdmin,
|
||||
required this.readed,
|
||||
required this.createdAt,
|
||||
required this.text,
|
||||
required this.audio,
|
||||
required this.radar,
|
||||
this.text,
|
||||
this.audio,
|
||||
this.radar,
|
||||
this.audioFile,
|
||||
this.audioDuration,
|
||||
});
|
||||
|
||||
factory MessageData.fromJson(Map<String, dynamic> json) => MessageData(
|
||||
|
|
@ -26,9 +33,12 @@ class MessageData {
|
|||
writedByAdmin: json['writedByAdmin'],
|
||||
readed: json['readed'],
|
||||
createdAt: json['createdAt'],
|
||||
audioDuration: json['waveform'] == null
|
||||
? null
|
||||
: jsonDecode(json['waveform'])['duration'] ?? 0,
|
||||
radar: json['radar'] == null
|
||||
? null
|
||||
: RadarAttachment.fromJson(json['radar'] as Map<String, dynamic>),
|
||||
: RadarAttachment.fromJson(json['radar']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:didvan/models/category.dart';
|
||||
|
||||
class RadarAttachment {
|
||||
final int id;
|
||||
final String title;
|
||||
|
|
@ -5,6 +7,8 @@ class RadarAttachment {
|
|||
final int timeToRead;
|
||||
final String image;
|
||||
final bool forManagers;
|
||||
final String createdAt;
|
||||
final List<CategoryData> categories;
|
||||
|
||||
const RadarAttachment({
|
||||
required this.id,
|
||||
|
|
@ -13,6 +17,8 @@ class RadarAttachment {
|
|||
required this.timeToRead,
|
||||
required this.image,
|
||||
required this.forManagers,
|
||||
required this.categories,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
factory RadarAttachment.fromJson(Map<String, dynamic> json) =>
|
||||
|
|
@ -22,7 +28,13 @@ class RadarAttachment {
|
|||
description: json['description'],
|
||||
timeToRead: json['timeToRead'],
|
||||
image: json['image'],
|
||||
createdAt: json['createdAt'],
|
||||
forManagers: json['forManagers'],
|
||||
categories: List<CategoryData>.from(
|
||||
json['categories'].map(
|
||||
(cat) => CategoryData.fromJson(cat),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:didvan/models/content.dart';
|
||||
import 'package:didvan/models/overview_data.dart';
|
||||
import 'package:didvan/models/tag.dart';
|
||||
|
||||
class NewsDetailsData {
|
||||
|
|
@ -12,6 +13,7 @@ class NewsDetailsData {
|
|||
final int order;
|
||||
final List<Tag> tags;
|
||||
final List<Content> contents;
|
||||
final List<OverviewData> relatedContents = [];
|
||||
|
||||
NewsDetailsData({
|
||||
required this.id,
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
import 'package:didvan/models/item_overview.dart';
|
||||
|
||||
class NewsOverviewData extends OverviewData {
|
||||
final String reference;
|
||||
bool marked;
|
||||
|
||||
NewsOverviewData({
|
||||
required this.reference,
|
||||
required this.marked,
|
||||
required id,
|
||||
required createdAt,
|
||||
required description,
|
||||
required title,
|
||||
required image,
|
||||
}) : super(
|
||||
createdAt: createdAt,
|
||||
description: description,
|
||||
id: id,
|
||||
image: image,
|
||||
title: title,
|
||||
type: 'news',
|
||||
);
|
||||
|
||||
factory NewsOverviewData.fromJson(Map<String, dynamic> json) =>
|
||||
NewsOverviewData(
|
||||
id: json['id'],
|
||||
title: json['title'],
|
||||
reference: json['reference'],
|
||||
description: json['description'],
|
||||
image: json['image'],
|
||||
createdAt: json['createdAt'],
|
||||
marked: json['marked'] ?? true,
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import 'package:didvan/models/category.dart';
|
||||
|
||||
class OverviewData {
|
||||
final int id;
|
||||
final String title;
|
||||
final String image;
|
||||
final String description;
|
||||
final int? timeToRead;
|
||||
final String? reference;
|
||||
final bool forManagers;
|
||||
final String createdAt;
|
||||
final String type;
|
||||
int comments;
|
||||
bool marked;
|
||||
final List<CategoryData>? categories;
|
||||
|
||||
OverviewData({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.image,
|
||||
required this.description,
|
||||
required this.createdAt,
|
||||
required this.type,
|
||||
required this.marked,
|
||||
required this.comments,
|
||||
required this.forManagers,
|
||||
this.timeToRead,
|
||||
this.reference,
|
||||
this.categories,
|
||||
});
|
||||
|
||||
factory OverviewData.fromJson(Map<String, dynamic> json) => OverviewData(
|
||||
id: json['id'],
|
||||
title: json['title'],
|
||||
image: json['image'],
|
||||
description: json['description'],
|
||||
timeToRead: json['timeToRead'],
|
||||
reference: json['reference'],
|
||||
forManagers: json['forManagers'] ?? false,
|
||||
comments: json['comments'] ?? 0,
|
||||
createdAt: json['createdAt'],
|
||||
type: json['type'] ?? '',
|
||||
marked: json['marked'] ?? false,
|
||||
categories: (json['categories'] as List<dynamic>?)
|
||||
?.map((e) => CategoryData.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'image': image,
|
||||
'description': description,
|
||||
'timeToRead': timeToRead,
|
||||
'reference': reference,
|
||||
'forManagers': forManagers,
|
||||
'createdAt': createdAt,
|
||||
'type': type,
|
||||
'categories': categories?.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:didvan/models/category.dart';
|
||||
import 'package:didvan/models/overview_data.dart';
|
||||
|
||||
import 'content.dart';
|
||||
import 'tag.dart';
|
||||
|
|
@ -15,8 +16,9 @@ class RadarDetailsData {
|
|||
int comments;
|
||||
final List<Tag> tags;
|
||||
final List<Content> contents;
|
||||
final List<Category> categories;
|
||||
final List<CategoryData> categories;
|
||||
final int order;
|
||||
final List<OverviewData> relatedContents = [];
|
||||
|
||||
RadarDetailsData({
|
||||
required this.id,
|
||||
|
|
@ -52,9 +54,9 @@ class RadarDetailsData {
|
|||
(content) => Content.fromJson(content),
|
||||
),
|
||||
),
|
||||
categories: List<Category>.from(
|
||||
categories: List<CategoryData>.from(
|
||||
json['categories'].map(
|
||||
(cat) => Category.fromJson(cat),
|
||||
(cat) => CategoryData.fromJson(cat),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
import 'package:didvan/models/item_overview.dart';
|
||||
|
||||
import 'category.dart';
|
||||
|
||||
class RadarOverviewData extends OverviewData {
|
||||
final bool forManagers;
|
||||
final List<Category> categories;
|
||||
final int timeToRead;
|
||||
int comments;
|
||||
bool marked;
|
||||
|
||||
RadarOverviewData({
|
||||
required this.forManagers,
|
||||
required this.categories,
|
||||
required this.comments,
|
||||
required this.timeToRead,
|
||||
required this.marked,
|
||||
required createdAt,
|
||||
required description,
|
||||
required id,
|
||||
required image,
|
||||
required title,
|
||||
}) : super(
|
||||
createdAt: createdAt,
|
||||
description: description,
|
||||
id: id,
|
||||
image: image,
|
||||
title: title,
|
||||
type: 'radar',
|
||||
);
|
||||
|
||||
factory RadarOverviewData.fromJson(Map<String, dynamic> json) =>
|
||||
RadarOverviewData(
|
||||
id: json['id'],
|
||||
image: json['image'],
|
||||
title: json['title'],
|
||||
description: json['description'],
|
||||
timeToRead: json['timeToRead'],
|
||||
createdAt: json['createdAt'],
|
||||
forManagers: json['forManagers'],
|
||||
marked: json['marked'],
|
||||
comments: json['comments'],
|
||||
categories: List<Category>.from(
|
||||
json['categories'].map(
|
||||
(category) => Category.fromJson(category),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -43,11 +43,11 @@ class User {
|
|||
}) {
|
||||
return User(
|
||||
id: id ?? this.id,
|
||||
username: username ?? this.username,
|
||||
username: this.username,
|
||||
phoneNumber: phoneNumber ?? this.phoneNumber,
|
||||
photo: photo ?? this.photo,
|
||||
photo: photo,
|
||||
fullName: fullName ?? this.fullName,
|
||||
email: email ?? this.email,
|
||||
email: email,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class ActionSheetData {
|
|||
final IconData? titleIcon;
|
||||
final Color? titleColor;
|
||||
final bool hasDismissButton;
|
||||
final bool hasConfirmButton;
|
||||
final bool withoutButtonMode;
|
||||
final bool smallDismissButton;
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ class ActionSheetData {
|
|||
this.onConfirmed,
|
||||
this.titleColor,
|
||||
this.hasDismissButton = true,
|
||||
this.hasConfirmButton = true,
|
||||
this.titleIcon,
|
||||
this.dismissTitle,
|
||||
this.onDismissed,
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
import 'package:didvan/pages/home/direct/direct_state.dart';
|
||||
import 'package:didvan/pages/home/direct/widgets/message_box.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/widgets/didvan/scaffold.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Direct extends StatefulWidget {
|
||||
final int id;
|
||||
const Direct({Key? key, required this.id}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<Direct> createState() => _DirectState();
|
||||
}
|
||||
|
||||
class _DirectState extends State<Direct> {
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<DirectState>().getMessages(widget.id);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
bottom: 56,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: DidvanScaffold(
|
||||
appBarData: AppBarData(
|
||||
hasBack: true,
|
||||
subtitle: 'ارتباط با سردبیر',
|
||||
title: 'رادار اقتصادی',
|
||||
),
|
||||
slivers: const [],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: const MessageBox(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:didvan/providers/core_provider.dart';
|
||||
import 'package:didvan/services/network/request.dart';
|
||||
import 'package:didvan/services/network/request_helper.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_vibrate/flutter_vibrate.dart';
|
||||
import 'package:record/record.dart';
|
||||
|
||||
class DirectState extends CoreProvier {
|
||||
final _recorder = Record();
|
||||
|
||||
File? recordedFile;
|
||||
|
||||
bool isRecording = false;
|
||||
|
||||
Future<void> getMessages(int id) async {
|
||||
final RequestService service = RequestService(RequestHelper.direct(id));
|
||||
await service.httpGet();
|
||||
if (service.isSuccess) {}
|
||||
}
|
||||
|
||||
void deleteRecordedFile() {
|
||||
recordedFile!.delete();
|
||||
recordedFile = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> startRecording() async {
|
||||
await _recorder.hasPermission();
|
||||
if (!kIsWeb) {
|
||||
Vibrate.feedback(FeedbackType.medium);
|
||||
}
|
||||
isRecording = true;
|
||||
_recorder.start();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> stopRecording(bool sendImidiately) async {
|
||||
final path = await _recorder.stop();
|
||||
isRecording = false;
|
||||
if (path == null) {
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
if (kIsWeb) {
|
||||
final uri = Uri.file(path);
|
||||
recordedFile = File.fromUri(uri);
|
||||
} else {
|
||||
recordedFile = File(path);
|
||||
}
|
||||
if (sendImidiately) {
|
||||
await sendMessage();
|
||||
} else {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> sendMessage() async {}
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/pages/home/direct/direct_state.dart';
|
||||
import 'package:didvan/pages/home/widgets/audio_visualizer.dart';
|
||||
import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MessageBox extends StatelessWidget {
|
||||
const MessageBox({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 56,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Theme.of(context).colorScheme.cardBorder,
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
child: Consumer<DirectState>(
|
||||
builder: (context, state, child) {
|
||||
if (state.isRecording) {
|
||||
return const _Recording();
|
||||
} else if (!state.isRecording && state.recordedFile != null) {
|
||||
return const _RecordChecking();
|
||||
}
|
||||
return const _Typing();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Typing extends StatelessWidget {
|
||||
const _Typing({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.read<DirectState>();
|
||||
return Row(
|
||||
children: [
|
||||
DidvanIconButton(
|
||||
icon: DidvanIcons.mic_solid,
|
||||
onPressed: state.startRecording,
|
||||
size: 32,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
textInputAction: TextInputAction.send,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: 'بنویسید یا پیام صوتی بگذارید...',
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.caption!
|
||||
.copyWith(color: Theme.of(context).colorScheme.disabledText),
|
||||
),
|
||||
onChanged: (value) {},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Recording extends StatelessWidget {
|
||||
const _Recording({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.read<DirectState>();
|
||||
return Row(
|
||||
children: [
|
||||
DidvanIconButton(
|
||||
icon: DidvanIcons.send_solid,
|
||||
onPressed: () => state.stopRecording(true),
|
||||
gestureSize: 52,
|
||||
),
|
||||
Expanded(
|
||||
child: DidvanText(
|
||||
'در حال ضبط صدا ...',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
),
|
||||
DidvanIconButton(
|
||||
icon: DidvanIcons.stop_circle_solid,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: () => state.stopRecording(false),
|
||||
size: 32,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _RecordChecking extends StatelessWidget {
|
||||
const _RecordChecking({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.read<DirectState>();
|
||||
return Row(
|
||||
children: [
|
||||
DidvanIconButton(
|
||||
icon: DidvanIcons.send_solid,
|
||||
onPressed: () => state.stopRecording(true),
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: AudioVisualizer(
|
||||
audioFile: state.recordedFile!,
|
||||
),
|
||||
),
|
||||
),
|
||||
DidvanIconButton(
|
||||
icon: DidvanIcons.trash_solid,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: state.deleteRecordedFile,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Studio extends StatelessWidget {
|
||||
const Studio({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
const LogoAppBar(),
|
||||
Expanded(
|
||||
child: EmptyState(
|
||||
asset: Assets.emptyStudio,
|
||||
title: 'استودیو آینده',
|
||||
subtitle: 'به زودی...',
|
||||
titleColor: Theme.of(context).colorScheme.title,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,314 +0,0 @@
|
|||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/services/storage/storage.dart';
|
||||
import 'package:didvan/utils/date_time.dart';
|
||||
import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:just_waveform/just_waveform.dart';
|
||||
|
||||
class AudioVisualizer extends StatefulWidget {
|
||||
final File audioFile;
|
||||
|
||||
const AudioVisualizer({
|
||||
Key? key,
|
||||
required this.audioFile,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<AudioVisualizer> createState() => _AudioVisualizerState();
|
||||
}
|
||||
|
||||
class _AudioVisualizerState extends State<AudioVisualizer> {
|
||||
final AudioPlayer _audioPlayer = AudioPlayer();
|
||||
|
||||
Stream<WaveformProgress>? waveDataStream;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (!kIsWeb) {
|
||||
waveDataStream = JustWaveform.extract(
|
||||
audioInFile: widget.audioFile,
|
||||
waveOutFile: File(StorageService.appTempsDir + '/rec-wave.wave'),
|
||||
zoom: const WaveformZoom.pixelsPerSecond(100),
|
||||
);
|
||||
}
|
||||
_setupAudioPlayer();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: DesignConfig.isDark
|
||||
? Theme.of(context).colorScheme.black
|
||||
: Theme.of(context).colorScheme.background,
|
||||
borderRadius: DesignConfig.mediumBorderRadius,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 12),
|
||||
StreamBuilder<Duration>(
|
||||
stream: _audioPlayer.positionStream,
|
||||
builder: (context, snapshot) {
|
||||
String text = '';
|
||||
if (_audioPlayer.duration == null) {
|
||||
Future.delayed(Duration.zero, () {
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
if (snapshot.data == null || snapshot.data == Duration.zero) {
|
||||
text = DateTimeUtils.normalizeTimeDuration(
|
||||
_audioPlayer.duration ?? Duration.zero);
|
||||
} else {
|
||||
text = DateTimeUtils.normalizeTimeDuration(snapshot.data!);
|
||||
}
|
||||
return DidvanText(
|
||||
text,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
isEnglishFont: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
if (kIsWeb) {
|
||||
return SvgPicture.asset(Assets.record);
|
||||
}
|
||||
return StreamBuilder<WaveformProgress>(
|
||||
stream: waveDataStream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.data == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
if (snapshot.data!.waveform == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
final waveform = snapshot.data!.waveform!;
|
||||
return GestureDetector(
|
||||
onHorizontalDragUpdate: _changePosition,
|
||||
onTapDown: _changePosition,
|
||||
child: SizedBox(
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: _AudioWaveformWidget(
|
||||
waveform: waveform,
|
||||
audioPlayer: _audioPlayer,
|
||||
start: Duration.zero,
|
||||
scale: 2,
|
||||
strokeWidth: 3,
|
||||
duration: waveform.duration,
|
||||
waveColor:
|
||||
Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
StreamBuilder<bool>(
|
||||
stream: _audioPlayer.playingStream,
|
||||
builder: (context, snapshot) {
|
||||
return DidvanIconButton(
|
||||
icon: snapshot.data == true
|
||||
? DidvanIcons.pause_circle_solid
|
||||
: DidvanIcons.play_circle_solid,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
onPressed: _playAndPouse,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _changePosition(details) {
|
||||
double posper =
|
||||
details.localPosition.dx / (MediaQuery.of(context).size.width - 200);
|
||||
if (posper >= 1 || posper < 0) return;
|
||||
final position = _audioPlayer.duration!.inMilliseconds;
|
||||
_audioPlayer.seek(
|
||||
Duration(milliseconds: (posper * position).toInt()),
|
||||
);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Future<void> _setupAudioPlayer() async {
|
||||
if (kIsWeb) {
|
||||
await _audioPlayer.setUrl(
|
||||
widget.audioFile.uri.path.replaceAll('%3A', ':'),
|
||||
);
|
||||
} else {
|
||||
await _audioPlayer.setFilePath(widget.audioFile.path);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _playAndPouse() async {
|
||||
if (_audioPlayer.playing) {
|
||||
_audioPlayer.pause();
|
||||
return;
|
||||
}
|
||||
await _audioPlayer.play();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_audioPlayer.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class _AudioWaveformWidget extends StatefulWidget {
|
||||
final Color waveColor;
|
||||
final double scale;
|
||||
final double strokeWidth;
|
||||
final double pixelsPerStep;
|
||||
final Waveform waveform;
|
||||
final Duration start;
|
||||
final Duration duration;
|
||||
final AudioPlayer audioPlayer;
|
||||
|
||||
const _AudioWaveformWidget({
|
||||
Key? key,
|
||||
required this.waveform,
|
||||
required this.start,
|
||||
required this.duration,
|
||||
required this.audioPlayer,
|
||||
this.waveColor = Colors.blue,
|
||||
this.scale = 1.0,
|
||||
this.strokeWidth = 5.0,
|
||||
this.pixelsPerStep = 8.0,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
__AudioWaveformWidgetState createState() => __AudioWaveformWidgetState();
|
||||
}
|
||||
|
||||
class __AudioWaveformWidgetState extends State<_AudioWaveformWidget>
|
||||
with SingleTickerProviderStateMixin {
|
||||
double progress = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
widget.audioPlayer.positionStream.listen((event) {
|
||||
if (widget.audioPlayer.duration == null) return;
|
||||
setState(() {
|
||||
progress = event.inMilliseconds /
|
||||
widget.audioPlayer.duration!.inMilliseconds *
|
||||
100;
|
||||
if (progress >= 100) {
|
||||
progress = 0;
|
||||
widget.audioPlayer.stop();
|
||||
widget.audioPlayer.seek(Duration.zero);
|
||||
}
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRect(
|
||||
child: CustomPaint(
|
||||
painter: _AudioWaveformPainter(
|
||||
waveColor: widget.waveColor,
|
||||
waveform: widget.waveform,
|
||||
start: widget.start,
|
||||
duration: widget.duration,
|
||||
scale: widget.scale,
|
||||
strokeWidth: widget.strokeWidth,
|
||||
pixelsPerStep: widget.pixelsPerStep,
|
||||
progressPercentage: progress,
|
||||
progressColor: Theme.of(context).colorScheme.focusedBorder,
|
||||
color: Theme.of(context).colorScheme.border,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _AudioWaveformPainter extends CustomPainter {
|
||||
final double scale;
|
||||
final double strokeWidth;
|
||||
final double pixelsPerStep;
|
||||
final Waveform waveform;
|
||||
final Duration start;
|
||||
final Duration duration;
|
||||
final double progressPercentage;
|
||||
final Color progressColor;
|
||||
final Color color;
|
||||
|
||||
_AudioWaveformPainter({
|
||||
required this.waveform,
|
||||
required this.start,
|
||||
required this.duration,
|
||||
required this.progressPercentage,
|
||||
required this.color,
|
||||
required this.progressColor,
|
||||
Color waveColor = Colors.blue,
|
||||
this.scale = 1.0,
|
||||
this.strokeWidth = 5.0,
|
||||
this.pixelsPerStep = 8.0,
|
||||
});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
if (duration == Duration.zero) return;
|
||||
double width = size.width;
|
||||
double height = size.height;
|
||||
|
||||
final waveformPixelsPerWindow = waveform.positionToPixel(duration).toInt();
|
||||
final waveformPixelsPerDevicePixel = waveformPixelsPerWindow / width;
|
||||
final waveformPixelsPerStep = waveformPixelsPerDevicePixel * pixelsPerStep;
|
||||
final sampleOffset = waveform.positionToPixel(start);
|
||||
final sampleStart = -sampleOffset % waveformPixelsPerStep;
|
||||
final totalLength = waveformPixelsPerWindow;
|
||||
final wavePaintB = Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = strokeWidth
|
||||
..strokeCap = StrokeCap.round
|
||||
..color = progressColor;
|
||||
final wavePaintA = Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = strokeWidth
|
||||
..strokeCap = StrokeCap.round
|
||||
..color = color;
|
||||
for (var i = sampleStart.toDouble();
|
||||
i <= waveformPixelsPerWindow + 1.0;
|
||||
i += waveformPixelsPerStep) {
|
||||
final sampleIdx = (sampleOffset + i).toInt();
|
||||
final x = i / waveformPixelsPerDevicePixel;
|
||||
final minY = normalise(waveform.getPixelMin(sampleIdx), height);
|
||||
final maxY = normalise(waveform.getPixelMax(sampleIdx), height);
|
||||
canvas.drawLine(
|
||||
Offset(x + strokeWidth / 2, max(strokeWidth * 0.75, minY)),
|
||||
Offset(x + strokeWidth / 2, min(height - strokeWidth * 0.75, maxY)),
|
||||
i / totalLength < progressPercentage / 100 ? wavePaintB : wavePaintA,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant _AudioWaveformPainter oldDelegate) {
|
||||
return oldDelegate.progressPercentage != progressPercentage;
|
||||
}
|
||||
|
||||
double normalise(int s, double height) {
|
||||
final y = 32768 + (scale * s).clamp(-32768.0, 32767.0).toDouble();
|
||||
return height - 1 - y * height / 65536;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TagItem extends StatelessWidget {
|
||||
final String label;
|
||||
|
||||
const TagItem({
|
||||
Key? key,
|
||||
required this.label,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 8,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DesignConfig.lowBorderRadius,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
DidvanIcons.hashtag_regular,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
DidvanText(
|
||||
label,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
import 'package:didvan/providers/core_provider.dart';
|
||||
import 'package:didvan/services/network/request.dart';
|
||||
import 'package:didvan/services/network/request_helper.dart';
|
||||
|
||||
class ServerDataProvider extends CoreProvier {
|
||||
final List<MapEntry> directTypes = [];
|
||||
class ServerDataProvider {
|
||||
static final List<MapEntry> directTypes = [];
|
||||
|
||||
Future<void> getData() async {
|
||||
static Future<void> getData() async {
|
||||
await _getDirectTypes();
|
||||
}
|
||||
|
||||
Future<void> _getDirectTypes() async {
|
||||
static int labelToTypeId(String? label) => label == null
|
||||
? 7
|
||||
: directTypes.firstWhere((element) => element.value.contains(label)).key;
|
||||
|
||||
static Future<void> _getDirectTypes() async {
|
||||
final service = RequestService(RequestHelper.directTypes);
|
||||
await service.httpGet();
|
||||
if (service.isSuccess) {
|
||||
|
|
@ -17,6 +20,8 @@ class ServerDataProvider extends CoreProvier {
|
|||
for (var i = 0; i < types.length; i++) {
|
||||
directTypes.add(MapEntry(types[i]['id'], types[i]['label']));
|
||||
}
|
||||
} else {
|
||||
throw 'Fetchin direct types failed!';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class UserProvider extends CoreProvier {
|
|||
return token;
|
||||
}
|
||||
await StorageService.setValue(key: 'token', value: newToken);
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> getUserInfo() async {
|
||||
|
|
@ -35,8 +36,15 @@ class UserProvider extends CoreProvier {
|
|||
Future<bool> setProfilePhoto(dynamic file) async {
|
||||
appState = AppState.isolatedBusy;
|
||||
final RequestService service =
|
||||
RequestService(RequestHelper.updateUserProfile);
|
||||
await service.multipart(file);
|
||||
RequestService(RequestHelper.updateProfilePhoto);
|
||||
await service.multipart(
|
||||
file: file,
|
||||
method: 'PUT',
|
||||
fileName: 'user-profile',
|
||||
fieldName: 'photo',
|
||||
mediaExtension: 'jpg',
|
||||
mediaFormat: 'image',
|
||||
);
|
||||
if (service.isSuccess) {
|
||||
user = user.copyWith(photo: service.result['photo']);
|
||||
appState = AppState.idle;
|
||||
|
|
@ -46,6 +54,20 @@ class UserProvider extends CoreProvier {
|
|||
return false;
|
||||
}
|
||||
|
||||
Future<bool> deleteProfilePhoto() async {
|
||||
appState = AppState.isolatedBusy;
|
||||
final RequestService service =
|
||||
RequestService(RequestHelper.updateProfilePhoto);
|
||||
await service.delete();
|
||||
if (service.isSuccess) {
|
||||
user = user.copyWith(photo: null);
|
||||
appState = AppState.idle;
|
||||
return true;
|
||||
}
|
||||
appState = AppState.idle;
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<bool?> checkUsername(String username) async {
|
||||
if (user.username == username) return true;
|
||||
final RequestService service = RequestService(
|
||||
|
|
|
|||
|
|
@ -1,30 +1,32 @@
|
|||
import 'package:didvan/pages/authentication/authentication.dart';
|
||||
import 'package:didvan/pages/authentication/authentication_state.dart';
|
||||
import 'package:didvan/pages/home/comments/comments.dart';
|
||||
import 'package:didvan/pages/home/comments/comments_state.dart';
|
||||
import 'package:didvan/pages/home/direct/direct.dart';
|
||||
import 'package:didvan/pages/home/direct/direct_state.dart';
|
||||
import 'package:didvan/pages/home/home.dart';
|
||||
import 'package:didvan/pages/home/home_state.dart';
|
||||
import 'package:didvan/pages/home/news/news_details/news_details.dart';
|
||||
import 'package:didvan/pages/home/news/news_details/news_details_state.dart';
|
||||
import 'package:didvan/pages/home/news/news_state.dart';
|
||||
import 'package:didvan/pages/home/radar/radar_details/radar_details.dart';
|
||||
import 'package:didvan/pages/home/radar/radar_details/radar_details_state.dart';
|
||||
import 'package:didvan/pages/home/radar/radar_state.dart';
|
||||
import 'package:didvan/pages/home/settings/about_us/about_us.dart';
|
||||
import 'package:didvan/pages/home/settings/bookmarks/bookmarks.dart';
|
||||
import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart';
|
||||
import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmark.dart';
|
||||
import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
|
||||
import 'package:didvan/pages/home/settings/direct_list/direct_list.dart';
|
||||
import 'package:didvan/pages/home/settings/direct_list/direct_list_state.dart';
|
||||
import 'package:didvan/pages/home/settings/general_settings/settings.dart';
|
||||
import 'package:didvan/pages/home/settings/general_settings/settings_state.dart';
|
||||
import 'package:didvan/pages/home/settings/profile/profile.dart';
|
||||
import 'package:didvan/pages/splash/splash.dart';
|
||||
import 'package:didvan/models/tag.dart';
|
||||
import 'package:didvan/views/authentication/authentication.dart';
|
||||
import 'package:didvan/views/authentication/authentication_state.dart';
|
||||
import 'package:didvan/views/home/comments/comments.dart';
|
||||
import 'package:didvan/views/home/comments/comments_state.dart';
|
||||
import 'package:didvan/views/home/direct/direct.dart';
|
||||
import 'package:didvan/views/home/direct/direct_state.dart';
|
||||
import 'package:didvan/views/home/hashtag/hashtag.dart';
|
||||
import 'package:didvan/views/home/hashtag/hashtag_state.dart';
|
||||
import 'package:didvan/views/home/home.dart';
|
||||
import 'package:didvan/views/home/home_state.dart';
|
||||
import 'package:didvan/views/home/news/news_details/news_details.dart';
|
||||
import 'package:didvan/views/home/news/news_details/news_details_state.dart';
|
||||
import 'package:didvan/views/home/news/news_state.dart';
|
||||
import 'package:didvan/views/home/radar/radar_details/radar_details.dart';
|
||||
import 'package:didvan/views/home/radar/radar_details/radar_details_state.dart';
|
||||
import 'package:didvan/views/home/radar/radar_state.dart';
|
||||
import 'package:didvan/views/home/settings/about_us/about_us.dart';
|
||||
import 'package:didvan/views/home/settings/bookmarks/bookmarks.dart';
|
||||
import 'package:didvan/views/home/settings/bookmarks/bookmark_state.dart';
|
||||
import 'package:didvan/views/home/settings/bookmarks/filtered_bookmark/filtered_bookmark.dart';
|
||||
import 'package:didvan/views/home/settings/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
|
||||
import 'package:didvan/views/home/settings/direct_list/direct_list.dart';
|
||||
import 'package:didvan/views/home/settings/direct_list/direct_list_state.dart';
|
||||
import 'package:didvan/views/home/settings/general_settings/settings.dart';
|
||||
import 'package:didvan/views/home/settings/general_settings/settings_state.dart';
|
||||
import 'package:didvan/views/home/settings/profile/profile.dart';
|
||||
import 'package:didvan/views/splash/splash.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/widgets/image_cropper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -67,12 +69,6 @@ class RouteGenerator {
|
|||
return _createRoute(
|
||||
const AboutUs(),
|
||||
);
|
||||
case Routes.imageCropper:
|
||||
return _createRoute(
|
||||
ImageCropper(
|
||||
data: settings.arguments as Map<String, dynamic>,
|
||||
),
|
||||
);
|
||||
case Routes.generalSettings:
|
||||
return _createRoute(
|
||||
ChangeNotifierProvider<GeneralSettingsState>(
|
||||
|
|
@ -109,7 +105,7 @@ class RouteGenerator {
|
|||
return _createRoute(
|
||||
ChangeNotifierProvider<DirectState>(
|
||||
create: (context) => DirectState(),
|
||||
child: Direct(id: settings.arguments as int),
|
||||
child: Direct(pageData: settings.arguments as Map<String, dynamic>),
|
||||
),
|
||||
);
|
||||
case Routes.comments:
|
||||
|
|
@ -128,6 +124,14 @@ class RouteGenerator {
|
|||
child: const Bookmarks(),
|
||||
),
|
||||
);
|
||||
case Routes.hashtag:
|
||||
return _createRoute(
|
||||
ChangeNotifierProvider<HashtagState>(
|
||||
create: (context) => HashtagState(),
|
||||
child: Hashtag(tag: settings.arguments as Tag),
|
||||
),
|
||||
);
|
||||
|
||||
case Routes.filteredBookmarks:
|
||||
return _createRoute(
|
||||
ChangeNotifierProvider<FilteredBookmarksState>(
|
||||
|
|
@ -157,7 +161,13 @@ class RouteGenerator {
|
|||
|
||||
static Route _createRoute(page) {
|
||||
return MaterialPageRoute(
|
||||
builder: (context) => page,
|
||||
builder: (context) => Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SafeArea(
|
||||
child: page,
|
||||
top: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ class Routes {
|
|||
static const String bookmarks = '/bookmarks';
|
||||
static const String filteredBookmarks = '/filtered-bookmarks';
|
||||
static const String imageCropper = '/image-cropper';
|
||||
static const String hashtag = '/hashtag';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:didvan/services/media/media.dart';
|
||||
import 'package:didvan/services/storage/storage.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
|
@ -11,8 +10,8 @@ class AppInitializer {
|
|||
StorageService.appDocsDir =
|
||||
(await getApplicationDocumentsDirectory()).path;
|
||||
StorageService.appTempsDir = (await getTemporaryDirectory()).path;
|
||||
MediaService.init();
|
||||
}
|
||||
await _initializeFirebase();
|
||||
}
|
||||
|
||||
static Future<ThemeMode> initilizeSettings() async {
|
||||
|
|
@ -43,29 +42,4 @@ class AppInitializer {
|
|||
return ThemeMode.light;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _initializeFirebase() async {
|
||||
try {
|
||||
await Firebase.initializeApp(
|
||||
options: const FirebaseOptions(
|
||||
apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw',
|
||||
appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543',
|
||||
messagingSenderId: '935017686266',
|
||||
projectId: 'didvan-9b7da',
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
Firebase.app();
|
||||
}
|
||||
final FirebaseMessaging fcm = FirebaseMessaging.instance;
|
||||
await fcm.requestPermission(
|
||||
alert: true,
|
||||
announcement: false,
|
||||
badge: true,
|
||||
carPlay: false,
|
||||
criticalAlert: false,
|
||||
provisional: false,
|
||||
sound: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,59 @@
|
|||
import 'package:didvan/services/network/request.dart';
|
||||
import 'package:didvan/services/network/request_helper.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
|
||||
class MediaService {
|
||||
static final AudioPlayer audioPlayer = AudioPlayer();
|
||||
static String? audioPlayerTag;
|
||||
|
||||
static void init() {
|
||||
audioPlayer.positionStream.listen((event) {
|
||||
if (audioPlayer.duration != null && audioPlayer.duration! < event) {
|
||||
audioPlayer.stop();
|
||||
audioPlayer.seek(const Duration(seconds: 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static Future<void> handleAudioPlayback({
|
||||
required dynamic audioSource,
|
||||
}) async {
|
||||
bool isNetworkAudio = audioSource.runtimeType == String;
|
||||
String tag;
|
||||
if (isNetworkAudio) {
|
||||
tag = audioSource;
|
||||
} else {
|
||||
tag = audioSource.path;
|
||||
}
|
||||
if (audioPlayerTag == tag) {
|
||||
if (audioPlayer.playing) {
|
||||
await audioPlayer.pause();
|
||||
} else {
|
||||
await audioPlayer.play();
|
||||
}
|
||||
} else {
|
||||
await audioPlayer.stop();
|
||||
audioPlayerTag = tag;
|
||||
if (isNetworkAudio) {
|
||||
await audioPlayer.setUrl(
|
||||
RequestHelper.baseUrl +
|
||||
audioSource +
|
||||
'?accessToken=${RequestService.token}',
|
||||
);
|
||||
} else {
|
||||
if (kIsWeb) {
|
||||
await audioPlayer
|
||||
.setUrl(audioSource!.uri.path.replaceAll('%3A', ':'));
|
||||
} else {
|
||||
await audioPlayer.setFilePath(audioSource.path);
|
||||
}
|
||||
}
|
||||
audioPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<XFile?> pickImage({required ImageSource source}) async {
|
||||
final imagePicker = ImagePicker();
|
||||
final XFile? pickedFile = await imagePicker.pickImage(source: source);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||
import 'dart:developer';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http_parser/http_parser.dart' as parser;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
class RequestService {
|
||||
static late String token;
|
||||
|
|
@ -100,19 +99,31 @@ class RequestService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> multipart(XFile file) async {
|
||||
Future<void> multipart({
|
||||
required dynamic file,
|
||||
required String method,
|
||||
required String fileName,
|
||||
required String fieldName,
|
||||
required String mediaFormat,
|
||||
required String mediaExtension,
|
||||
}) async {
|
||||
try {
|
||||
final request = http.MultipartRequest('PUT', Uri.parse(url));
|
||||
final request = http.MultipartRequest(method, Uri.parse(url));
|
||||
_headers.update('Content-Type', (_) => 'multipart/form-data');
|
||||
request.headers.addAll(_headers);
|
||||
final length = await file.length();
|
||||
if (_requestBody != null) {
|
||||
_requestBody!.forEach((key, value) {
|
||||
request.fields.addAll({key.toString(): value.toString()});
|
||||
});
|
||||
}
|
||||
request.files.add(
|
||||
http.MultipartFile(
|
||||
'photo',
|
||||
fieldName,
|
||||
file.readAsBytes().asStream(),
|
||||
length,
|
||||
filename: 'profile-photo',
|
||||
contentType: parser.MediaType('image', 'jpg'),
|
||||
filename: fileName + '.' + mediaExtension,
|
||||
contentType: parser.MediaType(mediaFormat, mediaExtension),
|
||||
),
|
||||
);
|
||||
final streamedResponse = await request
|
||||
|
|
|
|||
|
|
@ -6,19 +6,37 @@ class RequestHelper {
|
|||
static const String _baseUserUrl = baseUrl + '/user';
|
||||
static const String _baseRadarUrl = baseUrl + '/radar';
|
||||
static const String _baseNewsUrl = baseUrl + '/news';
|
||||
static const String _baseDirectUrl = _baseUserUrl + '/direct';
|
||||
|
||||
static const String confirmUsername = _baseUserUrl + '/confirmUsername';
|
||||
static const String login = _baseUserUrl + '/login';
|
||||
static const String directs = _baseUserUrl + '/direct';
|
||||
static const String userInfo = _baseUserUrl + '/info';
|
||||
static const String updateUserProfile = _baseUserUrl + '/profile/photo';
|
||||
static const String updateProfilePhoto = _baseUserUrl + '/profile/photo';
|
||||
static const String checkUsername = _baseUserUrl + '/CheckUsername';
|
||||
static const String updateProfile = _baseUserUrl + '/profile/edit';
|
||||
static String bookmarks({String? type}) =>
|
||||
_baseUserUrl + '/marked/${type ?? ''}';
|
||||
|
||||
static const String directTypes = baseUrl + '/direct/types';
|
||||
static String direct(int id) => _baseUserUrl + '/direct/$id';
|
||||
static String direct(int id) => _baseDirectUrl + '/$id';
|
||||
static String sendDirectMessage(int id) =>
|
||||
_baseDirectUrl + '/$id/sendMessage';
|
||||
static String tag({
|
||||
required List<int> ids,
|
||||
String? type,
|
||||
int? itemId,
|
||||
int? page,
|
||||
int? limit,
|
||||
}) =>
|
||||
baseUrl +
|
||||
'/tag' +
|
||||
_urlConcatGenerator([
|
||||
MapEntry('limit', limit?.toString() ?? '3'),
|
||||
MapEntry('type', type),
|
||||
MapEntry('id', itemId.toString()),
|
||||
MapEntry('tags', _urlListConcatGenerator(ids))
|
||||
]);
|
||||
|
||||
static String markRadar(int id) => _baseRadarUrl + '/$id/mark';
|
||||
static String radarComments(int id) => _baseRadarUrl + '/$id/comments';
|
||||
|
|
@ -96,5 +114,6 @@ class RequestHelper {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import 'package:didvan/constants/assets.dart';
|
|||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/models/view/alert_data.dart';
|
||||
import 'package:didvan/widgets/didvan/button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/views/widgets/didvan/button.dart';
|
||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rive/rive.dart';
|
||||
|
||||
|
|
@ -83,9 +83,7 @@ class ActionSheetUtils {
|
|||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(
|
||||
10,
|
||||
),
|
||||
top: Radius.circular(10),
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
|
|
@ -136,17 +134,18 @@ class ActionSheetUtils {
|
|||
),
|
||||
),
|
||||
if (data.hasDismissButton) const SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: data.smallDismissButton ? 2 : 1,
|
||||
child: DidvanButton(
|
||||
style: ButtonStyleMode.primary,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
data.onConfirmed?.call();
|
||||
},
|
||||
title: data.confrimTitle ?? 'تایید',
|
||||
if (data.hasConfirmButton)
|
||||
Expanded(
|
||||
flex: data.smallDismissButton ? 2 : 1,
|
||||
child: DidvanButton(
|
||||
style: ButtonStyleMode.primary,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
data.onConfirmed?.call();
|
||||
},
|
||||
title: data.confrimTitle ?? 'تایید',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
@ -160,6 +159,7 @@ class ActionSheetUtils {
|
|||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => Dialog(
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: DesignConfig.mediumBorderRadius,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -52,6 +52,31 @@ class DateTimeUtils {
|
|||
return result?.toDateTime().toString();
|
||||
}
|
||||
|
||||
static String timeWithAmPm(String input) {
|
||||
final dateTime = utcToLocalTime(input);
|
||||
bool isAm = true;
|
||||
int hour = 0;
|
||||
int minute = 0;
|
||||
if (dateTime.hour > 12) {
|
||||
isAm = false;
|
||||
hour = dateTime.hour - 12;
|
||||
} else {
|
||||
hour = dateTime.hour;
|
||||
}
|
||||
minute = dateTime.minute;
|
||||
return '$hour:${_timeNormalizer(minute)} ${isAm ? 'ق.ظ' : 'ب.ظ'}';
|
||||
}
|
||||
|
||||
static DateTime utcToLocalTime(String input) {
|
||||
final dateTime = DateTime.parse(input);
|
||||
return dateTime.add(const Duration(hours: 3, minutes: 30));
|
||||
}
|
||||
|
||||
static String _timeNormalizer(int input) {
|
||||
if (input < 10) return '0$input';
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
static String momentGenerator(String input) {
|
||||
final date = DateTime.parse(input);
|
||||
final int seconds = (DateTime.now().difference(date).inSeconds).floor();
|
||||
|
|
@ -67,6 +92,7 @@ class DateTimeUtils {
|
|||
}
|
||||
interval = seconds / 86400;
|
||||
if (interval > 1) {
|
||||
if (interval.floor() == 1) return 'دیروز';
|
||||
return interval.floor().toString() + " روز پیش";
|
||||
}
|
||||
interval = seconds / 3600;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/pages/authentication/authentication_state.dart';
|
||||
import 'package:didvan/pages/authentication/screens/password.dart';
|
||||
import 'package:didvan/pages/authentication/screens/username.dart';
|
||||
import 'package:didvan/pages/authentication/screens/reset_password.dart';
|
||||
import 'package:didvan/pages/authentication/screens/verification.dart';
|
||||
import 'package:didvan/views/authentication/authentication_state.dart';
|
||||
import 'package:didvan/views/authentication/screens/password.dart';
|
||||
import 'package:didvan/views/authentication/screens/reset_password.dart';
|
||||
import 'package:didvan/views/authentication/screens/username.dart';
|
||||
import 'package:didvan/views/authentication/screens/verification.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -55,5 +55,6 @@ class AuthenticationState extends CoreProvier {
|
|||
appState = AppState.failed;
|
||||
ActionSheetUtils.showAlert(AlertData(message: service.errorMessage));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
import 'package:didvan/pages/authentication/authentication_state.dart';
|
||||
import 'package:didvan/pages/authentication/widgets/authentication_layout.dart';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:didvan/providers/server_data_provider.dart';
|
||||
import 'package:didvan/providers/user_provider.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/widgets/didvan/button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/didvan/text_field.dart';
|
||||
import 'package:didvan/views/authentication/authentication_state.dart';
|
||||
import 'package:didvan/views/authentication/widgets/authentication_layout.dart';
|
||||
import 'package:didvan/views/widgets/didvan/button.dart';
|
||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||
import 'package:didvan/views/widgets/didvan/text_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -70,6 +73,8 @@ class _PasswordInputState extends State<PasswordInput> {
|
|||
final userProvider = context.read<UserProvider>();
|
||||
final token = await state.login(userProvider);
|
||||
if (token != null) {
|
||||
log(token);
|
||||
await ServerDataProvider.getData();
|
||||
Navigator.of(context).pushReplacementNamed(Routes.home);
|
||||
}
|
||||
}
|
||||