From 5950cc02446e86b423f6368d0db39da9ff117ebc Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:12:52 +0300 Subject: [PATCH 1/8] Update MainActivity.kt --- .../hassaneltantawy/ruqayyah/MainActivity.kt | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt b/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt index 9a2b513..c0576b6 100644 --- a/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt +++ b/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt @@ -3,4 +3,44 @@ package com.hassaneltantawy.ruqayyah import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { + private lateinit var channel: MethodChannel + private var activateVolumeDispatch:Boolean = false + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "volume_button_channel") + channel.setMethodCallHandler { call, _ -> + if (call.method == "activate_volumeBtn") { + activateVolumeDispatch = call.arguments as Boolean + } + } + } + + override fun dispatchKeyEvent(event: KeyEvent): Boolean { + val action: Int = event.getAction() + val keyCode: Int = event.getKeyCode() + if (!activateVolumeDispatch){ + return super.dispatchKeyEvent(event) + } + return when (keyCode) { + KeyEvent.KEYCODE_VOLUME_UP -> { + if (action == KeyEvent.ACTION_DOWN) { + channel.invokeMethod("volumeBtnPressed", "VOLUME_UP_DOWN") + } else if (action == KeyEvent.ACTION_UP) { + channel.invokeMethod("volumeBtnPressed", "VOLUME_UP_UP") + } + true + } + KeyEvent.KEYCODE_VOLUME_DOWN -> { + if (action == KeyEvent.ACTION_DOWN) { + channel.invokeMethod("volumeBtnPressed", "VOLUME_DOWN_DOWN") + } else if (action == KeyEvent.ACTION_UP) { + channel.invokeMethod("volumeBtnPressed", "VOLUME_DOWN_UP") + } + true + } + + else -> super.dispatchKeyEvent(event) + } + } } From 5c6a0bbafb204012131bcec4a949d1124f63d51a Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:13:07 +0300 Subject: [PATCH 2/8] Create volume_button_manager.dart --- .../src/core/utils/volume_button_manager.dart | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 ruqayyah/lib/src/core/utils/volume_button_manager.dart diff --git a/ruqayyah/lib/src/core/utils/volume_button_manager.dart b/ruqayyah/lib/src/core/utils/volume_button_manager.dart new file mode 100644 index 0000000..ff2cbb0 --- /dev/null +++ b/ruqayyah/lib/src/core/utils/volume_button_manager.dart @@ -0,0 +1,48 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; + +class VolumeButtonManager { + static MethodChannel channel = const MethodChannel("volume_button_channel"); + + void listen({ + Function()? onVolumeUpPressed, + Function()? onVolumeDownPressed, + Function()? onVolumeUpReleased, + Function()? onVolumeDownReleased, + }) { + channel.setMethodCallHandler( + (call) async { + if (call.method == "volumeBtnPressed") { + switch (call.arguments) { + case "VOLUME_UP_DOWN": + onVolumeUpPressed?.call(); + + case "VOLUME_DOWN_DOWN": + onVolumeDownPressed?.call(); + + case "VOLUME_UP_UP": + onVolumeUpReleased?.call(); + + case "VOLUME_DOWN_UP": + onVolumeDownReleased?.call(); + } + } + }, + ); + } + + Future toggleActivation({required bool activate}) async { + if (Platform.isAndroid) { + await channel.invokeMethod( + 'activate_volumeBtn', + activate, + ); + } + } + + void dispose() { + toggleActivation(activate: false); + channel.setMethodCallHandler(null); + } +} From 8343209705d1524b4db414a560437bab0fc4a152 Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:16:32 +0300 Subject: [PATCH 3/8] impl volume manager in rukia viewer --- ruqayyah/lib/src/core/di/dependency_injection.dart | 2 ++ .../presentation/screens/rukia_viewer_screen.dart | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/ruqayyah/lib/src/core/di/dependency_injection.dart b/ruqayyah/lib/src/core/di/dependency_injection.dart index 472e8f4..4885828 100644 --- a/ruqayyah/lib/src/core/di/dependency_injection.dart +++ b/ruqayyah/lib/src/core/di/dependency_injection.dart @@ -1,6 +1,7 @@ import 'package:get_it/get_it.dart'; import 'package:get_storage/get_storage.dart'; import 'package:ruqayyah/src/core/constants/const.dart'; +import 'package:ruqayyah/src/core/utils/volume_button_manager.dart'; import 'package:ruqayyah/src/features/effects_manager/data/repository/effects_repo.dart'; import 'package:ruqayyah/src/features/effects_manager/presentation/controller/effect_manager.dart'; import 'package:ruqayyah/src/features/home/data/repository/ruki_db_helper.dart'; @@ -26,6 +27,7 @@ Future initSL() async { ///MARK: Init Manager sl.registerFactory(() => EffectsManager(sl())); + sl.registerFactory(() => VolumeButtonManager()); ///MARK: Init BLOC diff --git a/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart b/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart index 9d21470..bd1c5dd 100644 --- a/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart +++ b/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart @@ -1,6 +1,7 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/material.dart'; import 'package:ruqayyah/src/core/di/dependency_injection.dart'; +import 'package:ruqayyah/src/core/utils/volume_button_manager.dart'; import 'package:ruqayyah/src/features/effects_manager/presentation/controller/effect_manager.dart'; import 'package:ruqayyah/src/features/home/data/models/rukia.dart'; import 'package:ruqayyah/src/features/home/data/models/rukia_type_enum.dart'; @@ -39,6 +40,16 @@ class _RukiaViewerScreenState extends State { if (sl().enableWakeLock) { WakelockPlus.enable(); } + + sl().toggleActivation( + activate: sl().praiseWithVolumeKeys, + ); + + sl().listen( + onVolumeUpPressed: () => _onTap(currentPage), + onVolumeDownPressed: () => _onTap(currentPage), + ); + _loadData(); } @@ -46,6 +57,7 @@ class _RukiaViewerScreenState extends State { void dispose() { _pageController.dispose(); WakelockPlus.disable(); + sl().dispose(); super.dispose(); } From a7cba8ef9a6ec27f111bda1a7ca358c4853df170 Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:23:16 +0300 Subject: [PATCH 4/8] fix: effect on count not saved --- .../settings/presentation/controller/cubit/settings_cubit.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruqayyah/lib/src/features/settings/presentation/controller/cubit/settings_cubit.dart b/ruqayyah/lib/src/features/settings/presentation/controller/cubit/settings_cubit.dart index 0ca17d9..7ec992b 100644 --- a/ruqayyah/lib/src/features/settings/presentation/controller/cubit/settings_cubit.dart +++ b/ruqayyah/lib/src/features/settings/presentation/controller/cubit/settings_cubit.dart @@ -63,7 +63,7 @@ class SettingsCubit extends Cubit { if (activate) { effectsManager.onCountSound(); } - await effectsRepo.changeSingleDoneSoundStatus(value: activate); + await effectsRepo.changeOnCountStatus(value: activate); emit( state.copyWith( zikrEffects: state.zikrEffects.copyWith(soundOnCount: activate), From 160d550307267d865c2c52e8741c4e84d94b65b5 Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:23:51 +0300 Subject: [PATCH 5/8] Control praise with volume keys from settings --- ruqayyah/lib/generated/intl/messages_ar.dart | 2 ++ ruqayyah/lib/generated/intl/messages_en.dart | 2 ++ ruqayyah/lib/generated/l10n.dart | 10 ++++++++++ ruqayyah/lib/l10n/intl_ar.arb | 1 + ruqayyah/lib/l10n/intl_en.arb | 1 + .../settings/presentation/screens/settings_screen.dart | 10 ++++++++++ 6 files changed, 26 insertions(+) diff --git a/ruqayyah/lib/generated/intl/messages_ar.dart b/ruqayyah/lib/generated/intl/messages_ar.dart index 9dd2056..c55eab5 100644 --- a/ruqayyah/lib/generated/intl/messages_ar.dart +++ b/ruqayyah/lib/generated/intl/messages_ar.dart @@ -52,6 +52,8 @@ class MessageLookup extends MessageLookupByLibrary { "اهتزاز الهاتف عند انتهاء جميع الأذكار"), "prayForUsAndParents": MessageLookupByLibrary.simpleMessage("نسألكم الدعاء لنا ولوالدينا"), + "prefPraiseWithVolumeKeys": + MessageLookupByLibrary.simpleMessage("التسبيح بمفاتيح الصوت"), "rukiaBookAuthor": MessageLookupByLibrary.simpleMessage( "د. خالد بن عبدالرحمن الجريسي"), "rukiaBookTitle": MessageLookupByLibrary.simpleMessage( diff --git a/ruqayyah/lib/generated/intl/messages_en.dart b/ruqayyah/lib/generated/intl/messages_en.dart index ac306ae..33df4a0 100644 --- a/ruqayyah/lib/generated/intl/messages_en.dart +++ b/ruqayyah/lib/generated/intl/messages_en.dart @@ -53,6 +53,8 @@ class MessageLookup extends MessageLookupByLibrary { "Phone vibration when all zikr end"), "prayForUsAndParents": MessageLookupByLibrary.simpleMessage( "Pray for us and our parents."), + "prefPraiseWithVolumeKeys": + MessageLookupByLibrary.simpleMessage("Praise with volume keys"), "rukiaBookAuthor": MessageLookupByLibrary.simpleMessage( "Dr. Khalid bin Abdulrahman Al-Juraisi"), "rukiaBookTitle": MessageLookupByLibrary.simpleMessage( diff --git a/ruqayyah/lib/generated/l10n.dart b/ruqayyah/lib/generated/l10n.dart index 99532c8..e7ac458 100644 --- a/ruqayyah/lib/generated/l10n.dart +++ b/ruqayyah/lib/generated/l10n.dart @@ -260,6 +260,16 @@ class S { ); } + /// `Praise with volume keys` + String get prefPraiseWithVolumeKeys { + return Intl.message( + 'Praise with volume keys', + name: 'prefPraiseWithVolumeKeys', + desc: '', + args: [], + ); + } + /// `Dr. Khalid bin Abdulrahman Al-Juraisi` String get rukiaBookAuthor { return Intl.message( diff --git a/ruqayyah/lib/l10n/intl_ar.arb b/ruqayyah/lib/l10n/intl_ar.arb index 981c0fc..0ca0891 100644 --- a/ruqayyah/lib/l10n/intl_ar.arb +++ b/ruqayyah/lib/l10n/intl_ar.arb @@ -20,6 +20,7 @@ "phoneVibrationAtSingleZikrEnd": "اهتزاز الهاتف عند انتهاء كل ذكر", "phoneVibrationWhenAllZikrEnd": "اهتزاز الهاتف عند انتهاء جميع الأذكار", "prayForUsAndParents": "نسألكم الدعاء لنا ولوالدينا", + "prefPraiseWithVolumeKeys": "التسبيح بمفاتيح الصوت", "rukiaBookAuthor": "د. خالد بن عبدالرحمن الجريسي", "rukiaBookTitle": "الرقية الشرعية من القرآن الكريم والسنة النبوية", "ruqyahEtiquette": "آداب الرقية", diff --git a/ruqayyah/lib/l10n/intl_en.arb b/ruqayyah/lib/l10n/intl_en.arb index 2a9e97b..6d169c8 100644 --- a/ruqayyah/lib/l10n/intl_en.arb +++ b/ruqayyah/lib/l10n/intl_en.arb @@ -20,6 +20,7 @@ "phoneVibrationAtSingleZikrEnd": "Phone vibration at single zikr end", "phoneVibrationWhenAllZikrEnd": "Phone vibration when all zikr end", "prayForUsAndParents": "Pray for us and our parents.", + "prefPraiseWithVolumeKeys": "Praise with volume keys", "rukiaBookAuthor": "Dr. Khalid bin Abdulrahman Al-Juraisi", "rukiaBookTitle": "Al-Ruqyah Al-Shar'iyyah from the Quran Al-Kareem and the Sunnah Al-Nabawiyyah", "ruqyahEtiquette": "Ruqyah Etiquette", diff --git a/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart b/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart index b5033b1..6ea7935 100644 --- a/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart +++ b/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart @@ -78,6 +78,16 @@ class SettingsGeneralSection extends StatelessWidget { builder: (context, state) { return Column( children: [ + SwitchListTile( + secondary: const Icon(Icons.volume_down), + value: state.praiseWithVolumeKeys, + title: Text(S.of(context).prefPraiseWithVolumeKeys), + onChanged: (value) { + context.read().togglePraiseWithVolumeKeys( + use: !state.praiseWithVolumeKeys, + ); + }, + ), SwitchListTile( secondary: const Icon(Icons.screenshot), value: state.enableWakeLock, From 74006ed22e029db204a1632abd5f68b24533dc04 Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 05:26:50 +0300 Subject: [PATCH 6/8] .. --- ruqayyah/lib/app.dart | 2 +- .../settings/presentation/screens/settings_screen.dart | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ruqayyah/lib/app.dart b/ruqayyah/lib/app.dart index e8dbfa0..627c366 100644 --- a/ruqayyah/lib/app.dart +++ b/ruqayyah/lib/app.dart @@ -25,7 +25,7 @@ class MyApp extends StatelessWidget { onGenerateTitle: (context) => S.of(context).appTitle, scrollBehavior: AppScrollBehavior(), debugShowCheckedModeBanner: false, - locale: const Locale('ar', 'EG'), + locale: const Locale('ar'), supportedLocales: S.delegate.supportedLocales, localizationsDelegates: const [ S.delegate, diff --git a/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart b/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart index 6ea7935..dfdc6ff 100644 --- a/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart +++ b/ruqayyah/lib/src/features/settings/presentation/screens/settings_screen.dart @@ -20,9 +20,7 @@ class _SettingsScreenState extends State { appBar: AppBar( centerTitle: true, elevation: 0, - title: const Text( - "الإعدادات", - ), + title: Text(S.of(context).settings), ), body: ListView( children: [ From 9cada895e25b420267fc2aeabb452be9a2c41d25 Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 07:03:37 +0300 Subject: [PATCH 7/8] Update MainActivity.kt --- .../main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt b/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt index c0576b6..6090de5 100644 --- a/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt +++ b/ruqayyah/android/app/src/main/kotlin/com/hassaneltantawy/ruqayyah/MainActivity.kt @@ -1,9 +1,12 @@ package com.hassaneltantawy.ruqayyah import io.flutter.embedding.android.FlutterActivity +import android.view.KeyEvent +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodChannel class MainActivity: FlutterActivity() { - private lateinit var channel: MethodChannel + private lateinit var channel: MethodChannel private var activateVolumeDispatch:Boolean = false override fun configureFlutterEngine(flutterEngine: FlutterEngine) { From 1987572922978b180b468c11f510fc02a9dbb78a Mon Sep 17 00:00:00 2001 From: 7eltantawy Date: Tue, 24 Sep 2024 07:03:52 +0300 Subject: [PATCH 8/8] Update rukia_viewer_screen.dart --- .../screens/rukia_viewer_screen.dart | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart b/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart index bd1c5dd..5a684a3 100644 --- a/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart +++ b/ruqayyah/lib/src/features/home/presentation/screens/rukia_viewer_screen.dart @@ -34,11 +34,23 @@ class _RukiaViewerScreenState extends State { void initState() { super.initState(); + _start(); + } + + @override + void dispose() { + _pageController.dispose(); + WakelockPlus.disable(); + sl().dispose(); + super.dispose(); + } + + Future _start() async { _pageController = PageController(); _pageController.addListener(_pageChange); if (sl().enableWakeLock) { - WakelockPlus.enable(); + await WakelockPlus.enable(); } sl().toggleActivation( @@ -50,24 +62,22 @@ class _RukiaViewerScreenState extends State { onVolumeDownPressed: () => _onTap(currentPage), ); - _loadData(); - } + await _loadData(); - @override - void dispose() { - _pageController.dispose(); - WakelockPlus.disable(); - sl().dispose(); - super.dispose(); + setState(() { + isLoading = false; + }); } Future _loadData() async { rukiasToView = await sl().getRukiaListByType(widget.rukiaType); + } - setState(() { - isLoading = false; - }); + Future _reset() async { + await _loadData(); + _pageController.jumpTo(0); + setState(() {}); } void _pageChange() { @@ -110,7 +120,7 @@ class _RukiaViewerScreenState extends State { @override Widget build(BuildContext context) { - if (isLoading) return const SizedBox(); + if (isLoading) return const Center(child: CircularProgressIndicator()); return Scaffold( appBar: AppBar( @@ -163,8 +173,7 @@ class _RukiaViewerScreenState extends State { ), IconButton( onPressed: () { - _pageController.jumpTo(0); - _loadData(); + _reset(); }, icon: const Icon(Icons.repeat), ),