Rhmn -- 27/05/1403 -- fix notification firebase,
This commit is contained in:
parent
1365673b93
commit
8b88463efe
|
|
@ -22,6 +22,9 @@ if (flutterVersionName == null) {
|
|||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
// START: FlutterFire Configuration
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
// END: FlutterFire Configuration
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
|
|
@ -32,7 +35,8 @@ if (keystorePropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
namespace "com.didvan.didvanapp"
|
||||
compileSdk 34
|
||||
ndkVersion "25.1.8937393"
|
||||
|
||||
compileOptions {
|
||||
|
|
@ -53,7 +57,7 @@ android {
|
|||
applicationId "com.didvan.didvanapp"
|
||||
minSdkVersion 24
|
||||
//noinspection ExpiredTargetSdkVersion
|
||||
targetSdkVersion 30
|
||||
targetSdkVersion 31
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
|
@ -79,6 +83,22 @@ android {
|
|||
buildFeatures {
|
||||
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 {
|
||||
|
|
@ -86,10 +106,11 @@ flutter {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation platform('com.google.firebase:firebase-bom:29.1.0')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
// implementation platform('com.google.firebase:firebase-bom:29.1.0')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
|
||||
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.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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@
|
|||
{
|
||||
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "com.didvan.didvanapp"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<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.SCHEDULE_EXACT_ALARM"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Didvan"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:usesCleartextTraffic="true">
|
||||
<receiver
|
||||
android:name=".FavWidget"
|
||||
|
|
@ -36,8 +36,7 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
<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
|
||||
|
|
@ -49,8 +48,14 @@
|
|||
android:showWhenLocked="true"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:turnScreenOn="true"
|
||||
android:exported="true"
|
||||
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
|
||||
the Android process has started. This theme is visible to the user
|
||||
|
|
@ -82,15 +87,9 @@
|
|||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:exported="true"
|
||||
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>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
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 io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
|
|
@ -9,5 +14,7 @@ class MainActivity: FlutterActivity() {
|
|||
@Override
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
GeneratedPluginRegistrant.registerWith(flutterEngine)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ buildscript {
|
|||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +17,8 @@ allprojects {
|
|||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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"}}}}}}
|
||||
|
|
@ -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',
|
||||
);
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import 'dart:io';
|
||||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:android_intent_plus/android_intent.dart';
|
||||
import 'package:bot_toast/bot_toast.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/providers/media.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/routes.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/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/studio_details/studio_details_state.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
|
|
@ -26,43 +28,18 @@ import 'package:provider/provider.dart';
|
|||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
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"
|
||||
),
|
||||
);
|
||||
print("background: ${NotificationMessage.fromJson(message.data).toJson()}");
|
||||
try {
|
||||
await AwsomeNotificationHandler().show(message);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
Future _initPushNotification(RemoteMessage message) async {
|
||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||
if (kDebugMode) {
|
||||
print("background: ${NotificationData.fromJson(message.data).toJson()}");
|
||||
}
|
||||
try {
|
||||
NotificationService.showFirebaseNotification(message);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
|
|
@ -80,19 +57,16 @@ Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
|
|||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
try {
|
||||
await AwsomeNotificationHandler().alarm();
|
||||
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||||
//ignore: deprecated_member_use
|
||||
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
|
||||
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
|
||||
await AppInitializer.initializeFirebase();
|
||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||
print(
|
||||
"forground: ${NotificationMessage.fromJson(message.data).toJson()}");
|
||||
AwsomeNotificationHandler().show(message);
|
||||
});
|
||||
|
||||
await NotificationService.initializeNotification();
|
||||
FirebaseMessaging.onBackgroundMessage(_initPushNotification);
|
||||
await Firebase.initializeApp(
|
||||
options: DefaultFirebaseOptions.currentPlatform);
|
||||
await FirebaseApi().initNotification();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
debugPrint;
|
||||
}
|
||||
|
||||
runApp(const Didvan());
|
||||
|
|
@ -113,7 +87,7 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
AwsomeNotificationHandler.startListeningNotificationEvents();
|
||||
NotificationService.startListeningNotificationEvents();
|
||||
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
|
@ -123,9 +97,9 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
|||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
// MediaService.audioPlayer.dispose();
|
||||
if(MediaService.currentPodcast != null){
|
||||
MediaService.audioPlayer.dispose();
|
||||
}
|
||||
if (MediaService.currentPodcast != null) {
|
||||
MediaService.audioPlayer.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
class DayTime{
|
||||
String hour;
|
||||
String minute;
|
||||
Meridiem meridiem;
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
class DayTime {
|
||||
String hour;
|
||||
String minute;
|
||||
Meridiem meridiem;
|
||||
|
||||
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 }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,17 +7,21 @@ class NotificationMessage {
|
|||
String? link;
|
||||
String? image;
|
||||
String? photo;
|
||||
String? groupKey;
|
||||
String? userId;
|
||||
|
||||
NotificationMessage(
|
||||
{this.notificationType,
|
||||
this.title,
|
||||
this.body,
|
||||
this.id,
|
||||
this.type,
|
||||
this.link,
|
||||
this.image,
|
||||
this.photo,
|
||||
});
|
||||
NotificationMessage({
|
||||
this.notificationType,
|
||||
this.title,
|
||||
this.body,
|
||||
this.id,
|
||||
this.type,
|
||||
this.link,
|
||||
this.image,
|
||||
this.photo,
|
||||
this.groupKey,
|
||||
this.userId,
|
||||
});
|
||||
|
||||
NotificationMessage.fromJson(Map<String, dynamic> json) {
|
||||
notificationType = json['notificationType'];
|
||||
|
|
@ -28,6 +32,8 @@ class NotificationMessage {
|
|||
link = json['link'];
|
||||
image = json['image'];
|
||||
photo = json['photo'];
|
||||
groupKey = json['groupKey'];
|
||||
userId = json['userId'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
@ -40,8 +46,11 @@ class NotificationMessage {
|
|||
data['link'] = link;
|
||||
data['image'] = image;
|
||||
data['photo'] = photo;
|
||||
data['groupKey'] = groupKey;
|
||||
data['userId'] = userId;
|
||||
return data;
|
||||
}
|
||||
|
||||
Map<String, String> toPayload() {
|
||||
final Map<String, String> data = <String, String>{};
|
||||
data['notificationType'] = notificationType!;
|
||||
|
|
@ -52,6 +61,7 @@ class NotificationMessage {
|
|||
data['link'] = link!;
|
||||
data['image'] = image!;
|
||||
data['photo'] = photo!;
|
||||
data['userId'] = userId!;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import 'package:didvan/models/enums.dart';
|
|||
import 'package:didvan/models/user.dart';
|
||||
import 'package:didvan/models/view/alert_data.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_helper.dart';
|
||||
import 'package:didvan/services/notification/firebase_api.dart';
|
||||
import 'package:didvan/services/storage/storage.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
|
||||
|
|
@ -64,9 +64,9 @@ class UserProvider extends CoreProvier {
|
|||
value: service.result['user']['end'],
|
||||
);
|
||||
|
||||
AppInitializer.initializeFirebase().then((_) {
|
||||
_registerFirebaseToken();
|
||||
}).catchError((err) {});
|
||||
FirebaseApi()
|
||||
.initNotification()
|
||||
.then((value) => _registerFirebaseToken());
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
|
|
@ -78,13 +78,12 @@ class UserProvider extends CoreProvier {
|
|||
}
|
||||
|
||||
Future<void> _registerFirebaseToken() async {
|
||||
if (AppInitializer.fcmToken == null) {
|
||||
return;
|
||||
if (FirebaseApi.fcmToken != null) {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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/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/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/mentions/mentions.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';
|
||||
import 'package:didvan/views/splash/splash.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/material.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:didvan/main.dart';
|
||||
import 'package:didvan/models/notification_message.dart';
|
||||
import 'package:didvan/models/requests/news.dart';
|
||||
import 'package:didvan/models/requests/radar.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/views/home/home_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/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../models/notification_message.dart';
|
||||
import 'notification/awsome/awsome_notification_handler.dart';
|
||||
|
||||
class AppInitializer {
|
||||
static String? fcmToken;
|
||||
static String? clickAction;
|
||||
|
|
@ -32,7 +27,7 @@ class AppInitializer {
|
|||
}
|
||||
// ignore: use_build_context_synchronously
|
||||
final studioState = context.read<StudioDetailsState>();
|
||||
MediaService.audioPlayer.isPlaying.listen((event) {
|
||||
MediaService.audioPlayer.playingStream.listen((event) {
|
||||
if (event &&
|
||||
(MediaService.audioPlayerTag?.contains('podcast') ?? false)) {
|
||||
studioState.handleTracking(
|
||||
|
|
@ -150,67 +145,30 @@ class AppInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
static Future<void> initializeFirebase() async {
|
||||
try {
|
||||
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"
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
Firebase.app();
|
||||
static int createNotificationId(NotificationMessage data) {
|
||||
int t = 0;
|
||||
switch (data.type!) {
|
||||
case "infography":
|
||||
t = 1;
|
||||
break;
|
||||
case "news":
|
||||
t = 2;
|
||||
|
||||
break;
|
||||
case "radar":
|
||||
t = 3;
|
||||
|
||||
break;
|
||||
case "video":
|
||||
t = 4;
|
||||
|
||||
break;
|
||||
case "podcast":
|
||||
t = 5;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
final initMsg = await FirebaseMessaging.instance.getInitialMessage();
|
||||
|
||||
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,
|
||||
);
|
||||
|
||||
|
||||
int id = int.parse('${data.userId}${data.id}$t');
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
|
@ -6,16 +6,15 @@ import 'package:didvan/services/network/request_helper.dart';
|
|||
import 'package:didvan/services/storage/storage.dart';
|
||||
import 'package:flutter/foundation.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 {
|
||||
static final audioPlayer = AssetsAudioPlayer();
|
||||
static final audioPlayer = AudioPlayer();
|
||||
static String? audioPlayerTag;
|
||||
static StudioDetailsData? currentPodcast;
|
||||
static StudioRequestArgs? podcastPlaylistArgs;
|
||||
|
||||
static Duration? get duration =>
|
||||
audioPlayer.current.valueOrNull?.audio.duration;
|
||||
static Duration? get duration => audioPlayer.duration;
|
||||
|
||||
static Future<void> handleAudioPlayback({
|
||||
required dynamic audioSource,
|
||||
|
|
@ -33,13 +32,17 @@ class MediaService {
|
|||
isNetworkAudio = false;
|
||||
}
|
||||
if (audioPlayerTag == tag) {
|
||||
await audioPlayer.playOrPause();
|
||||
if (audioPlayer.playerState ==
|
||||
PlayerState(true, ProcessingState.ready)) {
|
||||
await audioPlayer.pause();
|
||||
} else {
|
||||
await audioPlayer.play();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// await audioPlayer.stop();
|
||||
audioPlayerTag = tag;
|
||||
Audio audio;
|
||||
String source;
|
||||
if (isNetworkAudio) {
|
||||
if (isVoiceMessage) {
|
||||
|
|
@ -48,38 +51,39 @@ class MediaService {
|
|||
} else {
|
||||
source = audioSource;
|
||||
}
|
||||
audio = Audio.network(
|
||||
audioPlayer.setUrl(
|
||||
kIsWeb ? source.replaceAll('%3A', ':') : source,
|
||||
metas: isVoiceMessage
|
||||
tag: isVoiceMessage
|
||||
? null
|
||||
: Metas(
|
||||
artist: 'استودیو دیدوان',
|
||||
title: currentPodcast?.title ?? '',
|
||||
),
|
||||
: {
|
||||
"artist": 'استودیو دیدوان',
|
||||
"title": currentPodcast?.title ?? '',
|
||||
},
|
||||
);
|
||||
} else {
|
||||
audio = Audio.file(
|
||||
audioPlayer.setAsset(
|
||||
audioSource,
|
||||
metas: isVoiceMessage
|
||||
tag: isVoiceMessage
|
||||
? null
|
||||
: Metas(
|
||||
artist: 'استودیو دیدوان',
|
||||
title: currentPodcast?.title ?? '',
|
||||
),
|
||||
: {
|
||||
"artist": 'استودیو دیدوان',
|
||||
"title": currentPodcast?.title ?? '',
|
||||
},
|
||||
);
|
||||
}
|
||||
await audioPlayer.open(
|
||||
audio,
|
||||
showNotification: !isVoiceMessage,
|
||||
notificationSettings: NotificationSettings(
|
||||
customStopAction: (_) => resetAudioPlayer(),
|
||||
customNextAction: (_) => onTrackChanged?.call(true),
|
||||
customPrevAction: (_) => onTrackChanged?.call(false),
|
||||
),
|
||||
);
|
||||
await audioPlayer.play();
|
||||
// await audioPlayer.open(
|
||||
// audio,
|
||||
// showNotification: !isVoiceMessage,
|
||||
// notificationSettings: NotificationSettings(
|
||||
// customStopAction: (_) => resetAudioPlayer(),
|
||||
// customNextAction: (_) => onTrackChanged?.call(true),
|
||||
// customPrevAction: (_) => onTrackChanged?.call(false),
|
||||
// ),
|
||||
// );
|
||||
} catch (e) {
|
||||
// resetAudioPlayer();
|
||||
rethrow;
|
||||
// rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class RequestService {
|
|||
headers: _headers,
|
||||
)
|
||||
.timeout(
|
||||
const Duration(seconds: 10),
|
||||
const Duration(seconds: 30),
|
||||
)
|
||||
.catchError(
|
||||
(e) => throw e,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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');
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/views/authentication/authentication_state.dart';
|
||||
import 'package:didvan/views/authentication/screens/password.dart';
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ class _PasswordInputState extends State<PasswordInput> {
|
|||
await ServerDataProvider.getData();
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pushReplacementNamed(Routes.home);
|
||||
Future.delayed(Duration.zero,
|
||||
() => Navigator.of(context).pushReplacementNamed(Routes.home));
|
||||
}
|
||||
|
||||
_showResetPasswordDialog();
|
||||
|
|
|
|||
|
|
@ -54,14 +54,19 @@ class _ResetPasswordState extends State<ResetPassword> {
|
|||
.read<AuthenticationState>()
|
||||
.resetPassword(_password);
|
||||
if (!mounted) return;
|
||||
if (result && context.read<UserProvider>().isAuthenticated) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.authenticaion,
|
||||
arguments: false,
|
||||
Future.delayed(
|
||||
Duration.zero,
|
||||
() {
|
||||
if (result && context.read<UserProvider>().isAuthenticated) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.authenticaion,
|
||||
arguments: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
title: 'تغییر رمز عبور',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
|
|
|
|||
|
|
@ -84,15 +84,20 @@ class CustomizeCategoryState extends CoreProvier {
|
|||
);
|
||||
await service.put();
|
||||
if (service.isSuccess) {
|
||||
if (toTimer) {
|
||||
Navigator.of(context).pushNamed(Routes.notificationTime,
|
||||
arguments: {"fromFav": toTimer});
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
ActionSheetUtils.showAlert(AlertData(
|
||||
message: "تغییرات شما با موفقیت اعمال شد.",
|
||||
aLertType: ALertType.success));
|
||||
}
|
||||
Future.delayed(
|
||||
Duration.zero,
|
||||
() {
|
||||
if (toTimer) {
|
||||
Navigator.of(context).pushNamed(Routes.notificationTime,
|
||||
arguments: {"fromFav": toTimer});
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
ActionSheetUtils.showAlert(AlertData(
|
||||
message: "تغییرات شما با موفقیت اعمال شد.",
|
||||
aLertType: ALertType.success));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
appState = AppState.idle;
|
||||
await HomeWidgetRepository.fetchWidget();
|
||||
|
|
@ -112,16 +117,21 @@ class CustomizeCategoryState extends CoreProvier {
|
|||
);
|
||||
await service.put();
|
||||
if (service.isSuccess) {
|
||||
if (toTimer) {
|
||||
Navigator.of(context).pushNamed(Routes.notificationTime,
|
||||
arguments: {"fromFav": toTimer});
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
ActionSheetUtils.showAlert(AlertData(
|
||||
message: "تغییرات شما با موفقیت اعمال شد.",
|
||||
aLertType: ALertType.success));
|
||||
}
|
||||
Future.delayed(
|
||||
Duration.zero,
|
||||
() {
|
||||
if (toTimer) {
|
||||
Navigator.of(context).pushNamed(Routes.notificationTime,
|
||||
arguments: {"fromFav": toTimer});
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
ActionSheetUtils.showAlert(AlertData(
|
||||
message: "تغییرات شما با موفقیت اعمال شد.",
|
||||
aLertType: ALertType.success));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
appState = AppState.idle;
|
||||
await HomeWidgetRepository.fetchWidget();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/models/enums.dart';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:assets_audio_player/assets_audio_player.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.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/widgets/didvan/icon_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AudioWidget extends StatelessWidget {
|
||||
|
|
@ -28,7 +28,7 @@ class AudioWidget extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<bool>(
|
||||
stream: MediaService.audioPlayer.isPlaying,
|
||||
stream: MediaService.audioPlayer.playingStream,
|
||||
builder: (context, snapshot) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
|
@ -36,12 +36,18 @@ class AudioWidget extends StatelessWidget {
|
|||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: AudioSlider(
|
||||
tag: audioMetaData != null
|
||||
? '${audioMetaData!.type}-$id'
|
||||
: 'message-$id',
|
||||
duration: audioMetaData?.duration,
|
||||
showTimer: true,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AudioSlider(
|
||||
tag: audioMetaData != null
|
||||
? '${audioMetaData!.type}-$id'
|
||||
: 'message-$id',
|
||||
duration: audioMetaData?.duration,
|
||||
showTimer: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -79,11 +85,11 @@ class _AudioControllerButton extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<PlayingAudio?>(
|
||||
stream: MediaService.audioPlayer.onReadyToPlay,
|
||||
return StreamBuilder<PlayerState>(
|
||||
stream: MediaService.audioPlayer.playerStateStream,
|
||||
builder: (context, snapshot) {
|
||||
return DidvanIconButton(
|
||||
icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying
|
||||
icon: MediaService.audioPlayer.playing && _nowPlaying
|
||||
? DidvanIcons.pause_circle_solid
|
||||
: DidvanIcons.play_circle_solid,
|
||||
gestureSize: 36,
|
||||
|
|
@ -100,7 +106,7 @@ class _AudioControllerButton extends StatelessWidget {
|
|||
}
|
||||
if (snapshot.data == null &&
|
||||
_nowPlaying &&
|
||||
MediaService.audioPlayer.isPlaying.value) {
|
||||
MediaService.audioPlayer.playing) {
|
||||
return;
|
||||
}
|
||||
if (audioMetaData != null) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:didvan/config/design_config.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/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/categories/categories_page.dart';
|
||||
import 'package:didvan/views/home/main/main_page.dart';
|
||||
import 'package:didvan/views/home/home_state.dart';
|
||||
import 'package:didvan/views/home/new_statistic/new_statistic.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/didvan/bnb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../services/app_home_widget/home_widget_repository.dart';
|
||||
|
||||
|
|
@ -28,7 +34,7 @@ class _HomeState extends State<Home>
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
AwsomeNotificationHandler.startListeningNotificationEvents();
|
||||
NotificationService.startListeningNotificationEvents();
|
||||
|
||||
final state = context.read<HomeState>();
|
||||
DesignConfig.updateSystemUiOverlayStyle();
|
||||
|
|
@ -59,28 +65,50 @@ class _HomeState extends State<Home>
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const LogoAppBar(),
|
||||
body: 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(),
|
||||
],
|
||||
body: WillPopScope(
|
||||
onWillPop: () async {
|
||||
if (context.read<HomeState>().tabController.index == 0) {
|
||||
ActionSheetUtils.openDialog(
|
||||
data: ActionSheetData(
|
||||
content: const DidvanText(
|
||||
'آیا قصد خروج از برنامه را دارید؟',
|
||||
),
|
||||
onConfirmed: () {
|
||||
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
||||
},
|
||||
isBackgroundDropBlur: true,
|
||||
confrimTitle: 'بله',
|
||||
onDismissed: Navigator.of(ActionSheetUtils.context).pop,
|
||||
dismissTitle: 'خیر',
|
||||
));
|
||||
} else {
|
||||
_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>(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'dart:async';
|
|||
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/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_type4.dart';
|
||||
import 'package:didvan/views/home/new_statistic/stock/total_type6.dart';
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ class NewStockState extends CoreProvier {
|
|||
int lastPage = 1;
|
||||
List contents = [];
|
||||
int? length;
|
||||
int? length_type3;
|
||||
int? length_type4;
|
||||
|
||||
Future<void> getStock({required int page}) async {
|
||||
this.page = page;
|
||||
|
|
@ -53,8 +53,7 @@ class _MentionsState extends State<Mentions> {
|
|||
|
||||
bool get _isPage => widget.pageData['isPage'] != false;
|
||||
|
||||
void _onChange(MentionsState state, value) {
|
||||
state.searchUsers = value;
|
||||
void _onChange(MentionsState state, String value) {
|
||||
state.getUsersMention(context.read<UserProvider>().user.id);
|
||||
state.update();
|
||||
}
|
||||
|
|
@ -159,6 +158,7 @@ class _MentionsState extends State<Mentions> {
|
|||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: mentionsState.searchUsers,
|
||||
focusNode: _focusNodeMention,
|
||||
keyboardType: TextInputType.multiline,
|
||||
textInputAction: TextInputAction.send,
|
||||
|
|
@ -183,6 +183,8 @@ class _MentionsState extends State<Mentions> {
|
|||
icon: DidvanIcons.close_regular,
|
||||
onPressed: () {
|
||||
mentionsState.showUsersForMentionsLayout = false;
|
||||
mentionsState.searchUsers.text = '';
|
||||
|
||||
mentionsState.update();
|
||||
}),
|
||||
],
|
||||
|
|
@ -233,12 +235,6 @@ class _MessageBoxState extends State<_MessageBox> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.watch<MentionsState>();
|
||||
|
||||
void onCheckBoxChange(bool b) {
|
||||
state.hideMentionedUser = b;
|
||||
state.update();
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
AnimatedVisibility(
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import 'package:provider/provider.dart';
|
|||
|
||||
class MentionsState extends CoreProvier {
|
||||
TextEditingController textFieldController = TextEditingController();
|
||||
TextEditingController searchUsers = TextEditingController();
|
||||
List<UsersMention> mentionedUsers = [];
|
||||
String searchUsers = '';
|
||||
int? commentId;
|
||||
UserOverview? replyingTo;
|
||||
bool showReplyBox = false;
|
||||
|
|
@ -51,7 +51,7 @@ class MentionsState extends CoreProvier {
|
|||
|
||||
Future<void> getUsersMention(int id) async {
|
||||
final service = RequestService(
|
||||
RequestHelper.usersMentions(searchUsers),
|
||||
RequestHelper.usersMentions(searchUsers.text),
|
||||
);
|
||||
|
||||
await service.httpGet();
|
||||
|
|
@ -116,7 +116,7 @@ class MentionsState extends CoreProvier {
|
|||
|
||||
mentionedUsers.clear();
|
||||
users.clear();
|
||||
searchUsers = '';
|
||||
searchUsers.text = '';
|
||||
textFieldController.text = '';
|
||||
showUsersForMentionsLayout = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class NotificationTimeState extends CoreProvier {
|
|||
bool isAnytime = false;
|
||||
bool fromFav = false;
|
||||
|
||||
late void Function() onTimeChanged = (){};
|
||||
late void Function() onTimeChanged = () {};
|
||||
|
||||
Future<void> getTime() async {
|
||||
appState = AppState.busy;
|
||||
|
|
@ -53,15 +53,22 @@ class NotificationTimeState extends CoreProvier {
|
|||
await service.put();
|
||||
if (service.isSuccess) {
|
||||
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) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
ActionSheetUtils.showAlert(AlertData(message: "تغییرات شما با موفقیت اعمال شد.",aLertType: ALertType.success));
|
||||
ActionSheetUtils.showAlert(AlertData(
|
||||
message: "تغییرات شما با موفقیت اعمال شد.",
|
||||
aLertType: ALertType.success));
|
||||
|
||||
appState = AppState.idle;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -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/services/media/media.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:provider/provider.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class StudioDetails extends StatefulWidget {
|
||||
final Map<String, dynamic> pageData;
|
||||
|
|
@ -23,18 +25,17 @@ class StudioDetails extends StatefulWidget {
|
|||
|
||||
class _StudioDetailsState extends State<StudioDetails> {
|
||||
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
|
||||
void initState() {
|
||||
_betterPlayerController = BetterPlayerController(
|
||||
const BetterPlayerConfiguration(
|
||||
aspectRatio: 16 / 9,
|
||||
showPlaceholderUntilPlay: true,
|
||||
autoDispose: false,
|
||||
fullScreenAspectRatio: 16 / 9,
|
||||
),
|
||||
);
|
||||
final state = context.read<StudioDetailsState>();
|
||||
state.args = widget.pageData['args'];
|
||||
|
||||
|
|
@ -115,7 +116,12 @@ class _StudioDetailsState extends State<StudioDetails> {
|
|||
height: d.size.height - d.padding.top - 56,
|
||||
child: Column(
|
||||
children: [
|
||||
BetterPlayer(controller: _betterPlayerController),
|
||||
AspectRatio(
|
||||
aspectRatio: 16 / 9,
|
||||
child: Chewie(
|
||||
controller: _chewieController,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: StudioDetailsWidget(
|
||||
onMarkChanged: (id, value) => widget
|
||||
|
|
@ -135,29 +141,17 @@ class _StudioDetailsState extends State<StudioDetails> {
|
|||
}
|
||||
|
||||
Future<void> _handleVideoPlayback(state) async {
|
||||
final betterPlayerDataSource = BetterPlayerDataSource(
|
||||
BetterPlayerDataSourceType.network,
|
||||
_videoPlayerController = VideoPlayerController.network(
|
||||
state.studio.link,
|
||||
videoFormat: BetterPlayerVideoFormat.hls,
|
||||
);
|
||||
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,
|
||||
),
|
||||
);
|
||||
)..initialize().then((value) async {});
|
||||
_currentlyPlayingId = state.studio.id;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_betterPlayerController.pause();
|
||||
_betterPlayerController.dispose();
|
||||
_videoPlayerController.pause();
|
||||
_videoPlayerController.dispose();
|
||||
_chewieController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class StudioDetailsState extends CoreProvier {
|
|||
// MediaService.resetAudioPlayer();
|
||||
update();
|
||||
appState = AppState.idle;
|
||||
rethrow;
|
||||
// rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ class StudioDetailsState extends CoreProvier {
|
|||
);
|
||||
if (nextStudio != null && !_positionListenerActivated) {
|
||||
_positionListenerActivated = true;
|
||||
MediaService.audioPlayer.currentPosition.listen((event) {
|
||||
MediaService.audioPlayer.positionStream.listen((event) {
|
||||
if (MediaService.audioPlayerTag?.contains('message') == true) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
|
|
|
|||
|
|
@ -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/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/providers/theme.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/widgets/menu_item.dart';
|
||||
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||
|
|
@ -40,9 +35,6 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
|||
return 'کوچک';
|
||||
}
|
||||
|
||||
int _intervalStart = 0;
|
||||
int _intervalEnd = 24;
|
||||
|
||||
@override
|
||||
void 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(
|
||||
BuildContext context, GeneralSettingsState state, String brightness) {
|
||||
final bool isDarkTheme = brightness == 'dark';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
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';
|
||||
|
|
@ -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/skeleton_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AudioPlayerWidget extends StatelessWidget {
|
||||
|
|
@ -59,10 +59,55 @@ class AudioPlayerWidget extends StatelessWidget {
|
|||
const SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: AudioSlider(
|
||||
tag: 'podcast-${podcast.id}',
|
||||
showTimer: true,
|
||||
duration: podcast.duration,
|
||||
child: Row(
|
||||
children: [
|
||||
StreamBuilder<double>(
|
||||
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(
|
||||
|
|
@ -108,9 +153,9 @@ class AudioPlayerWidget extends StatelessWidget {
|
|||
onPressed: () {
|
||||
MediaService.audioPlayer.seek(
|
||||
Duration(
|
||||
seconds: MediaService.audioPlayer.currentPosition
|
||||
.value.inSeconds +
|
||||
30,
|
||||
seconds:
|
||||
MediaService.audioPlayer.position.inSeconds +
|
||||
30,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
@ -126,14 +171,14 @@ class AudioPlayerWidget extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: StreamBuilder<PlayingAudio?>(
|
||||
stream: MediaService.audioPlayer.onReadyToPlay,
|
||||
child: StreamBuilder<PlayerState>(
|
||||
stream: MediaService.audioPlayer.playerStateStream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.data == null) {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
return StreamBuilder<bool>(
|
||||
stream: MediaService.audioPlayer.isPlaying,
|
||||
stream: MediaService.audioPlayer.playingStream,
|
||||
builder: (context, snapshot) {
|
||||
return _PlayPouseAnimatedIcon(
|
||||
audioSource: podcast.link,
|
||||
|
|
@ -158,8 +203,7 @@ class AudioPlayerWidget extends StatelessWidget {
|
|||
Duration(
|
||||
seconds: max(
|
||||
0,
|
||||
MediaService.audioPlayer.currentPosition.value
|
||||
.inSeconds -
|
||||
MediaService.audioPlayer.position.inSeconds -
|
||||
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 {
|
||||
int timerValue = 10;
|
||||
final controller = FixedExtentScrollController();
|
||||
|
|
@ -271,8 +325,7 @@ class AudioPlayerWidget extends StatelessWidget {
|
|||
title: 'پایان پادکست',
|
||||
onPressed: () async {
|
||||
state.timerValue = MediaService.duration!.inMinutes -
|
||||
MediaService
|
||||
.audioPlayer.currentPosition.value.inMinutes;
|
||||
MediaService.audioPlayer.position.inMinutes;
|
||||
await controller.animateTo(
|
||||
state.timerValue * 10,
|
||||
duration: DesignConfig.lowAnimationDuration,
|
||||
|
|
@ -351,7 +404,7 @@ class __PlayPouseAnimatedIconState extends State<_PlayPouseAnimatedIcon>
|
|||
}
|
||||
|
||||
void _handleAnimation() {
|
||||
if (MediaService.audioPlayer.isPlaying.value) {
|
||||
if (MediaService.audioPlayer.playing) {
|
||||
_animationController.forward();
|
||||
} else {
|
||||
_animationController.reverse();
|
||||
|
|
|
|||
|
|
@ -26,33 +26,39 @@ class AudioSlider extends StatelessWidget {
|
|||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StreamBuilder<Duration>(
|
||||
stream:
|
||||
_isPlaying && MediaService.audioPlayer.currentPosition.hasValue
|
||||
? MediaService.audioPlayer.currentPosition
|
||||
: null,
|
||||
builder: (context, snapshot) => ProgressBar(
|
||||
thumbColor: Theme.of(context).colorScheme.title,
|
||||
progressBarColor: DesignConfig.isDark
|
||||
? Theme.of(context).colorScheme.title
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
baseBarColor: Theme.of(context).colorScheme.border,
|
||||
bufferedBarColor: Theme.of(context).colorScheme.splash,
|
||||
total: Duration(
|
||||
seconds: duration ?? MediaService.duration?.inSeconds ?? 0),
|
||||
progress: snapshot.data ?? Duration.zero,
|
||||
thumbRadius: disableThumb ? 0 : 6,
|
||||
barHeight: 3,
|
||||
timeLabelTextStyle: TextStyle(
|
||||
fontSize: showTimer ? null : 0,
|
||||
height: showTimer ? 3 : 0,
|
||||
color: Theme.of(context).colorScheme.text,
|
||||
fontFamily: DesignConfig.fontFamily.replaceAll(
|
||||
'-FA',
|
||||
'',
|
||||
),
|
||||
),
|
||||
onSeek: (value) => _onSeek(value.inMilliseconds),
|
||||
),
|
||||
stream: _isPlaying ? MediaService.audioPlayer.positionStream : null,
|
||||
builder: (context, snapshot) {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProgressBar(
|
||||
thumbColor: Theme.of(context).colorScheme.title,
|
||||
progressBarColor: DesignConfig.isDark
|
||||
? Theme.of(context).colorScheme.title
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
baseBarColor: Theme.of(context).colorScheme.border,
|
||||
bufferedBarColor: Theme.of(context).colorScheme.splash,
|
||||
total: Duration(
|
||||
seconds:
|
||||
duration ?? MediaService.duration?.inSeconds ?? 0),
|
||||
progress: snapshot.data ?? Duration.zero,
|
||||
thumbRadius: disableThumb ? 0 : 6,
|
||||
barHeight: 3,
|
||||
timeLabelTextStyle: TextStyle(
|
||||
fontSize: showTimer ? null : 0,
|
||||
height: showTimer ? 3 : 0,
|
||||
color: Theme.of(context).colorScheme.text,
|
||||
fontFamily: DesignConfig.fontFamily.replaceAll(
|
||||
'-FA',
|
||||
'',
|
||||
),
|
||||
),
|
||||
onSeek: (value) => _onSeek(value.inMilliseconds),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import 'package:assets_audio_player/assets_audio_player.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
|
@ -39,7 +37,7 @@ class _PlayerNavBarState extends State<PlayerNavBar> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<bool>(
|
||||
stream: MediaService.audioPlayer.isPlaying,
|
||||
stream: MediaService.audioPlayer.playingStream,
|
||||
builder: (context, isPlaying) => GestureDetector(
|
||||
onTap: () => (MediaService.currentPodcast == null &&
|
||||
(MediaService.audioPlayerTag ?? '')
|
||||
|
|
|
|||
|
|
@ -1,26 +1,8 @@
|
|||
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/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/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/widgets.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../audio/player_navbar.dart';
|
||||
|
||||
|
|
@ -36,7 +18,9 @@ class DidvanBNB extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
const PlayerNavBar(inHome: true,),
|
||||
const PlayerNavBar(
|
||||
inHome: true,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
|
|
@ -96,7 +80,6 @@ class DidvanBNB extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class _NavBarItem extends StatelessWidget {
|
||||
final VoidCallback onTap;
|
||||
final bool isSelected;
|
||||
|
|
|
|||
|
|
@ -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/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/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_spinkit/flutter_spinkit.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../audio/player_navbar.dart';
|
||||
|
||||
|
|
@ -87,7 +67,7 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
|||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height -
|
||||
statusBarHeight -
|
||||
systemNavigationBarHeight ,
|
||||
systemNavigationBarHeight,
|
||||
child: Stack(
|
||||
children: [
|
||||
CustomScrollView(
|
||||
|
|
@ -145,7 +125,7 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
|||
12,
|
||||
),
|
||||
),
|
||||
if(!widget.hidePlayer)
|
||||
if (!widget.hidePlayer)
|
||||
const SliverPadding(padding: EdgeInsets.only(bottom: 90))
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: prefer_typing_uninitialized_variables, library_private_types_in_public_api
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NotificationDynamicDialog extends StatefulWidget {
|
||||
|
|
@ -5,7 +7,8 @@ class NotificationDynamicDialog extends StatefulWidget {
|
|||
final body;
|
||||
const NotificationDynamicDialog({super.key, this.title, this.body});
|
||||
@override
|
||||
_NotificationDynamicDialogState createState() => _NotificationDynamicDialogState();
|
||||
_NotificationDynamicDialogState createState() =>
|
||||
_NotificationDynamicDialogState();
|
||||
}
|
||||
|
||||
class _NotificationDynamicDialogState extends State<NotificationDynamicDialog> {
|
||||
|
|
@ -27,4 +30,3 @@ class _NotificationDynamicDialogState extends State<NotificationDynamicDialog> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
331
pubspec.lock
331
pubspec.lock
|
|
@ -5,10 +5,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7"
|
||||
sha256: b1595874fbc8f7a50da90f5d8f327bb0bfd6a95dc906c390efe991540c3b54aa
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.35"
|
||||
version: "1.3.40"
|
||||
android_intent_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -41,22 +41,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -65,6 +49,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -73,62 +65,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -137,23 +73,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -218,6 +137,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
chewie:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: chewie
|
||||
sha256: "2243e41e79e865d426d9dd9c1a9624aa33c4ad11de2d0cd680f826e2cd30e879"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -354,78 +281,54 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c"
|
||||
sha256: "3187f4f8e49968573fd7403011dca67ba95aae419bc0d8131500fae160d94f92"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.32.0"
|
||||
version: "3.3.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: "1003a5a03a61fc9a22ef49f37cbcb9e46c86313a7b2e7029b9390cf8c6fc32cb"
|
||||
sha256: "3c3a1e92d6f4916c32deea79c4a7587aa0e9dbbe5889c7a16afcf005a485ee02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
version: "5.2.0"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "6643fe3dbd021e6ccfb751f7882b39df355708afbdeb4130fc50f9305a9d1a3d"
|
||||
sha256: e8d1e22de72cb21cdcfc5eed7acddab3e99cd83f3b317f54f7a96c32f25fd11e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.17.2"
|
||||
version: "2.17.4"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: a1662cc95d9750a324ad9df349b873360af6f11414902021f130c68ec02267c4
|
||||
sha256: "1b0a4f9ecbaf9007771bac152afad738ddfacc4b8431a7591c00829480d99553"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.9.4"
|
||||
version: "15.0.4"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: "87c4a922cb6f811cfb7a889bdbb3622702443c52a0271636cbc90d813ceac147"
|
||||
sha256: c5a6443e66ae064fe186901d740ee7ce648ca2a6fd0484b8c5e963849ac0fc28
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.37"
|
||||
version: "4.5.42"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: "0d34dca01a7b103ed7f20138bffbb28eb0e61a677bf9e78a028a932e2c7322d5"
|
||||
sha256: "232ef63b986467ae5b5577a09c2502b26e2e2aebab5b85e6c966a5ca9b038b89"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.8.7"
|
||||
version: "3.8.12"
|
||||
fl_chart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -463,30 +366,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
|
@ -582,22 +461,6 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -734,6 +597,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -822,6 +709,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1147,14 +1050,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timezone
|
||||
sha256: a6ccda4a69a442098b602c44e61a1e2b4bf6f5516e875bbf0f427d5df14745d5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3"
|
||||
toggle_switch:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1291,14 +1186,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
visibility_detector:
|
||||
dependency: transitive
|
||||
video_player:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: visibility_detector
|
||||
sha256: "15c54a459ec2c17b4705450483f3d5a2858e733aee893dcee9d75fd04814940d"
|
||||
name: video_player
|
||||
sha256: e30df0d226c4ef82e2c150ebf6834b3522cf3f654d8e2f9419d376cdc071425d
|
||||
url: "https://pub.dev"
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1307,46 +1234,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
wakelock:
|
||||
wakelock_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock
|
||||
sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db"
|
||||
name: wakelock_plus
|
||||
sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.2"
|
||||
wakelock_macos:
|
||||
version: "1.2.8"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_macos
|
||||
sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd"
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
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"
|
||||
version: "1.2.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1391,10 +1294,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
|
||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "5.5.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
23
pubspec.yaml
23
pubspec.yaml
|
|
@ -61,15 +61,15 @@ dependencies:
|
|||
url_launcher: ^6.0.18
|
||||
audio_video_progress_bar: ^2.0.0
|
||||
image_cropper: ^1.5.0
|
||||
firebase_messaging: ^14.1.3
|
||||
firebase_core: ^2.3.0
|
||||
firebase_core: ^3.1.0
|
||||
firebase_messaging: ^15.0.1
|
||||
webview_flutter: ^4.2.0
|
||||
expandable_bottom_sheet: ^1.1.1+1
|
||||
permission_handler: ^11.0.0
|
||||
better_player:
|
||||
git:
|
||||
url: https://github.com/tintran-dev/betterplayer.git
|
||||
assets_audio_player: ^3.1.1
|
||||
# better_player:
|
||||
# git:
|
||||
# url: https://github.com/tintran-dev/betterplayer.git
|
||||
# assets_audio_player: ^3.1.1
|
||||
fl_chart: ^0.63.0
|
||||
collection: ^1.17.2
|
||||
animated_custom_dropdown: ^3.0.0
|
||||
|
|
@ -78,14 +78,15 @@ dependencies:
|
|||
http: any
|
||||
http_parser: any
|
||||
cached_network_image_platform_interface: any
|
||||
flutter_local_notifications: ^17.1.2
|
||||
awesome_notifications_core: ^0.9.0
|
||||
awesome_notifications: any
|
||||
awesome_notifications: ^0.8.2
|
||||
home_widget: ^0.5.0
|
||||
android_intent_plus: ^5.0.0
|
||||
get: ^4.6.6
|
||||
firebase_auth: ^4.19.6
|
||||
audioplayers: ^6.0.0
|
||||
# firebase_auth: ^4.19.6
|
||||
just_audio: ^0.9.39
|
||||
video_player: ^2.8.7
|
||||
chewie: ^1.8.3
|
||||
# onesignal_flutter: ^3.5.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue