Rhmn -- 27/05/1403 -- fix notification firebase,

This commit is contained in:
OkaykOrhmn 2024-08-17 10:46:03 +03:30
parent 1365673b93
commit 8b88463efe
52 changed files with 936 additions and 1476 deletions

View File

@ -22,6 +22,9 @@ if (flutterVersionName == null) {
} }
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
// START: FlutterFire Configuration
apply plugin: 'com.google.gms.google-services'
// END: FlutterFire Configuration
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
@ -32,7 +35,8 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
compileSdkVersion 34 namespace "com.didvan.didvanapp"
compileSdk 34
ndkVersion "25.1.8937393" ndkVersion "25.1.8937393"
compileOptions { compileOptions {
@ -53,7 +57,7 @@ android {
applicationId "com.didvan.didvanapp" applicationId "com.didvan.didvanapp"
minSdkVersion 24 minSdkVersion 24
//noinspection ExpiredTargetSdkVersion //noinspection ExpiredTargetSdkVersion
targetSdkVersion 30 targetSdkVersion 31
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }
@ -79,6 +83,22 @@ android {
buildFeatures { buildFeatures {
viewBinding true viewBinding true
} }
splits {
//configure apks based on ABI
abi {
enable true
reset()
include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
universalApk true
}
// density {
// enable true
// reset()
// include "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"
// }
}
} }
flutter { flutter {
@ -86,10 +106,11 @@ flutter {
} }
dependencies { dependencies {
implementation platform('com.google.firebase:firebase-bom:29.1.0') // implementation platform('com.google.firebase:firebase-bom:29.1.0')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
// implementation 'com.github.bumptech.glide:glide:4.16.0'
implementation 'com.squareup.picasso:picasso:2.8' implementation 'com.squareup.picasso:picasso:2.8'
implementation 'com.android.support:cardview-v7:28.0.0' implementation "androidx.room:room-runtime:2.2.5"
implementation "androidx.sqlite:sqlite-framework:2.1.0"
implementation "androidx.sqlite:sqlite:2.1.0"
} }

View File

@ -29,6 +29,13 @@
{ {
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com", "client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
},
{
"client_id": "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.didvan.didvanapp"
}
} }
] ]
} }

View File

@ -8,14 +8,14 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/> <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application <application
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="Didvan" android:label="Didvan"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="true"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">
<receiver <receiver
android:name=".FavWidget" android:name=".FavWidget"
@ -36,8 +36,7 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService" <service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true"/> android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
<activity <activity
@ -49,8 +48,14 @@
android:showWhenLocked="true" android:showWhenLocked="true"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:turnScreenOn="true" android:turnScreenOn="true"
android:exported="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- <!--
Specifies an Android theme to apply to this Activity as soon as Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
@ -82,15 +87,9 @@
<activity <activity
android:name="com.yalantis.ucrop.UCropActivity" android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<service
android:name=".MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.messaging.RECEIVE" />
</intent-filter>
</service>
</application> </application>
</manifest> </manifest>

View File

@ -1,5 +1,10 @@
package com.didvan.didvanapp package com.didvan.didvanapp
import android.app.NotificationChannel
import android.app.NotificationManager
import android.os.Build
import android.os.Bundle
import android.os.PersistableBundle
import androidx.annotation.NonNull import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
@ -9,5 +14,7 @@ class MainActivity: FlutterActivity() {
@Override @Override
override fun configureFlutterEngine(flutterEngine: FlutterEngine) { override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine) GeneratedPluginRegistrant.registerWith(flutterEngine)
} }
} }

View File

@ -3,11 +3,12 @@ buildscript {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven { url "https://jitpack.io" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.4.1' classpath 'com.android.tools.build:gradle:7.4.1'
classpath 'com.google.gms:google-services:4.3.10' classpath 'com.google.gms:google-services:4.3.14'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -16,6 +17,8 @@ allprojects {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven { url "https://jitpack.io" }
} }
} }

View File

@ -1,14 +0,0 @@
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

View File

@ -1,14 +0,0 @@
kind: ExternalService
name: app-test
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: 150Mi
domains:
- name: test.didvan.app

1
firebase.json Normal file
View File

@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"didvan-9b7da","appId":"1:935017686266:android:f9cbc9aba8e3d65ed2d543","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"didvan-9b7da","configurations":{"android":"1:935017686266:android:f9cbc9aba8e3d65ed2d543","ios":"1:935017686266:ios:de47638bd662463fd2d543","web":"1:935017686266:web:a93f7a19bed23c51d2d543"}}}}}}

76
lib/firebase_options.dart Normal file
View File

@ -0,0 +1,76 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyA0HZjKpRuPOi1SC3f_EZTvlS3mcj9UVo0',
appId: '1:935017686266:web:a93f7a19bed23c51d2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
authDomain: 'didvan-9b7da.firebaseapp.com',
storageBucket: 'didvan-9b7da.appspot.com',
measurementId: 'G-80B4H9E8Y0',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw',
appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
storageBucket: 'didvan-9b7da.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCMa-zg_uVhOfTnea5Klz6aPZlgHwVGj7U',
appId: '1:935017686266:ios:de47638bd662463fd2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
storageBucket: 'didvan-9b7da.appspot.com',
iosClientId: '935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com',
iosBundleId: 'com.didvan.didvanapp',
);
}

View File

@ -1,8 +1,10 @@
import 'dart:io'; // ignore_for_file: deprecated_member_use
import 'package:android_intent_plus/android_intent.dart'; import 'package:android_intent_plus/android_intent.dart';
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/firebase_options.dart';
import 'package:didvan/models/notification_data.dart';
import 'package:didvan/models/notification_message.dart'; import 'package:didvan/models/notification_message.dart';
import 'package:didvan/providers/media.dart'; import 'package:didvan/providers/media.dart';
import 'package:didvan/providers/theme.dart'; import 'package:didvan/providers/theme.dart';
@ -10,9 +12,9 @@ import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/route_generator.dart'; import 'package:didvan/routes/route_generator.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart'; import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/notification/awsome/awsome_notification_handler.dart'; import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart'; import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart'; import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
@ -26,43 +28,18 @@ import 'package:provider/provider.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@pragma('vm:entry-point') @pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { Future _initPushNotification(RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await Firebase.initializeApp( if (kDebugMode) {
options: kIsWeb print("background: ${NotificationData.fromJson(message.data).toJson()}");
? const FirebaseOptions( }
apiKey: "AIzaSyA0HZjKpRuPOi1SC3f_EZTvlS3mcj9UVo0", try {
authDomain: "didvan-9b7da.firebaseapp.com", NotificationService.showFirebaseNotification(message);
projectId: "didvan-9b7da", } catch (e) {
storageBucket: "didvan-9b7da.appspot.com", if (kDebugMode) {
messagingSenderId: "935017686266", print(e);
appId: "1:935017686266:web:a93f7a19bed23c51d2d543", }
measurementId: "G-80B4H9E8Y0")
: Platform.isAndroid
? const FirebaseOptions(
apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw',
appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
)
: const FirebaseOptions(
apiKey: 'AIzaSyCMa-zg_uVhOfTnea5Klz6aPZlgHwVGj7U',
appId: '1:935017686266:ios:de47638bd662463fd2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
// iosBundleId: "com.didvan.didvanapp",
// storageBucket: "didvan-9b7da.appspot.com",
// iosClientId:
// "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com"
),
);
print("background: ${NotificationMessage.fromJson(message.data).toJson()}");
try {
await AwsomeNotificationHandler().show(message);
} catch (e) {
rethrow;
} }
return;
} }
@pragma('vm:entry-point') @pragma('vm:entry-point')
@ -80,19 +57,16 @@ Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
try { try {
await AwsomeNotificationHandler().alarm();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
//ignore: deprecated_member_use
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget); HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget); HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
await AppInitializer.initializeFirebase();
FirebaseMessaging.onMessage.listen((RemoteMessage message) { await NotificationService.initializeNotification();
print( FirebaseMessaging.onBackgroundMessage(_initPushNotification);
"forground: ${NotificationMessage.fromJson(message.data).toJson()}"); await Firebase.initializeApp(
AwsomeNotificationHandler().show(message); options: DefaultFirebaseOptions.currentPlatform);
}); await FirebaseApi().initNotification();
} catch (e) { } catch (e) {
rethrow; debugPrint;
} }
runApp(const Didvan()); runApp(const Didvan());
@ -113,7 +87,7 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
@override @override
void initState() { void initState() {
AwsomeNotificationHandler.startListeningNotificationEvents(); NotificationService.startListeningNotificationEvents();
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
@ -123,9 +97,9 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
// MediaService.audioPlayer.dispose(); // MediaService.audioPlayer.dispose();
if(MediaService.currentPodcast != null){ if (MediaService.currentPodcast != null) {
MediaService.audioPlayer.dispose(); MediaService.audioPlayer.dispose();
} }
super.dispose(); super.dispose();
} }

View File

@ -1,11 +1,13 @@
class DayTime{ // ignore_for_file: constant_identifier_names
String hour;
String minute; class DayTime {
Meridiem meridiem; String hour;
String minute;
Meridiem meridiem;
DayTime({this.hour = "1", this.minute = "0", this.meridiem = Meridiem.AM}); DayTime({this.hour = "1", this.minute = "0", this.meridiem = Meridiem.AM});
} }
enum SelectorType { meridiem, hour, minute } enum SelectorType { meridiem, hour, minute }
enum Meridiem { AM, PM } enum Meridiem { AM, PM }

View File

@ -0,0 +1,49 @@
class NotificationData {
String? title;
String? body;
String? largeIcon;
String? bigPicture;
String? id;
String? notificationType;
String? type;
String? link;
String? groupKey;
NotificationData({
this.title,
this.body,
this.largeIcon,
this.bigPicture,
this.id,
this.notificationType,
this.type,
this.link,
this.groupKey,
});
NotificationData.fromJson(Map<String, dynamic> json) {
title = json['title'];
body = json['body'];
largeIcon = json['largeIcon'];
bigPicture = json['bigPicture'];
id = json['id'];
notificationType = json['notificationType'];
type = json['type'];
link = json['link'];
groupKey = json['groupKey'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['title'] = title;
data['body'] = body;
data['largeIcon'] = largeIcon;
data['bigPicture'] = bigPicture;
data['id'] = id;
data['notificationType'] = notificationType;
data['type'] = type;
data['link'] = link;
data['groupKey'] = groupKey;
return data;
}
}

View File

@ -7,17 +7,21 @@ class NotificationMessage {
String? link; String? link;
String? image; String? image;
String? photo; String? photo;
String? groupKey;
String? userId;
NotificationMessage( NotificationMessage({
{this.notificationType, this.notificationType,
this.title, this.title,
this.body, this.body,
this.id, this.id,
this.type, this.type,
this.link, this.link,
this.image, this.image,
this.photo, this.photo,
}); this.groupKey,
this.userId,
});
NotificationMessage.fromJson(Map<String, dynamic> json) { NotificationMessage.fromJson(Map<String, dynamic> json) {
notificationType = json['notificationType']; notificationType = json['notificationType'];
@ -28,6 +32,8 @@ class NotificationMessage {
link = json['link']; link = json['link'];
image = json['image']; image = json['image'];
photo = json['photo']; photo = json['photo'];
groupKey = json['groupKey'];
userId = json['userId'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -40,8 +46,11 @@ class NotificationMessage {
data['link'] = link; data['link'] = link;
data['image'] = image; data['image'] = image;
data['photo'] = photo; data['photo'] = photo;
data['groupKey'] = groupKey;
data['userId'] = userId;
return data; return data;
} }
Map<String, String> toPayload() { Map<String, String> toPayload() {
final Map<String, String> data = <String, String>{}; final Map<String, String> data = <String, String>{};
data['notificationType'] = notificationType!; data['notificationType'] = notificationType!;
@ -52,6 +61,7 @@ class NotificationMessage {
data['link'] = link!; data['link'] = link!;
data['image'] = image!; data['image'] = image!;
data['photo'] = photo!; data['photo'] = photo!;
data['userId'] = userId!;
return data; return data;
} }
} }

View File

@ -4,9 +4,9 @@ import 'package:didvan/models/enums.dart';
import 'package:didvan/models/user.dart'; import 'package:didvan/models/user.dart';
import 'package:didvan/models/view/alert_data.dart'; import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/providers/core.dart'; import 'package:didvan/providers/core.dart';
import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/storage/storage.dart'; import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/action_sheet.dart';
@ -64,9 +64,9 @@ class UserProvider extends CoreProvier {
value: service.result['user']['end'], value: service.result['user']['end'],
); );
AppInitializer.initializeFirebase().then((_) { FirebaseApi()
_registerFirebaseToken(); .initNotification()
}).catchError((err) {}); .then((value) => _registerFirebaseToken());
return true; return true;
} catch (e) { } catch (e) {
@ -78,13 +78,12 @@ class UserProvider extends CoreProvier {
} }
Future<void> _registerFirebaseToken() async { Future<void> _registerFirebaseToken() async {
if (AppInitializer.fcmToken == null) { if (FirebaseApi.fcmToken != null) {
return; final service = RequestService(RequestHelper.firebaseToken, body: {
'token': FirebaseApi.fcmToken,
});
await service.put();
} }
final service = RequestService(RequestHelper.firebaseToken, body: {
'token': AppInitializer.fcmToken,
});
await service.put();
} }
Future<bool> setProfilePhoto(dynamic file) async { Future<bool> setProfilePhoto(dynamic file) async {

View File

@ -16,7 +16,7 @@ import 'package:didvan/views/home/home_state.dart';
import 'package:didvan/views/home/new_statistic/new_statistics_state.dart'; import 'package:didvan/views/home/new_statistic/new_statistics_state.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart'; import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_state.dart'; import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_state.dart';
import 'package:didvan/views/home/new_statistic/stock/newStock_state.dart'; import 'package:didvan/views/home/new_statistic/stock/new_stock_state.dart';
import 'package:didvan/views/home/new_statistic/stock/new_stock.dart'; import 'package:didvan/views/home/new_statistic/stock/new_stock.dart';
import 'package:didvan/views/mentions/mentions.dart'; import 'package:didvan/views/mentions/mentions.dart';
import 'package:didvan/views/mentions/mentions_state.dart'; import 'package:didvan/views/mentions/mentions_state.dart';
@ -48,8 +48,6 @@ import 'package:didvan/views/podcasts/studio_details/studio_details.mobile.dart'
if (dart.library.html) 'package:didvan/views/podcasts/studio_details/studio_details.web.dart'; if (dart.library.html) 'package:didvan/views/podcasts/studio_details/studio_details.web.dart';
import 'package:didvan/views/splash/splash.dart'; import 'package:didvan/views/splash/splash.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:didvan/views/widgets/audio/player_navbar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:home_widget/home_widget.dart'; import 'package:home_widget/home_widget.dart';

View File

@ -1,6 +1,6 @@
import 'dart:io';
import 'package:didvan/main.dart'; import 'package:didvan/main.dart';
import 'package:didvan/models/notification_message.dart';
import 'package:didvan/models/requests/news.dart'; import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.dart'; import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/requests/studio.dart';
@ -10,16 +10,11 @@ import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/storage/storage.dart'; import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/views/home/home_state.dart'; import 'package:didvan/views/home/home_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart'; import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../models/notification_message.dart';
import 'notification/awsome/awsome_notification_handler.dart';
class AppInitializer { class AppInitializer {
static String? fcmToken; static String? fcmToken;
static String? clickAction; static String? clickAction;
@ -32,7 +27,7 @@ class AppInitializer {
} }
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
final studioState = context.read<StudioDetailsState>(); final studioState = context.read<StudioDetailsState>();
MediaService.audioPlayer.isPlaying.listen((event) { MediaService.audioPlayer.playingStream.listen((event) {
if (event && if (event &&
(MediaService.audioPlayerTag?.contains('podcast') ?? false)) { (MediaService.audioPlayerTag?.contains('podcast') ?? false)) {
studioState.handleTracking( studioState.handleTracking(
@ -150,67 +145,30 @@ class AppInitializer {
} }
} }
static Future<void> initializeFirebase() async { static int createNotificationId(NotificationMessage data) {
try { int t = 0;
await Firebase.initializeApp( switch (data.type!) {
options: kIsWeb case "infography":
? const FirebaseOptions( t = 1;
apiKey: "AIzaSyA0HZjKpRuPOi1SC3f_EZTvlS3mcj9UVo0", break;
authDomain: "didvan-9b7da.firebaseapp.com", case "news":
projectId: "didvan-9b7da", t = 2;
storageBucket: "didvan-9b7da.appspot.com",
messagingSenderId: "935017686266", break;
appId: "1:935017686266:web:a93f7a19bed23c51d2d543", case "radar":
measurementId: "G-80B4H9E8Y0") t = 3;
: Platform.isAndroid
? const FirebaseOptions( break;
apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw', case "video":
appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543', t = 4;
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da', break;
) case "podcast":
: const FirebaseOptions( t = 5;
apiKey: 'AIzaSyCMa-zg_uVhOfTnea5Klz6aPZlgHwVGj7U',
appId: '1:935017686266:ios:de47638bd662463fd2d543', break;
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
// iosBundleId: "com.didvan.didvanapp",
// storageBucket: "didvan-9b7da.appspot.com",
// iosClientId:
// "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com"
),
);
} catch (e) {
Firebase.app();
} }
int id = int.parse('${data.userId}${data.id}$t');
final initMsg = await FirebaseMessaging.instance.getInitialMessage(); return id;
if (initMsg != null) {
clickAction = initMsg.data['click_action'].replaceAll(
'navigate-',
'',
);
}
final FirebaseMessaging fcm = FirebaseMessaging.instance;
fcmToken = await fcm.getToken(
vapidKey: kIsWeb
? 'BMXHGd93t_htpS7c62ceuuLVVmia2cEDmqxp46g9Vt0B3OxNMKIqN9nupsUMtv2Vq8Yy2sQGIqgCm9FxUSKvssU'
: null,
);
print("FCM TOKEN: $fcmToken");
// await fcm.subscribeToTopic('general');
await fcm.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
} }
} }

View File

@ -1,133 +0,0 @@
import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
class AudioHandler {
late AudioPlayer _player;
PlayerState? _playerState;
Duration? audioDuration = Duration.zero;
Duration? audioPosition = Duration.zero;
bool isLoading = true;
StreamSubscription? durationSubscriptionS;
StreamSubscription? positionSubscriptionS;
StreamSubscription? playerCompleteSubscriptionS;
StreamSubscription? playerStateChangeSubscriptionS;
AudioPlayer get player => _player;
PlayerState? get playerState => _playerState;
bool get isPlaying => _playerState == PlayerState.playing;
bool get isPaused => _playerState == PlayerState.paused;
String get durationText => audioDuration?.toString().split('.').first ?? '';
String get positionText => audioPosition?.toString().split('.').first ?? '';
AudioHandler(String url) {
_player = AudioPlayer();
_player.setReleaseMode(ReleaseMode.stop);
_player
.play(UrlSource(url))
.then((value) {
_player.pause();
isLoading = false;
_playerState = PlayerState.paused;
});
player.getDuration().then((value) => audioDuration = value);
player.getCurrentPosition().then((value) => audioPosition = value);
}
StreamSubscription? durationSubscription(Function(Duration d) func) {
return durationSubscriptionS = player.onDurationChanged.listen((duration) {
// setState(() => _duration = duration);
audioDuration = duration;
func(duration);
});
}
StreamSubscription? positionSubscription(Function(Duration d) func) {
return positionSubscriptionS = player.onPositionChanged.listen(
(p) {
audioPosition = p;
func(p);
},
);
}
StreamSubscription? playerCompleteSubscription(Function() func) {
return playerCompleteSubscriptionS =
player.onPlayerComplete.listen((event) {
stop();
func();
});
}
StreamSubscription? playerStateChangeSubscription(
Function(PlayerState) func) {
return playerStateChangeSubscriptionS =
player.onPlayerStateChanged.listen((state) {
_playerState = state;
func(state);
});
}
Future<void> play() async {
await _player.resume();
// _playerState = PlayerState.playing;
}
Future<void> pause() async {
await _player.pause();
// _playerState = PlayerState.paused;
}
Future<void> stop() async {
await _player.stop();
// _playerState = PlayerState.stopped;
audioPosition = Duration.zero;
}
// void _initStreams() {
// durationSubscription = player.onDurationChanged.listen((duration) {
// setState(() => _duration = duration);
// });
//
// _positionSubscription = player.onPositionChanged.listen(
// (p) {
// setState(() {
// _position = p;
// for (var i = 0; i < bars.length / 10; i++) {
// if (i <= _position!.inSeconds) {
// bars[i].color = primaryColor;
// }
// }
// });
// },
// );
//
// _playerCompleteSubscription = player.onPlayerComplete.listen((event) {
// setState(() {
// _playerState = PlayerState.stopped;
// _position = Duration.zero;
// });
// });
//
// _playerCompleteSubscription = player.onSeekComplete.listen((event) {
// setState(() {
// print(
// "Complete------------------------------------------------------------");
// });
// });
//
// _playerStateChangeSubscription =
// player.onPlayerStateChanged.listen((state) {
// setState(() {
// _playerState = state;
// });
// });
// }
}

View File

@ -6,16 +6,15 @@ import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart'; import 'package:didvan/services/storage/storage.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:assets_audio_player/assets_audio_player.dart'; import 'package:just_audio/just_audio.dart';
class MediaService { class MediaService {
static final audioPlayer = AssetsAudioPlayer(); static final audioPlayer = AudioPlayer();
static String? audioPlayerTag; static String? audioPlayerTag;
static StudioDetailsData? currentPodcast; static StudioDetailsData? currentPodcast;
static StudioRequestArgs? podcastPlaylistArgs; static StudioRequestArgs? podcastPlaylistArgs;
static Duration? get duration => static Duration? get duration => audioPlayer.duration;
audioPlayer.current.valueOrNull?.audio.duration;
static Future<void> handleAudioPlayback({ static Future<void> handleAudioPlayback({
required dynamic audioSource, required dynamic audioSource,
@ -33,13 +32,17 @@ class MediaService {
isNetworkAudio = false; isNetworkAudio = false;
} }
if (audioPlayerTag == tag) { if (audioPlayerTag == tag) {
await audioPlayer.playOrPause(); if (audioPlayer.playerState ==
PlayerState(true, ProcessingState.ready)) {
await audioPlayer.pause();
} else {
await audioPlayer.play();
}
return; return;
} }
// await audioPlayer.stop(); // await audioPlayer.stop();
audioPlayerTag = tag; audioPlayerTag = tag;
Audio audio;
String source; String source;
if (isNetworkAudio) { if (isNetworkAudio) {
if (isVoiceMessage) { if (isVoiceMessage) {
@ -48,38 +51,39 @@ class MediaService {
} else { } else {
source = audioSource; source = audioSource;
} }
audio = Audio.network( audioPlayer.setUrl(
kIsWeb ? source.replaceAll('%3A', ':') : source, kIsWeb ? source.replaceAll('%3A', ':') : source,
metas: isVoiceMessage tag: isVoiceMessage
? null ? null
: Metas( : {
artist: 'استودیو دیدوان', "artist": 'استودیو دیدوان',
title: currentPodcast?.title ?? '', "title": currentPodcast?.title ?? '',
), },
); );
} else { } else {
audio = Audio.file( audioPlayer.setAsset(
audioSource, audioSource,
metas: isVoiceMessage tag: isVoiceMessage
? null ? null
: Metas( : {
artist: 'استودیو دیدوان', "artist": 'استودیو دیدوان',
title: currentPodcast?.title ?? '', "title": currentPodcast?.title ?? '',
), },
); );
} }
await audioPlayer.open( await audioPlayer.play();
audio, // await audioPlayer.open(
showNotification: !isVoiceMessage, // audio,
notificationSettings: NotificationSettings( // showNotification: !isVoiceMessage,
customStopAction: (_) => resetAudioPlayer(), // notificationSettings: NotificationSettings(
customNextAction: (_) => onTrackChanged?.call(true), // customStopAction: (_) => resetAudioPlayer(),
customPrevAction: (_) => onTrackChanged?.call(false), // customNextAction: (_) => onTrackChanged?.call(true),
), // customPrevAction: (_) => onTrackChanged?.call(false),
); // ),
// );
} catch (e) { } catch (e) {
// resetAudioPlayer(); // resetAudioPlayer();
rethrow; // rethrow;
} }
} }

View File

@ -63,7 +63,7 @@ class RequestService {
headers: _headers, headers: _headers,
) )
.timeout( .timeout(
const Duration(seconds: 10), const Duration(seconds: 30),
) )
.catchError( .catchError(
(e) => throw e, (e) => throw e,

View File

@ -1,44 +0,0 @@
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import '../../../models/notification_message.dart';
class NotificationController {
/// Use this method to detect when a new notification or a schedule is created
@pragma("vm:entry-point")
static Future<void> onNotificationCreatedMethod(
ReceivedNotification receivedNotification) async {
// Your code goes here
}
/// Use this method to detect every time that a new notification is displayed
@pragma("vm:entry-point")
static Future<void> onNotificationDisplayedMethod(
ReceivedNotification receivedNotification) async {
// Your code goes here
}
/// Use this method to detect if the user dismissed a notification
@pragma("vm:entry-point")
static Future<void> onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {
// Your code goes here
}
/// Use this method to detect when the user taps on a notification or action button
@pragma("vm:entry-point")
static Future<void> onActionReceivedMethod(
ReceivedAction receivedAction) async {
NotificationMessage data =
NotificationMessage.fromJson(receivedAction.payload!);
// Your code goes here
HomeWidgetRepository.data = data;
await HomeWidgetRepository.decideWhereToGoNotif();
return;
// MyApp.navigatorKey.currentState?.pushNamedAndRemoveUntil('/notification-page',
// (route) => (route.settings.name != '/notification-page') || route.isFirst,
// arguments: receivedAction);
}
}

View File

@ -1,305 +0,0 @@
import 'dart:io';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../../models/notification_message.dart';
import '../../app_home_widget/home_widget_repository.dart';
import '../../network/request.dart';
import '../../network/request_helper.dart';
import 'awsome_notification_controller.dart';
class AwsomeNotificationHandler {
static ReceivedAction? initialAction;
alarm() async {
AwesomeNotifications().initialize(
// set the icon to null if you want to use the default app icon
null,
[
NotificationChannel(
channelKey: 'alerts',
channelName: 'Alerts',
channelDescription: 'Notification tests as alerts',
playSound: true,
onlyAlertOnce: true,
groupAlertBehavior: GroupAlertBehavior.Children,
importance: NotificationImportance.High,
defaultPrivacy: NotificationPrivacy.Public,
defaultColor: const Color(0xFF007EA7),
criticalAlerts: true,
ledColor: Colors.white,
)
],
// Channel groups are only visual and are not required
// channelGroups: [
// NotificationChannelGroup(
// channelGroupKey: 'basic_channel_group',
// channelGroupName: 'Basic group')
// ],
debug: true);
startListeningNotificationEvents();
// Get initial notification action is optional
initialAction = await AwesomeNotifications()
.getInitialNotificationAction(removeFromActionEvents: false);
if (initialAction?.payload != null) {
NotificationMessage data =
NotificationMessage.fromJson(initialAction!.payload!);
HomeWidgetRepository.data = data;
}
// Your code goes here
AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
//It would be more appropriate if you can show your own dialog
//to the user before requesting the notifications permissons.
if (!isAllowed) {
AwesomeNotifications().requestPermissionToSendNotifications(
permissions: [
NotificationPermission.Alert,
NotificationPermission.Sound,
NotificationPermission.Badge,
NotificationPermission.Vibration,
NotificationPermission.Light,
NotificationPermission.FullScreenIntent,
],
);
}
});
}
@pragma("vm:entry-point")
static Future<void> startListeningNotificationEvents() async {
await AwesomeNotifications().setListeners(
onActionReceivedMethod: NotificationController.onActionReceivedMethod,
onNotificationCreatedMethod:
NotificationController.onNotificationCreatedMethod,
onNotificationDisplayedMethod:
NotificationController.onNotificationDisplayedMethod,
onDismissActionReceivedMethod:
NotificationController.onDismissActionReceivedMethod);
return;
}
show(RemoteMessage message) async {
NotificationMessage notificationMessage =
NotificationMessage.fromJson(message.data);
switch (notificationMessage.notificationType.toString()) {
case "1":
await showNotificationTypeNews(notificationMessage);
break;
case "2":
await showNotificationTypeMessage(notificationMessage);
break;
case "3":
await HomeWidgetRepository.fetchWidget();
break;
case "4":
await showNotificationTypeEmoji(notificationMessage);
break;
}
}
showNotificationTypeNews(NotificationMessage message) async {
DateTime? time = await _getTime();
if (time == null) {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
title: "\u200f ${message.title} \u200f",
body: message.body.toString(),
notificationLayout: NotificationLayout.BigPicture,
largeIcon: message.image.toString(),
bigPicture: message.image.toString(),
category: NotificationCategory.Social,
wakeUpScreen: true,
hideLargeIconOnExpand: true,
payload: message.toPayload(),
color: const Color(0xFF007EA7)),
);
} else {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
title: "\u200f ${message.title} \u200f",
// body: message.body.toString(),
notificationLayout: Platform.isAndroid
? NotificationLayout.Default
: NotificationLayout.BigPicture,
largeIcon: message.image.toString(),
bigPicture: Platform.isAndroid ? null : message.image.toString(),
payload: message.toPayload(),
color: const Color(0xFF007EA7)),
schedule: NotificationCalendar(
hour: time.hour,
minute: time.minute,
));
}
}
showNotificationTypeMessage(NotificationMessage message) async {
DateTime? time = await _getTime();
if (time == null) {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
body:
"<b>${message.title.toString()}</b> ${message.body.toString()}",
largeIcon: message.photo.toString(),
roundedLargeIcon: true,
bigPicture: message.image.toString(),
payload: message.toPayload(),
notificationLayout: NotificationLayout.BigPicture,
color: const Color(0xFF007EA7)),
);
} else {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
body:
"<b>${message.title.toString()}</b> ${message.body.toString()}",
largeIcon: Platform.isAndroid
? message.photo.toString()
: message.image.toString(),
roundedLargeIcon: true,
bigPicture: message.image.toString(),
payload: message.toPayload(),
notificationLayout: NotificationLayout.BigPicture,
color: const Color(0xFF007EA7)),
schedule: NotificationCalendar(
hour: time.hour,
minute: time.minute,
));
}
// actionButtons: [
// NotificationActionButton(
// key: 'REPLY',
// label: 'جواب دادن',
// requireInputText: true,
// actionType: ActionType.SilentAction),
// NotificationActionButton(
// key: 'DISMISS',
// label: 'خوانده شده',
// actionType: ActionType.DismissAction,
// isDangerousOption: true)
// ]
}
showNotificationTypeEmoji(NotificationMessage message) async {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
title: 'Emojis are awes'
'ome too! ${Emojis.animals_lady_beetle}${Emojis.activites_balloon}${Emojis.emotion_red_heart}',
body:
'Simple body with a bunch of Emojis! ${Emojis.transport_police_car} ${Emojis.animals_dog} ${Emojis.flag_UnitedStates} ${Emojis.person_baby}',
largeIcon:
'https://cdn.britannica.com/72/232772-050-4E3D86CC/mind-blown-emoji-head-exploding-emoticon.jpg',
notificationLayout: NotificationLayout.Default,
payload: {
'title': 'Notification Title',
'body': 'Notification Body',
'image': 'path/to/smallImage.png', // Path to small image
'largeImage': 'path/to/largeImage.png', // Path to large image
}));
}
Future<DateTime?> _getTime() async {
final token = await StorageService.getValue(key: 'token');
final service = RequestService(RequestHelper.notificationTime(),
useAutherization: false,
requestHeaders: {
"accept": "*/*",
"Content-Type": "application/json; charset=UTF-8",
'Authorization': 'Bearer $token'
});
await service.httpGet();
if (service.isSuccess) {
final time = service.data('time');
DateTime result = DateTime.now();
if (time.toString().isNotEmpty) {
DateFormat format = DateFormat("HH:mm");
DateTime dateTime = format.parse(time);
result = DateTime.now()
.copyWith(hour: dateTime.hour, minute: dateTime.minute);
return result;
}
}
return null;
}
showNotificationScheduled(NotificationMessage message) async {
DateTime? time = await _getTime();
if (time == null) {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
title: 'Emojis are awes'
'ome too! ${Emojis.animals_lady_beetle}${Emojis.activites_balloon}${Emojis.emotion_red_heart}',
body:
'Simple body with a bunch of Emojis! ${Emojis.transport_police_car} ${Emojis.animals_dog} ${Emojis.flag_UnitedStates} ${Emojis.person_baby}',
largeIcon:
'https://cdn.britannica.com/72/232772-050-4E3D86CC/mind-blown-emoji-head-exploding-emoticon.jpg',
notificationLayout: NotificationLayout.BigPicture,
wakeUpScreen: true,
category: NotificationCategory.Alarm,
payload: {
'title': 'Notification Title',
'body': 'Notification Body',
'image': 'path/to/smallImage.png', // Path to small image
'largeImage': 'path/to/largeImage.png', // Path to large image
}),
);
} else {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
title: 'Emojis are awes'
'ome too! ${Emojis.animals_lady_beetle}${Emojis.activites_balloon}${Emojis.emotion_red_heart}',
body:
'Simple body with a bunch of Emojis! ${Emojis.transport_police_car} ${Emojis.animals_dog} ${Emojis.flag_UnitedStates} ${Emojis.person_baby}',
largeIcon:
'https://cdn.britannica.com/72/232772-050-4E3D86CC/mind-blown-emoji-head-exploding-emoticon.jpg',
notificationLayout: NotificationLayout.BigPicture,
wakeUpScreen: true,
category: NotificationCategory.Alarm,
payload: {
'title': 'Notification Title',
'body': 'Notification Body',
'image': 'path/to/smallImage.png', // Path to small image
'largeImage': 'path/to/largeImage.png', // Path to large image
}),
schedule: NotificationCalendar(
hour: time.hour,
minute: time.minute,
// timezone: await AwesomeNotifications().getLocalTimeZoneIdentifier()
));
}
}
}

View File

@ -1,72 +0,0 @@
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import '../../app_initalizer.dart';
class FirebaseNotificationHandler {
Future<void> initial() async {
try {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: kIsWeb
? const FirebaseOptions(
apiKey: "AIzaSyA0HZjKpRuPOi1SC3f_EZTvlS3mcj9UVo0",
authDomain: "didvan-9b7da.firebaseapp.com",
projectId: "didvan-9b7da",
storageBucket: "didvan-9b7da.appspot.com",
messagingSenderId: "935017686266",
appId: "1:935017686266:web:a93f7a19bed23c51d2d543",
measurementId: "G-80B4H9E8Y0")
: Platform.isAndroid
? const FirebaseOptions(
apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw',
appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
)
: const FirebaseOptions(
apiKey: 'AIzaSyCMa-zg_uVhOfTnea5Klz6aPZlgHwVGj7U',
appId: '1:935017686266:ios:de47638bd662463fd2d543',
messagingSenderId: '935017686266',
projectId: 'didvan-9b7da',
// iosBundleId: "com.didvan.didvanapp",
// storageBucket: "didvan-9b7da.appspot.com",
// iosClientId:
// "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com"
),
);
final initMsg = await FirebaseMessaging.instance.getInitialMessage();
if (initMsg != null) {
AppInitializer.clickAction = initMsg.data['click_action'].replaceAll(
'navigate-',
'',
);
}
// LocalNotificationService.initialize();
NotificationSettings settings =
await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
debugPrint(
'User granted notifications permission: ${settings.authorizationStatus}');
} catch (e) {
if (kDebugMode) {
print(e.toString());
}
}
}
}

View File

@ -0,0 +1,50 @@
import 'package:didvan/models/notification_data.dart';
import 'package:didvan/services/notification/notification_service.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
class FirebaseApi {
final _firebaseMessaging = FirebaseMessaging.instance;
static String? fcmToken;
Future<void> initNotification() async {
await _firebaseMessaging.requestPermission();
try {
fcmToken = await _firebaseMessaging.getToken();
if (kDebugMode) {
print("fCMToken: $fcmToken");
}
} catch (e) {
e.printError();
}
await _firebaseMessaging.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: false,
criticalAlert: true,
provisional: true,
sound: true,
);
FirebaseMessaging.instance.getInitialMessage();
FirebaseMessaging.onMessageOpenedApp.listen((event) {});
FirebaseMessaging.onMessage.listen((event) => handleMessage(event));
}
void handleMessage(RemoteMessage? message) async {
if (message == null) return;
//do ever you want with message
if (kDebugMode) {
print("forground: ${NotificationData.fromJson(message.data).toJson()}");
}
try {
await NotificationService.showFirebaseNotification(message);
} catch (e) {
rethrow;
}
}
}

View File

@ -1,130 +0,0 @@
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart';
import 'package:path_provider/path_provider.dart';
import '../../../models/notification_message.dart';
import '../../../views/widgets/notification/notification_dynamic_dialog.dart';
class LocalNotificationService {
// Instance of Flutternotification plugin
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static void initialize() {
// Initialization setting for android
const InitializationSettings initializationSettingsAndroid =
InitializationSettings(
android: AndroidInitializationSettings("@mipmap/ic_launcher"));
_notificationsPlugin.initialize(
initializationSettingsAndroid,
// to handle event when we receive notification
onDidReceiveNotificationResponse: (details) {
if (details.input != null) {}
},
);
}
static Future<void> display(RemoteMessage message) async {
// To display the notification in device
try {
final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
final BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(
const FilePathAndroidBitmap(
"lib/assets/aaaa.jpg"),
contentTitle: NotificationMessage.fromJson(message.data).title,
htmlFormatContentTitle: true,
summaryText: NotificationMessage.fromJson(message.data).body,
htmlFormatSummaryText: true,
htmlFormatContent: true,
largeIcon: const FilePathAndroidBitmap(
"lib/assets/aaaa.jpg"));
NotificationDetails notificationDetails = const NotificationDetails(
android: AndroidNotificationDetails("Channel Id", "Main Channel",
groupKey: "gfg",
color: Colors.white,
importance: Importance.max,
playSound: true,
priority: Priority.high),
);
if (message.notification == null) {
final NotificationMessage notificationModel =
NotificationMessage.fromJson(message.data);
await _notificationsPlugin.show(id, notificationModel.title,
notificationModel.body, notificationDetails,
payload: message.data['route']);
} else {
await _notificationsPlugin.show(id, message.notification?.title,
message.notification?.body, notificationDetails,
payload: message.data['route']);
}
} catch (e) {
debugPrint(e.toString());
}
}
void messageListener(BuildContext context) {
// Either you can pass buildcontext or you
// can take a context from navigator key
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message in the foreground!');
print('Message data: ${message.data}');
print(
'Message also contained a notification: so it will pop up ${message.notification!.body}');
showDialog(
context: context,
// context: navigatorKey!.currentContext!,
builder: ((BuildContext context) {
return NotificationDynamicDialog(
title: message.notification!.title,
body: message.notification!.body);
}));
});
}
static Future<String> _downloadAndSaveFile(String url, String fileName) async {
final Directory directory = await getApplicationDocumentsDirectory();
final String filePath = '${directory.path}/$fileName';
final Response response = await get(Uri.parse(url));
final File file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
static Future<void> showBigPictureNotification() async {
final String largeIconPath = await _downloadAndSaveFile(
'https://via.placeholder.com/48x48', 'largeIcon');
final String bigPicturePath = await _downloadAndSaveFile(
'https://via.placeholder.com/400x800', 'bigPicture');
final BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
largeIcon: FilePathAndroidBitmap(largeIconPath),
contentTitle: 'overridden <b>big</b> content title',
htmlFormatContentTitle: true,
summaryText: 'summary <i>text</i>',
htmlFormatSummaryText: true);
final AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'big text channel id', 'big text channel name',
channelDescription: 'big text channel description',
largeIcon: FilePathAndroidBitmap(largeIconPath),
channelShowBadge: false,
styleInformation: bigPictureStyleInformation);
final NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await _notificationsPlugin.show(
0, 'big text title', 'silent body', platformChannelSpecifics);
}
}

View File

@ -1,40 +0,0 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
void showNotificationAndroid(String title, String value) async {
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('channel_id', 'Channel Name',
channelDescription: 'Channel Description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
int notificationId = 1;
const NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
await FlutterLocalNotificationsPlugin().show(
notificationId, title, value, notificationDetails,
payload: 'Not present');
}
void showNotificationIos(String title, String value) async {
DarwinNotificationDetails iOSPlatformChannelSpecifics = DarwinNotificationDetails(
presentAlert: true,
// Present an alert when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
presentBadge: true,
// Present the badge number when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
presentSound: true,
// Play a sound when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
subtitle: title,
//Secondary description (only from iOS 10 onwards)
threadIdentifier: value);
int notificationId = 1;
NotificationDetails platformChannelSpecifics =
NotificationDetails(iOS: iOSPlatformChannelSpecifics);
await FlutterLocalNotificationsPlugin().show(
notificationId, title, value, platformChannelSpecifics,
payload: 'Not present');
}

View File

@ -0,0 +1,166 @@
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:didvan/models/notification_message.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NotificationService {
static Future<void> initializeNotification() async {
await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelKey: 'content',
channelGroupKey: 'content',
channelName: 'content Notification',
channelDescription: 'Notification channel',
defaultColor: Colors.blueAccent,
ledColor: Colors.white,
importance: NotificationImportance.Max,
channelShowBadge: true,
onlyAlertOnce: true,
playSound: true,
criticalAlerts: true),
// NotificationChannel(
// channelKey: 'mention',
// channelGroupKey: 'mention',
// channelName: 'mention Notification',
// channelDescription: 'Notification channel',
// defaultColor: Colors.blueAccent,
// ledColor: Colors.white,
// importance: NotificationImportance.Max,
// channelShowBadge: true,
// onlyAlertOnce: true,
// playSound: true,
// criticalAlerts: true),
],
// channelGroups: [
// NotificationChannelGroup(
// channelGroupKey: 'mention', channelGroupName: 'Group mention'),
// ],
debug: true);
await AwesomeNotifications()
.isNotificationAllowed()
.then((isAllowed) async {
if (!isAllowed) {
await AwesomeNotifications().requestPermissionToSendNotifications();
}
});
await startListeningNotificationEvents();
}
@pragma("vm:entry-point")
static Future<void> startListeningNotificationEvents() async {
await AwesomeNotifications().setListeners(
onActionReceivedMethod: _onActionReceivedMethod,
onDismissActionReceivedMethod: _onDismissActionReceivedMethod,
);
return;
}
@pragma('vm:entry-point')
static Future<void> _onActionReceivedMethod(
ReceivedAction receivedAction) async {
try {
NotificationMessage data =
NotificationMessage.fromJson(receivedAction.payload!);
HomeWidgetRepository.data = data;
await HomeWidgetRepository.decideWhereToGoNotif();
await StorageService.delete(
key: 'notification${AppInitializer.createNotificationId(data)}');
} catch (e) {
e.printError();
}
return;
}
@pragma('vm:entry-point')
static Future<void> _onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {
try {
NotificationMessage data =
NotificationMessage.fromJson(receivedAction.payload!);
if (data.notificationType!.contains('2')) {
await StorageService.delete(
key: 'notification${AppInitializer.createNotificationId(data)}');
}
} catch (e) {
e.printError();
}
}
// @pragma('vm:entry-point')
// static Future<void> _onNotificationCreatedMethod(
// ReceivedNotification receivedNotification) async {
// }
// static Future<void> _onNotificationDisplayedMethod(
// ReceivedNotification receivedNotification) async {}
static Future<void> showFirebaseNotification(RemoteMessage message) async {
try {
final data = NotificationMessage.fromJson(message.data);
if (data.notificationType!.contains('3')) {
HomeWidgetRepository.fetchWidget();
return;
}
NotificationService.showNotification(data);
} catch (e) {
e.printError();
}
}
static Future<void> showNotification(NotificationMessage data) async {
if (data.notificationType!.contains('2')) {
final String? storedValue = await StorageService.getValue(
key: 'notification${AppInitializer.createNotificationId(data)}');
if (storedValue != null) {
AwesomeNotifications()
.dismiss(AppInitializer.createNotificationId(data));
data.body = '${data.body}\n$storedValue';
}
}
await AwesomeNotifications().createNotification(
content: NotificationContent(
id: data.notificationType!.contains('1')
? DateTime.now().millisecondsSinceEpoch ~/ 1000
: AppInitializer.createNotificationId(data),
channelKey:
// data.notificationType!.contains('1') ?
'content'
// : 'mention'
,
title: data.title,
body: data.body,
actionType: ActionType.Default,
notificationLayout: data.notificationType!.contains('1')
? NotificationLayout.BigPicture
: NotificationLayout.Messaging,
summary:
data.notificationType!.contains('1') ? "خبر جدید" : "منشن شدید",
bigPicture: data.image,
largeIcon: data.photo,
hideLargeIconOnExpand: data.notificationType!.contains('1'),
displayOnBackground: true,
displayOnForeground: true,
wakeUpScreen: true,
icon: 'resource://drawable/logo',
roundedLargeIcon: data.notificationType!.contains('2'),
payload: data.toPayload()),
);
if (data.notificationType!.contains('2')) {
await StorageService.setValue(
key: 'notification${AppInitializer.createNotificationId(data)}',
value: data.body);
}
}
}

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/views/authentication/authentication_state.dart'; import 'package:didvan/views/authentication/authentication_state.dart';
import 'package:didvan/views/authentication/screens/password.dart'; import 'package:didvan/views/authentication/screens/password.dart';

View File

@ -79,7 +79,8 @@ class _PasswordInputState extends State<PasswordInput> {
await ServerDataProvider.getData(); await ServerDataProvider.getData();
if (mounted) { if (mounted) {
Navigator.of(context).pushReplacementNamed(Routes.home); Future.delayed(Duration.zero,
() => Navigator.of(context).pushReplacementNamed(Routes.home));
} }
_showResetPasswordDialog(); _showResetPasswordDialog();

View File

@ -54,14 +54,19 @@ class _ResetPasswordState extends State<ResetPassword> {
.read<AuthenticationState>() .read<AuthenticationState>()
.resetPassword(_password); .resetPassword(_password);
if (!mounted) return; if (!mounted) return;
if (result && context.read<UserProvider>().isAuthenticated) { Future.delayed(
Navigator.of(context).pop(); Duration.zero,
Navigator.of(context).pop(); () {
return; if (result && context.read<UserProvider>().isAuthenticated) {
} Navigator.of(context).pop();
Navigator.of(context).pushNamed( Navigator.of(context).pop();
Routes.authenticaion, return;
arguments: false, }
Navigator.of(context).pushNamed(
Routes.authenticaion,
arguments: false,
);
},
); );
}, },
title: 'تغییر رمز عبور', title: 'تغییر رمز عبور',

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';

View File

@ -84,15 +84,20 @@ class CustomizeCategoryState extends CoreProvier {
); );
await service.put(); await service.put();
if (service.isSuccess) { if (service.isSuccess) {
if (toTimer) { Future.delayed(
Navigator.of(context).pushNamed(Routes.notificationTime, Duration.zero,
arguments: {"fromFav": toTimer}); () {
} else { if (toTimer) {
Navigator.of(context).pop(); Navigator.of(context).pushNamed(Routes.notificationTime,
ActionSheetUtils.showAlert(AlertData( arguments: {"fromFav": toTimer});
message: "تغییرات شما با موفقیت اعمال شد.", } else {
aLertType: ALertType.success)); Navigator.of(context).pop();
} ActionSheetUtils.showAlert(AlertData(
message: "تغییرات شما با موفقیت اعمال شد.",
aLertType: ALertType.success));
}
},
);
appState = AppState.idle; appState = AppState.idle;
await HomeWidgetRepository.fetchWidget(); await HomeWidgetRepository.fetchWidget();
@ -112,16 +117,21 @@ class CustomizeCategoryState extends CoreProvier {
); );
await service.put(); await service.put();
if (service.isSuccess) { if (service.isSuccess) {
if (toTimer) { Future.delayed(
Navigator.of(context).pushNamed(Routes.notificationTime, Duration.zero,
arguments: {"fromFav": toTimer}); () {
} else { if (toTimer) {
Navigator.of(context).pop(); Navigator.of(context).pushNamed(Routes.notificationTime,
Navigator.of(context).pop(); arguments: {"fromFav": toTimer});
ActionSheetUtils.showAlert(AlertData( } else {
message: "تغییرات شما با موفقیت اعمال شد.", Navigator.of(context).pop();
aLertType: ALertType.success)); Navigator.of(context).pop();
} ActionSheetUtils.showAlert(AlertData(
message: "تغییرات شما با موفقیت اعمال شد.",
aLertType: ALertType.success));
}
},
);
appState = AppState.idle; appState = AppState.idle;
await HomeWidgetRepository.fetchWidget(); await HomeWidgetRepository.fetchWidget();

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';

View File

@ -1,6 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/requests/studio.dart';
@ -10,6 +9,7 @@ import 'package:didvan/views/widgets/audio/audio_slider.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart'; import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class AudioWidget extends StatelessWidget { class AudioWidget extends StatelessWidget {
@ -28,7 +28,7 @@ class AudioWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.isPlaying, stream: MediaService.audioPlayer.playingStream,
builder: (context, snapshot) { builder: (context, snapshot) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -36,12 +36,18 @@ class AudioWidget extends StatelessWidget {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 12), padding: const EdgeInsets.only(top: 12),
child: AudioSlider( child: Row(
tag: audioMetaData != null children: [
? '${audioMetaData!.type}-$id' Expanded(
: 'message-$id', child: AudioSlider(
duration: audioMetaData?.duration, tag: audioMetaData != null
showTimer: true, ? '${audioMetaData!.type}-$id'
: 'message-$id',
duration: audioMetaData?.duration,
showTimer: true,
),
),
],
), ),
), ),
), ),
@ -79,11 +85,11 @@ class _AudioControllerButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<PlayingAudio?>( return StreamBuilder<PlayerState>(
stream: MediaService.audioPlayer.onReadyToPlay, stream: MediaService.audioPlayer.playerStateStream,
builder: (context, snapshot) { builder: (context, snapshot) {
return DidvanIconButton( return DidvanIconButton(
icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying icon: MediaService.audioPlayer.playing && _nowPlaying
? DidvanIcons.pause_circle_solid ? DidvanIcons.pause_circle_solid
: DidvanIcons.play_circle_solid, : DidvanIcons.play_circle_solid,
gestureSize: 36, gestureSize: 36,
@ -100,7 +106,7 @@ class _AudioControllerButton extends StatelessWidget {
} }
if (snapshot.data == null && if (snapshot.data == null &&
_nowPlaying && _nowPlaying &&
MediaService.audioPlayer.isPlaying.value) { MediaService.audioPlayer.playing) {
return; return;
} }
if (audioMetaData != null) { if (audioMetaData != null) {

View File

@ -1,17 +1,23 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/models/notification_message.dart'; import 'package:didvan/models/notification_message.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/providers/theme.dart'; import 'package:didvan/providers/theme.dart';
import 'package:didvan/services/app_initalizer.dart'; import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/notification/awsome/awsome_notification_handler.dart'; import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/home/bookmarks/bookmarks.dart'; import 'package:didvan/views/home/bookmarks/bookmarks.dart';
import 'package:didvan/views/home/categories/categories_page.dart'; import 'package:didvan/views/home/categories/categories_page.dart';
import 'package:didvan/views/home/main/main_page.dart'; import 'package:didvan/views/home/main/main_page.dart';
import 'package:didvan/views/home/home_state.dart'; import 'package:didvan/views/home/home_state.dart';
import 'package:didvan/views/home/new_statistic/new_statistic.dart'; import 'package:didvan/views/home/new_statistic/new_statistic.dart';
import 'package:didvan/views/home/search/search.dart'; import 'package:didvan/views/home/search/search.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/logo_app_bar.dart'; import 'package:didvan/views/widgets/logo_app_bar.dart';
import 'package:didvan/views/widgets/didvan/bnb.dart'; import 'package:didvan/views/widgets/didvan/bnb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../services/app_home_widget/home_widget_repository.dart'; import '../../services/app_home_widget/home_widget_repository.dart';
@ -28,7 +34,7 @@ class _HomeState extends State<Home>
@override @override
void initState() { void initState() {
AwsomeNotificationHandler.startListeningNotificationEvents(); NotificationService.startListeningNotificationEvents();
final state = context.read<HomeState>(); final state = context.read<HomeState>();
DesignConfig.updateSystemUiOverlayStyle(); DesignConfig.updateSystemUiOverlayStyle();
@ -59,28 +65,50 @@ class _HomeState extends State<Home>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: const LogoAppBar(), appBar: const LogoAppBar(),
body: Consumer<HomeState>( body: WillPopScope(
builder: (context, state, child) => AnimatedCrossFade( onWillPop: () async {
duration: DesignConfig.lowAnimationDuration, if (context.read<HomeState>().tabController.index == 0) {
crossFadeState: state.filtering ActionSheetUtils.openDialog(
? CrossFadeState.showSecond data: ActionSheetData(
: CrossFadeState.showFirst, content: const DidvanText(
firstChild: SizedBox( 'آیا قصد خروج از برنامه را دارید؟',
height: MediaQuery.of(context).size.height, ),
width: MediaQuery.of(context).size.width, onConfirmed: () {
child: TabBarView( SystemChannels.platform.invokeMethod('SystemNavigator.pop');
physics: const NeverScrollableScrollPhysics(), },
controller: _tabController, isBackgroundDropBlur: true,
children: const [ confrimTitle: 'بله',
MainPage(), onDismissed: Navigator.of(ActionSheetUtils.context).pop,
NewStatistic(), dismissTitle: 'خیر',
//Statistic(), ));
CategoriesPage(), } else {
Bookmarks(), _tabController.animateTo(0);
], }
return false;
},
child: Consumer<HomeState>(
builder: (context, state, child) => AnimatedCrossFade(
duration: DesignConfig.lowAnimationDuration,
crossFadeState: state.filtering
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
firstChild: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: TabBarView(
physics: const NeverScrollableScrollPhysics(),
controller: _tabController,
children: const [
MainPage(),
NewStatistic(),
//Statistic(),
CategoriesPage(),
Bookmarks(),
],
),
), ),
secondChild: const SearchPage(),
), ),
secondChild: const SearchPage(),
), ),
), ),
bottomNavigationBar: Consumer<HomeState>( bottomNavigationBar: Consumer<HomeState>(

View File

@ -3,7 +3,7 @@ import 'dart:async';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/views/home/new_statistic/stock/exchange.dart'; import 'package:didvan/views/home/new_statistic/stock/exchange.dart';
import 'package:didvan/views/home/new_statistic/stock/metal.dart'; import 'package:didvan/views/home/new_statistic/stock/metal.dart';
import 'package:didvan/views/home/new_statistic/stock/newStock_state.dart'; import 'package:didvan/views/home/new_statistic/stock/new_stock_state.dart';
import 'package:didvan/views/home/new_statistic/stock/total_type3.dart'; import 'package:didvan/views/home/new_statistic/stock/total_type3.dart';
import 'package:didvan/views/home/new_statistic/stock/total_type4.dart'; import 'package:didvan/views/home/new_statistic/stock/total_type4.dart';
import 'package:didvan/views/home/new_statistic/stock/total_type6.dart'; import 'package:didvan/views/home/new_statistic/stock/total_type6.dart';

View File

@ -17,8 +17,6 @@ class NewStockState extends CoreProvier {
int lastPage = 1; int lastPage = 1;
List contents = []; List contents = [];
int? length; int? length;
int? length_type3;
int? length_type4;
Future<void> getStock({required int page}) async { Future<void> getStock({required int page}) async {
this.page = page; this.page = page;

View File

@ -53,8 +53,7 @@ class _MentionsState extends State<Mentions> {
bool get _isPage => widget.pageData['isPage'] != false; bool get _isPage => widget.pageData['isPage'] != false;
void _onChange(MentionsState state, value) { void _onChange(MentionsState state, String value) {
state.searchUsers = value;
state.getUsersMention(context.read<UserProvider>().user.id); state.getUsersMention(context.read<UserProvider>().user.id);
state.update(); state.update();
} }
@ -159,6 +158,7 @@ class _MentionsState extends State<Mentions> {
children: [ children: [
Expanded( Expanded(
child: TextField( child: TextField(
controller: mentionsState.searchUsers,
focusNode: _focusNodeMention, focusNode: _focusNodeMention,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.send, textInputAction: TextInputAction.send,
@ -183,6 +183,8 @@ class _MentionsState extends State<Mentions> {
icon: DidvanIcons.close_regular, icon: DidvanIcons.close_regular,
onPressed: () { onPressed: () {
mentionsState.showUsersForMentionsLayout = false; mentionsState.showUsersForMentionsLayout = false;
mentionsState.searchUsers.text = '';
mentionsState.update(); mentionsState.update();
}), }),
], ],
@ -233,12 +235,6 @@ class _MessageBoxState extends State<_MessageBox> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final state = context.watch<MentionsState>(); final state = context.watch<MentionsState>();
void onCheckBoxChange(bool b) {
state.hideMentionedUser = b;
state.update();
}
return Column( return Column(
children: [ children: [
AnimatedVisibility( AnimatedVisibility(

View File

@ -12,8 +12,8 @@ import 'package:provider/provider.dart';
class MentionsState extends CoreProvier { class MentionsState extends CoreProvier {
TextEditingController textFieldController = TextEditingController(); TextEditingController textFieldController = TextEditingController();
TextEditingController searchUsers = TextEditingController();
List<UsersMention> mentionedUsers = []; List<UsersMention> mentionedUsers = [];
String searchUsers = '';
int? commentId; int? commentId;
UserOverview? replyingTo; UserOverview? replyingTo;
bool showReplyBox = false; bool showReplyBox = false;
@ -51,7 +51,7 @@ class MentionsState extends CoreProvier {
Future<void> getUsersMention(int id) async { Future<void> getUsersMention(int id) async {
final service = RequestService( final service = RequestService(
RequestHelper.usersMentions(searchUsers), RequestHelper.usersMentions(searchUsers.text),
); );
await service.httpGet(); await service.httpGet();
@ -116,7 +116,7 @@ class MentionsState extends CoreProvier {
mentionedUsers.clear(); mentionedUsers.clear();
users.clear(); users.clear();
searchUsers = ''; searchUsers.text = '';
textFieldController.text = ''; textFieldController.text = '';
showUsersForMentionsLayout = false; showUsersForMentionsLayout = false;

View File

@ -15,7 +15,7 @@ class NotificationTimeState extends CoreProvier {
bool isAnytime = false; bool isAnytime = false;
bool fromFav = false; bool fromFav = false;
late void Function() onTimeChanged = (){}; late void Function() onTimeChanged = () {};
Future<void> getTime() async { Future<void> getTime() async {
appState = AppState.busy; appState = AppState.busy;
@ -53,15 +53,22 @@ class NotificationTimeState extends CoreProvier {
await service.put(); await service.put();
if (service.isSuccess) { if (service.isSuccess) {
onTimeChanged(); onTimeChanged();
Future.delayed(
Duration.zero,
() {
if (fromFav) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
} else {
Navigator.of(context).pop();
}
},
);
if (fromFav) { ActionSheetUtils.showAlert(AlertData(
Navigator.of(context).pop(); message: "تغییرات شما با موفقیت اعمال شد.",
Navigator.of(context).pop(); aLertType: ALertType.success));
Navigator.of(context).pop();
} else {
Navigator.of(context).pop();
}
ActionSheetUtils.showAlert(AlertData(message: "تغییرات شما با موفقیت اعمال شد.",aLertType: ALertType.success));
appState = AppState.idle; appState = AppState.idle;
return; return;

View File

@ -1,6 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'package:better_player/better_player.dart'; import 'package:chewie/chewie.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart'; import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
@ -11,6 +12,7 @@ import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:video_player/video_player.dart';
class StudioDetails extends StatefulWidget { class StudioDetails extends StatefulWidget {
final Map<String, dynamic> pageData; final Map<String, dynamic> pageData;
@ -23,18 +25,17 @@ class StudioDetails extends StatefulWidget {
class _StudioDetailsState extends State<StudioDetails> { class _StudioDetailsState extends State<StudioDetails> {
int _currentlyPlayingId = 0; int _currentlyPlayingId = 0;
late BetterPlayerController _betterPlayerController; late VideoPlayerController _videoPlayerController;
late final ChewieController _chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoPlay: true,
looping: true,
aspectRatio: 16 / 9,
materialProgressColors: ChewieProgressColors(
playedColor: Theme.of(context).colorScheme.title,
handleColor: Theme.of(context).colorScheme.title));
@override @override
void initState() { void initState() {
_betterPlayerController = BetterPlayerController(
const BetterPlayerConfiguration(
aspectRatio: 16 / 9,
showPlaceholderUntilPlay: true,
autoDispose: false,
fullScreenAspectRatio: 16 / 9,
),
);
final state = context.read<StudioDetailsState>(); final state = context.read<StudioDetailsState>();
state.args = widget.pageData['args']; state.args = widget.pageData['args'];
@ -115,7 +116,12 @@ class _StudioDetailsState extends State<StudioDetails> {
height: d.size.height - d.padding.top - 56, height: d.size.height - d.padding.top - 56,
child: Column( child: Column(
children: [ children: [
BetterPlayer(controller: _betterPlayerController), AspectRatio(
aspectRatio: 16 / 9,
child: Chewie(
controller: _chewieController,
),
),
Expanded( Expanded(
child: StudioDetailsWidget( child: StudioDetailsWidget(
onMarkChanged: (id, value) => widget onMarkChanged: (id, value) => widget
@ -135,29 +141,17 @@ class _StudioDetailsState extends State<StudioDetails> {
} }
Future<void> _handleVideoPlayback(state) async { Future<void> _handleVideoPlayback(state) async {
final betterPlayerDataSource = BetterPlayerDataSource( _videoPlayerController = VideoPlayerController.network(
BetterPlayerDataSourceType.network,
state.studio.link, state.studio.link,
videoFormat: BetterPlayerVideoFormat.hls, )..initialize().then((value) async {});
);
await _betterPlayerController.clearCache();
await _betterPlayerController.setupDataSource(betterPlayerDataSource);
_betterPlayerController.setBetterPlayerControlsConfiguration(
BetterPlayerControlsConfiguration(
enablePlaybackSpeed: false,
enableSubtitles: false,
enableAudioTracks: false,
progressBarPlayedColor: Theme.of(context).colorScheme.secondary,
progressBarHandleColor: Theme.of(context).colorScheme.secondary,
),
);
_currentlyPlayingId = state.studio.id; _currentlyPlayingId = state.studio.id;
} }
@override @override
void dispose() { void dispose() {
_betterPlayerController.pause(); _videoPlayerController.pause();
_betterPlayerController.dispose(); _videoPlayerController.dispose();
_chewieController.dispose();
super.dispose(); super.dispose();
} }
} }

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';

View File

@ -126,7 +126,7 @@ class StudioDetailsState extends CoreProvier {
// MediaService.resetAudioPlayer(); // MediaService.resetAudioPlayer();
update(); update();
appState = AppState.idle; appState = AppState.idle;
rethrow; // rethrow;
} }
} }
@ -148,7 +148,7 @@ class StudioDetailsState extends CoreProvier {
); );
if (nextStudio != null && !_positionListenerActivated) { if (nextStudio != null && !_positionListenerActivated) {
_positionListenerActivated = true; _positionListenerActivated = true;
MediaService.audioPlayer.currentPosition.listen((event) { MediaService.audioPlayer.positionStream.listen((event) {
if (MediaService.audioPlayerTag?.contains('message') == true) { if (MediaService.audioPlayerTag?.contains('message') == true) {
return; return;
} }

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';

View File

@ -1,15 +1,10 @@
import 'package:day_night_time_picker/lib/constants.dart';
import 'package:day_night_time_picker/lib/daynight_timepicker.dart';
import 'package:day_night_time_picker/lib/state/time.dart';
import 'package:didvan/config/design_config.dart'; 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/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/providers/theme.dart'; import 'package:didvan/providers/theme.dart';
import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/utils/date_time.dart';
import 'package:didvan/views/profile/general_settings/settings_state.dart'; import 'package:didvan/views/profile/general_settings/settings_state.dart';
import 'package:didvan/views/widgets/menu_item.dart'; import 'package:didvan/views/widgets/menu_item.dart';
import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/card.dart';
@ -40,9 +35,6 @@ class _GeneralSettingsState extends State<GeneralSettings> {
return 'کوچک'; return 'کوچک';
} }
int _intervalStart = 0;
int _intervalEnd = 24;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -230,91 +222,6 @@ class _GeneralSettingsState extends State<GeneralSettings> {
); );
} }
Future<void> _pickTimeRange(BuildContext context) async {
final state = context.read<GeneralSettingsState>();
_intervalStart = state.notificationTimeRange[0];
_intervalEnd = state.notificationTimeRange[1];
ActionSheetUtils.showBottomSheet(
data: ActionSheetData(
content: Row(
children: [
const SizedBox(width: 8),
Expanded(child: _timeFieldBuilder(context, 0)),
const SizedBox(width: 8),
const DidvanText('-'),
const SizedBox(width: 8),
Expanded(child: _timeFieldBuilder(context, 1)),
const SizedBox(width: 8),
],
),
title: 'زمان دریافت اعلان',
titleIcon: DidvanIcons.notification_regular,
onConfirmed: () {
state.notificationTimeRange = [_intervalStart, _intervalEnd];
},
),
);
}
Widget _timeFieldBuilder(BuildContext context, int index) {
final GeneralSettingsState state = context.read<GeneralSettingsState>();
return ChangeNotifierProvider.value(
value: state,
child: StatefulBuilder(
builder: (context, setState) => GestureDetector(
onTap: () async {
await _openTimePicker(context, index);
setState(() {});
},
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.splash,
borderRadius: DesignConfig.mediumBorderRadius,
border: Border.all(
color: Theme.of(context).colorScheme.border,
),
),
child: DidvanText(DateTimeUtils.normalizeTimeDuration(
Duration(minutes: index == 0 ? _intervalStart : _intervalEnd),
)),
),
),
),
);
}
Future<void> _openTimePicker(BuildContext context, int index) async {
await Navigator.of(context).push(
showPicker(
okText: 'تایید',
cancelText: 'بازگشت',
accentColor: Theme.of(context).colorScheme.primary,
okStyle: Theme.of(context).textTheme.bodyMedium!,
cancelStyle: Theme.of(context).textTheme.bodyMedium!,
unselectedColor: Theme.of(context).colorScheme.text,
blurredBackground: true,
disableMinute: true,
hourLabel: ':',
minuteLabel: '',
is24HrFormat: true,
iosStylePicker: true,
minuteInterval: TimePickerInterval.FIFTEEN,
context: context,
value: Time(hour: 0, minute: 0),
themeData: Theme.of(context),
onChange: (time) {
if (index == 0) {
_intervalStart = time.hour;
return;
}
_intervalEnd = time.hour;
},
),
);
}
Widget _themeItem( Widget _themeItem(
BuildContext context, GeneralSettingsState state, String brightness) { BuildContext context, GeneralSettingsState state, String brightness) {
final bool isDarkTheme = brightness == 'dark'; final bool isDarkTheme = brightness == 'dark';

View File

@ -1,7 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
@ -21,6 +20,7 @@ import 'package:didvan/views/widgets/ink_wrapper.dart';
import 'package:didvan/views/widgets/item_title.dart'; import 'package:didvan/views/widgets/item_title.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class AudioPlayerWidget extends StatelessWidget { class AudioPlayerWidget extends StatelessWidget {
@ -59,10 +59,55 @@ class AudioPlayerWidget extends StatelessWidget {
const SizedBox(height: 16), const SizedBox(height: 16),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: AudioSlider( child: Row(
tag: 'podcast-${podcast.id}', children: [
showTimer: true, StreamBuilder<double>(
duration: podcast.duration, stream: MediaService.audioPlayer.speedStream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
}
return Column(
children: [
PopupMenuButton(
child: Container(
width: 46,
alignment: Alignment.center,
margin: const EdgeInsets.fromLTRB(12, 0, 0, 46),
padding: const EdgeInsets.only(top: 2),
decoration: BoxDecoration(
borderRadius: DesignConfig.mediumBorderRadius,
border: Border.all(
color:
Theme.of(context).colorScheme.title)),
child: DidvanText(
'${snapshot.data!.toString().replaceAll('.0', '')}X'),
),
onSelected: (value) async {
await MediaService.audioPlayer.setSpeed(value);
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry>[
popUpSpeed(value: 0.5),
popUpSpeed(value: 0.75),
popUpSpeed(value: 1.0),
popUpSpeed(value: 1.25),
popUpSpeed(value: 1.5),
popUpSpeed(value: 2.0),
],
),
],
);
}),
Expanded(
child: AudioSlider(
tag: 'podcast-${podcast.id}',
showTimer: true,
duration: podcast.duration,
),
),
],
), ),
), ),
Row( Row(
@ -108,9 +153,9 @@ class AudioPlayerWidget extends StatelessWidget {
onPressed: () { onPressed: () {
MediaService.audioPlayer.seek( MediaService.audioPlayer.seek(
Duration( Duration(
seconds: MediaService.audioPlayer.currentPosition seconds:
.value.inSeconds + MediaService.audioPlayer.position.inSeconds +
30, 30,
), ),
); );
}, },
@ -126,14 +171,14 @@ class AudioPlayerWidget extends StatelessWidget {
), ),
Expanded( Expanded(
child: Center( child: Center(
child: StreamBuilder<PlayingAudio?>( child: StreamBuilder<PlayerState>(
stream: MediaService.audioPlayer.onReadyToPlay, stream: MediaService.audioPlayer.playerStateStream,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.data == null) { if (snapshot.data == null) {
return const CircularProgressIndicator(); return const CircularProgressIndicator();
} }
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.isPlaying, stream: MediaService.audioPlayer.playingStream,
builder: (context, snapshot) { builder: (context, snapshot) {
return _PlayPouseAnimatedIcon( return _PlayPouseAnimatedIcon(
audioSource: podcast.link, audioSource: podcast.link,
@ -158,8 +203,7 @@ class AudioPlayerWidget extends StatelessWidget {
Duration( Duration(
seconds: max( seconds: max(
0, 0,
MediaService.audioPlayer.currentPosition.value MediaService.audioPlayer.position.inSeconds -
.inSeconds -
10, 10,
), ),
), ),
@ -196,6 +240,16 @@ class AudioPlayerWidget extends StatelessWidget {
); );
} }
PopupMenuItem<dynamic> popUpSpeed({required double value}) {
return PopupMenuItem(
value: value,
height: 32,
child: DidvanText(
'${value}X',
),
);
}
Future<void> _showSleepTimer(StudioDetailsState state, update) async { Future<void> _showSleepTimer(StudioDetailsState state, update) async {
int timerValue = 10; int timerValue = 10;
final controller = FixedExtentScrollController(); final controller = FixedExtentScrollController();
@ -271,8 +325,7 @@ class AudioPlayerWidget extends StatelessWidget {
title: 'پایان پادکست', title: 'پایان پادکست',
onPressed: () async { onPressed: () async {
state.timerValue = MediaService.duration!.inMinutes - state.timerValue = MediaService.duration!.inMinutes -
MediaService MediaService.audioPlayer.position.inMinutes;
.audioPlayer.currentPosition.value.inMinutes;
await controller.animateTo( await controller.animateTo(
state.timerValue * 10, state.timerValue * 10,
duration: DesignConfig.lowAnimationDuration, duration: DesignConfig.lowAnimationDuration,
@ -351,7 +404,7 @@ class __PlayPouseAnimatedIconState extends State<_PlayPouseAnimatedIcon>
} }
void _handleAnimation() { void _handleAnimation() {
if (MediaService.audioPlayer.isPlaying.value) { if (MediaService.audioPlayer.playing) {
_animationController.forward(); _animationController.forward();
} else { } else {
_animationController.reverse(); _animationController.reverse();

View File

@ -26,33 +26,39 @@ class AudioSlider extends StatelessWidget {
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: StreamBuilder<Duration>( child: StreamBuilder<Duration>(
stream: stream: _isPlaying ? MediaService.audioPlayer.positionStream : null,
_isPlaying && MediaService.audioPlayer.currentPosition.hasValue builder: (context, snapshot) {
? MediaService.audioPlayer.currentPosition return Row(
: null, children: [
builder: (context, snapshot) => ProgressBar( Expanded(
thumbColor: Theme.of(context).colorScheme.title, child: ProgressBar(
progressBarColor: DesignConfig.isDark thumbColor: Theme.of(context).colorScheme.title,
? Theme.of(context).colorScheme.title progressBarColor: DesignConfig.isDark
: Theme.of(context).colorScheme.primary, ? Theme.of(context).colorScheme.title
baseBarColor: Theme.of(context).colorScheme.border, : Theme.of(context).colorScheme.primary,
bufferedBarColor: Theme.of(context).colorScheme.splash, baseBarColor: Theme.of(context).colorScheme.border,
total: Duration( bufferedBarColor: Theme.of(context).colorScheme.splash,
seconds: duration ?? MediaService.duration?.inSeconds ?? 0), total: Duration(
progress: snapshot.data ?? Duration.zero, seconds:
thumbRadius: disableThumb ? 0 : 6, duration ?? MediaService.duration?.inSeconds ?? 0),
barHeight: 3, progress: snapshot.data ?? Duration.zero,
timeLabelTextStyle: TextStyle( thumbRadius: disableThumb ? 0 : 6,
fontSize: showTimer ? null : 0, barHeight: 3,
height: showTimer ? 3 : 0, timeLabelTextStyle: TextStyle(
color: Theme.of(context).colorScheme.text, fontSize: showTimer ? null : 0,
fontFamily: DesignConfig.fontFamily.replaceAll( height: showTimer ? 3 : 0,
'-FA', color: Theme.of(context).colorScheme.text,
'', fontFamily: DesignConfig.fontFamily.replaceAll(
), '-FA',
), '',
onSeek: (value) => _onSeek(value.inMilliseconds), ),
), ),
onSeek: (value) => _onSeek(value.inMilliseconds),
),
),
],
);
},
), ),
), ),
); );

View File

@ -1,7 +1,5 @@
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart'; import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -39,7 +37,7 @@ class _PlayerNavBarState extends State<PlayerNavBar> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.isPlaying, stream: MediaService.audioPlayer.playingStream,
builder: (context, isPlaying) => GestureDetector( builder: (context, isPlaying) => GestureDetector(
onTap: () => (MediaService.currentPodcast == null && onTap: () => (MediaService.currentPodcast == null &&
(MediaService.audioPlayerTag ?? '') (MediaService.audioPlayerTag ?? '')

View File

@ -1,26 +1,8 @@
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:didvan/views/podcasts/studio_details/widgets/studio_details_widget.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/widgets/audio/audio_player_widget.dart';
import 'package:didvan/views/widgets/audio/audio_slider.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:provider/provider.dart';
import '../audio/player_navbar.dart'; import '../audio/player_navbar.dart';
@ -36,7 +18,9 @@ class DidvanBNB extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Stack(
children: [ children: [
const PlayerNavBar(inHome: true,), const PlayerNavBar(
inHome: true,
),
Positioned( Positioned(
bottom: 0, bottom: 0,
left: 0, left: 0,
@ -96,7 +80,6 @@ class DidvanBNB extends StatelessWidget {
} }
} }
class _NavBarItem extends StatelessWidget { class _NavBarItem extends StatelessWidget {
final VoidCallback onTap; final VoidCallback onTap;
final bool isSelected; final bool isSelected;

View File

@ -1,26 +1,6 @@
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/widgets/audio/audio_player_widget.dart';
import 'package:didvan/views/widgets/audio/audio_slider.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:didvan/views/podcasts/studio_details/widgets/studio_details_widget.dart';
import 'package:didvan/views/widgets/didvan/app_bar.dart'; import 'package:didvan/views/widgets/didvan/app_bar.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:provider/provider.dart';
import '../audio/player_navbar.dart'; import '../audio/player_navbar.dart';
@ -87,7 +67,7 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
child: SizedBox( child: SizedBox(
height: MediaQuery.of(context).size.height - height: MediaQuery.of(context).size.height -
statusBarHeight - statusBarHeight -
systemNavigationBarHeight , systemNavigationBarHeight,
child: Stack( child: Stack(
children: [ children: [
CustomScrollView( CustomScrollView(
@ -145,7 +125,7 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
12, 12,
), ),
), ),
if(!widget.hidePlayer) if (!widget.hidePlayer)
const SliverPadding(padding: EdgeInsets.only(bottom: 90)) const SliverPadding(padding: EdgeInsets.only(bottom: 90))
], ],
), ),

View File

@ -1,3 +1,5 @@
// ignore_for_file: prefer_typing_uninitialized_variables, library_private_types_in_public_api
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class NotificationDynamicDialog extends StatefulWidget { class NotificationDynamicDialog extends StatefulWidget {
@ -5,7 +7,8 @@ class NotificationDynamicDialog extends StatefulWidget {
final body; final body;
const NotificationDynamicDialog({super.key, this.title, this.body}); const NotificationDynamicDialog({super.key, this.title, this.body});
@override @override
_NotificationDynamicDialogState createState() => _NotificationDynamicDialogState(); _NotificationDynamicDialogState createState() =>
_NotificationDynamicDialogState();
} }
class _NotificationDynamicDialogState extends State<NotificationDynamicDialog> { class _NotificationDynamicDialogState extends State<NotificationDynamicDialog> {
@ -27,4 +30,3 @@ class _NotificationDynamicDialogState extends State<NotificationDynamicDialog> {
); );
} }
} }

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _flutterfire_internals name: _flutterfire_internals
sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7" sha256: b1595874fbc8f7a50da90f5d8f327bb0bfd6a95dc906c390efe991540c3b54aa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.35" version: "1.3.40"
android_intent_plus: android_intent_plus:
dependency: "direct main" dependency: "direct main"
description: description:
@ -41,22 +41,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.0" version: "2.5.0"
assets_audio_player:
dependency: "direct main"
description:
name: assets_audio_player
sha256: "9a87062cf39be0730ba8bb31ed4d148ca4e892e0ae607113f346d3c9a8da5df0"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
assets_audio_player_web:
dependency: transitive
description:
name: assets_audio_player_web
sha256: "24cf82e72c7e7f9292d67e1b52d7945a182d9695ce8f903f60e5c6b379cbcaac"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -65,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
audio_session:
dependency: transitive
description:
name: audio_session
sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261"
url: "https://pub.dev"
source: hosted
version: "0.1.21"
audio_video_progress_bar: audio_video_progress_bar:
dependency: "direct main" dependency: "direct main"
description: description:
@ -73,62 +65,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" version: "2.0.3"
audioplayers:
dependency: "direct main"
description:
name: audioplayers
sha256: "752039d6aa752597c98ec212e9759519061759e402e7da59a511f39d43aa07d2"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
audioplayers_android:
dependency: transitive
description:
name: audioplayers_android
sha256: de576b890befe27175c2f511ba8b742bec83765fa97c3ce4282bba46212f58e4
url: "https://pub.dev"
source: hosted
version: "5.0.0"
audioplayers_darwin:
dependency: transitive
description:
name: audioplayers_darwin
sha256: e507887f3ff18d8e5a10a668d7bedc28206b12e10b98347797257c6ae1019c3b
url: "https://pub.dev"
source: hosted
version: "6.0.0"
audioplayers_linux:
dependency: transitive
description:
name: audioplayers_linux
sha256: "3d3d244c90436115417f170426ce768856d8fe4dfc5ed66a049d2890acfa82f9"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
audioplayers_platform_interface:
dependency: transitive
description:
name: audioplayers_platform_interface
sha256: "6834dd48dfb7bc6c2404998ebdd161f79cd3774a7e6779e1348d54a3bfdcfaa5"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
audioplayers_web:
dependency: transitive
description:
name: audioplayers_web
sha256: db8fc420dadf80da18e2286c18e746fb4c3b2c5adbf0c963299dde046828886d
url: "https://pub.dev"
source: hosted
version: "5.0.0"
audioplayers_windows:
dependency: transitive
description:
name: audioplayers_windows
sha256: "8605762dddba992138d476f6a0c3afd9df30ac5b96039929063eceed416795c2"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
awesome_notifications: awesome_notifications:
dependency: "direct main" dependency: "direct main"
description: description:
@ -137,23 +73,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.2" version: "0.8.2"
awesome_notifications_core:
dependency: "direct main"
description:
name: awesome_notifications_core
sha256: "38c9f9d2618c0c2abe0cea267dc161aa8c4a0a239ca2263400900b9610f33e6f"
url: "https://pub.dev"
source: hosted
version: "0.9.3"
better_player:
dependency: "direct main"
description:
path: "."
ref: HEAD
resolved-ref: "91a9625524cdff448e0a9deb5047bcf20cc8dcf1"
url: "https://github.com/tintran-dev/betterplayer.git"
source: git
version: "0.0.83"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -218,6 +137,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
chewie:
dependency: "direct main"
description:
name: chewie
sha256: "2243e41e79e865d426d9dd9c1a9624aa33c4ad11de2d0cd680f826e2cd30e879"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -354,78 +281,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3+1" version: "0.9.3+1"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
sha256: cfc2d970829202eca09e2896f0a5aa7c87302817ecc0bdfa954f026046bf10ba
url: "https://pub.dev"
source: hosted
version: "4.20.0"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
sha256: a0270e1db3b2098a14cb2a2342b3cd2e7e458e0c391b1f64f6f78b14296ec093
url: "https://pub.dev"
source: hosted
version: "7.3.0"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
sha256: "64e067e763c6378b7e774e872f0f59f6812885e43020e25cde08f42e9459837b"
url: "https://pub.dev"
source: hosted
version: "5.12.0"
firebase_core: firebase_core:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_core name: firebase_core
sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c" sha256: "3187f4f8e49968573fd7403011dca67ba95aae419bc0d8131500fae160d94f92"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.32.0" version: "3.3.0"
firebase_core_platform_interface: firebase_core_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_core_platform_interface name: firebase_core_platform_interface
sha256: "1003a5a03a61fc9a22ef49f37cbcb9e46c86313a7b2e7029b9390cf8c6fc32cb" sha256: "3c3a1e92d6f4916c32deea79c4a7587aa0e9dbbe5889c7a16afcf005a485ee02"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.0" version: "5.2.0"
firebase_core_web: firebase_core_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_core_web name: firebase_core_web
sha256: "6643fe3dbd021e6ccfb751f7882b39df355708afbdeb4130fc50f9305a9d1a3d" sha256: e8d1e22de72cb21cdcfc5eed7acddab3e99cd83f3b317f54f7a96c32f25fd11e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.17.2" version: "2.17.4"
firebase_messaging: firebase_messaging:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_messaging name: firebase_messaging
sha256: a1662cc95d9750a324ad9df349b873360af6f11414902021f130c68ec02267c4 sha256: "1b0a4f9ecbaf9007771bac152afad738ddfacc4b8431a7591c00829480d99553"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.9.4" version: "15.0.4"
firebase_messaging_platform_interface: firebase_messaging_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_messaging_platform_interface name: firebase_messaging_platform_interface
sha256: "87c4a922cb6f811cfb7a889bdbb3622702443c52a0271636cbc90d813ceac147" sha256: c5a6443e66ae064fe186901d740ee7ce648ca2a6fd0484b8c5e963849ac0fc28
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.5.37" version: "4.5.42"
firebase_messaging_web: firebase_messaging_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_messaging_web name: firebase_messaging_web
sha256: "0d34dca01a7b103ed7f20138bffbb28eb0e61a677bf9e78a028a932e2c7322d5" sha256: "232ef63b986467ae5b5577a09c2502b26e2e2aebab5b85e6c966a5ca9b038b89"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.8.7" version: "3.8.12"
fl_chart: fl_chart:
dependency: "direct main" dependency: "direct main"
description: description:
@ -463,30 +366,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" version: "2.0.3"
flutter_local_notifications:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: ced76d337f54de33d7d9f06092137b4ac2da5079e00cee8a11a1794ffc7c61c6
url: "https://pub.dev"
source: hosted
version: "17.2.1"
flutter_local_notifications_linux:
dependency: transitive
description:
name: flutter_local_notifications_linux
sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03"
url: "https://pub.dev"
source: hosted
version: "4.0.0+1"
flutter_local_notifications_platform_interface:
dependency: transitive
description:
name: flutter_local_notifications_platform_interface
sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66"
url: "https://pub.dev"
source: hosted
version: "7.2.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -582,22 +461,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_widget_from_html_core:
dependency: transitive
description:
name: flutter_widget_from_html_core
sha256: e8f4f8b461a140ffb7c71f938bc76efc758893e7468843d9dbf70cb0b9e900cb
url: "https://pub.dev"
source: hosted
version: "0.8.5+3"
fwfh_text_style:
dependency: transitive
description:
name: fwfh_text_style
sha256: "5f8b587fd223a6bf14aad3d3da5e7ced0628becbd0768f8e7ae25ff6b9f3d2ec"
url: "https://pub.dev"
source: hosted
version: "2.23.8"
get: get:
dependency: "direct main" dependency: "direct main"
description: description:
@ -734,6 +597,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.7" version: "0.6.7"
just_audio:
dependency: "direct main"
description:
name: just_audio
sha256: ee50602364ba83fa6308f5512dd560c713ec3e1f2bc75f0db43618f0d82ef71a
url: "https://pub.dev"
source: hosted
version: "0.9.39"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
sha256: "0edb481ad4aa1ff38f8c40f1a3576013c3420bf6669b686fe661627d49bc606c"
url: "https://pub.dev"
source: hosted
version: "0.4.11"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -822,6 +709,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
package_info_plus:
dependency: transitive
description:
name: package_info_plus
sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
url: "https://pub.dev"
source: hosted
version: "8.0.2"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
url: "https://pub.dev"
source: hosted
version: "3.0.1"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -1147,14 +1050,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.1" version: "0.6.1"
timezone:
dependency: transitive
description:
name: timezone
sha256: a6ccda4a69a442098b602c44e61a1e2b4bf6f5516e875bbf0f427d5df14745d5
url: "https://pub.dev"
source: hosted
version: "0.9.3"
toggle_switch: toggle_switch:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1291,14 +1186,46 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
visibility_detector: video_player:
dependency: transitive dependency: "direct main"
description: description:
name: visibility_detector name: video_player
sha256: "15c54a459ec2c17b4705450483f3d5a2858e733aee893dcee9d75fd04814940d" sha256: e30df0d226c4ef82e2c150ebf6834b3522cf3f654d8e2f9419d376cdc071425d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.3" version: "2.9.1"
video_player_android:
dependency: transitive
description:
name: video_player_android
sha256: "134e1ad410d67e18a19486ed9512c72dfc6d8ffb284d0e8f2e99e903d1ba8fa3"
url: "https://pub.dev"
source: hosted
version: "2.4.14"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c
url: "https://pub.dev"
source: hosted
version: "2.6.1"
video_player_platform_interface:
dependency: transitive
description:
name: video_player_platform_interface
sha256: "236454725fafcacf98f0f39af0d7c7ab2ce84762e3b63f2cbb3ef9a7e0550bc6"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
video_player_web:
dependency: transitive
description:
name: video_player_web
sha256: "6dcdd298136523eaf7dfc31abaf0dfba9aa8a8dbc96670e87e9d42b6f2caf774"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -1307,46 +1234,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "13.0.0" version: "13.0.0"
wakelock: wakelock_plus:
dependency: transitive dependency: transitive
description: description:
name: wakelock name: wakelock_plus
sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.2" version: "1.2.8"
wakelock_macos: wakelock_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: wakelock_macos name: wakelock_plus_platform_interface
sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.0" version: "1.2.1"
wakelock_platform_interface:
dependency: transitive
description:
name: wakelock_platform_interface
sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
wakelock_web:
dependency: transitive
description:
name: wakelock_web
sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
wakelock_windows:
dependency: transitive
description:
name: wakelock_windows
sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
web: web:
dependency: transitive dependency: transitive
description: description:
@ -1391,10 +1294,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.4" version: "5.5.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@ -61,15 +61,15 @@ dependencies:
url_launcher: ^6.0.18 url_launcher: ^6.0.18
audio_video_progress_bar: ^2.0.0 audio_video_progress_bar: ^2.0.0
image_cropper: ^1.5.0 image_cropper: ^1.5.0
firebase_messaging: ^14.1.3 firebase_core: ^3.1.0
firebase_core: ^2.3.0 firebase_messaging: ^15.0.1
webview_flutter: ^4.2.0 webview_flutter: ^4.2.0
expandable_bottom_sheet: ^1.1.1+1 expandable_bottom_sheet: ^1.1.1+1
permission_handler: ^11.0.0 permission_handler: ^11.0.0
better_player: # better_player:
git: # git:
url: https://github.com/tintran-dev/betterplayer.git # url: https://github.com/tintran-dev/betterplayer.git
assets_audio_player: ^3.1.1 # assets_audio_player: ^3.1.1
fl_chart: ^0.63.0 fl_chart: ^0.63.0
collection: ^1.17.2 collection: ^1.17.2
animated_custom_dropdown: ^3.0.0 animated_custom_dropdown: ^3.0.0
@ -78,14 +78,15 @@ dependencies:
http: any http: any
http_parser: any http_parser: any
cached_network_image_platform_interface: any cached_network_image_platform_interface: any
flutter_local_notifications: ^17.1.2 awesome_notifications: ^0.8.2
awesome_notifications_core: ^0.9.0
awesome_notifications: any
home_widget: ^0.5.0 home_widget: ^0.5.0
android_intent_plus: ^5.0.0 android_intent_plus: ^5.0.0
get: ^4.6.6 get: ^4.6.6
firebase_auth: ^4.19.6 # firebase_auth: ^4.19.6
audioplayers: ^6.0.0 just_audio: ^0.9.39
video_player: ^2.8.7
chewie: ^1.8.3
# onesignal_flutter: ^3.5.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: