D1APP-31 basic ui + audio recording support

This commit is contained in:
MohammadTaha Basiri 2022-01-01 14:12:44 +03:30
parent 551061111e
commit ba83575aaf
16 changed files with 325 additions and 40 deletions

View File

@ -26,7 +26,8 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
compileSdkVersion 31
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8

View File

@ -1,5 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.didvan.didvanapp">
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:label="Didvan"
android:icon="@mipmap/ic_launcher">

View File

@ -0,0 +1,135 @@
import 'dart:developer';
import 'package:just_audio/just_audio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import 'package:universal_html/js.dart' as js;
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/widgets/didvan/scaffold.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
class Chat extends StatelessWidget {
const Chat({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
child: Stack(
children: [
Positioned(
top: 0,
bottom: 56,
left: 0,
right: 0,
child: DidvanScaffold(
appBarData: AppBarData(
hasBack: true,
subtitle: 'ارتباط با سردبیر',
title: 'رادار اقتصادی',
),
slivers: const [],
),
),
Positioned(
bottom: 0,
right: 0,
left: 0,
child: Container(
height: 56,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Theme.of(context).colorScheme.cardBorder,
),
),
color: Theme.of(context).colorScheme.surface,
),
child: Row(
children: [
const _VoiceRecorderButton(),
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'بنویسید یا پیام صوتی بگذارید...',
hintStyle: Theme.of(context)
.textTheme
.caption!
.copyWith(
color: Theme.of(context).colorScheme.disabledText,
),
),
onChanged: (value) {},
),
),
],
),
),
),
],
),
);
}
}
class _VoiceRecorderButton extends StatefulWidget {
const _VoiceRecorderButton({Key? key}) : super(key: key);
@override
_VoiceRecorderButtonState createState() => _VoiceRecorderButtonState();
}
class _VoiceRecorderButtonState extends State<_VoiceRecorderButton> {
final _recorder = Record();
final _player = AudioPlayer();
@override
void initState() {
_recorder.hasPermission();
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPressStart: (details) async {
if (!kIsWeb) {
Vibrate.feedback(FeedbackType.medium);
}
await _recorder.start();
},
onLongPressEnd: (details) async {
final path = await _recorder.stop();
if (kIsWeb) {
await _player.setUrl(path!);
} else {
await _player.setFilePath(path!);
}
await _player.play();
if (kIsWeb) {
js.context.callMethod('playAudio', ['/dash.mp3']);
}
},
child: Container(
color: Colors.transparent,
height: double.infinity,
width: 52,
child: Icon(
DidvanIcons.mic_solid,
color: Theme.of(context).colorScheme.focusedBorder,
),
),
);
}
@override
void dispose() {
_recorder.dispose();
_player.dispose();
super.dispose();
}
}

View File

@ -0,0 +1,3 @@
import 'package:didvan/providers/core_provider.dart';
class ChatState extends CoreProvier {}

View File

@ -133,7 +133,8 @@ class Settings extends StatelessWidget {
okText: 'تایید',
cancelText: 'بازگشت',
accentColor: Theme.of(context).colorScheme.primary,
okCancelStyle: Theme.of(context).textTheme.bodyText2!,
okStyle: Theme.of(context).textTheme.bodyText2!,
cancelStyle: Theme.of(context).textTheme.bodyText2!,
unselectedColor: Theme.of(context).colorScheme.text,
blurredBackground: true,
hourLabel: 'ساعت',

View File

@ -7,12 +7,12 @@ class SettingsState extends CoreProvier {
getSettingsFromStorage();
}
List<String> _notificationTimeRange = [];
List _notificationTimeRange = [];
String _fontFamily = 'Dana-FA';
double _fontSizeScale = 1;
String _brightness = 'light';
set notificationTimeRange(List<String> value) {
set notificationTimeRange(List value) {
_notificationTimeRange = value;
StorageService.setValue(
key: 'notificationTimeRange',
@ -21,7 +21,7 @@ class SettingsState extends CoreProvier {
);
}
List<String> get notificationTimeRange => _notificationTimeRange;
List get notificationTimeRange => _notificationTimeRange;
set fontFamily(String value) {
_fontFamily = value;

View File

@ -28,7 +28,12 @@ class MenuItem extends StatelessWidget {
color: Colors.transparent,
child: Row(
children: [
if (icon != null) Icon(icon, size: 18, color: color),
if (icon != null)
Icon(
icon,
size: 18,
color: color ?? Theme.of(context).colorScheme.title,
),
if (icon != null) const SizedBox(width: 4),
DidvanText(
title,

View File

@ -1,5 +1,7 @@
import 'package:didvan/pages/authentication/authentication.dart';
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/home/chat/chat.dart';
import 'package:didvan/pages/home/chat/chat_state.dart';
import 'package:didvan/pages/home/home.dart';
import 'package:didvan/pages/home/home_state.dart';
import 'package:didvan/pages/home/news/news_details/news_details.dart';
@ -73,7 +75,13 @@ class RouteGenerator {
child: const ChatList(),
),
);
case Routes.chat:
return _createRoute(
ChangeNotifierProvider<ChatState>(
create: (context) => ChatState(),
child: const Chat(),
),
);
default:
return _errorRoute();
}

View File

@ -8,4 +8,5 @@ class Routes {
static const String radarDetails = '/radar-details';
static const String newsDetails = '/news-details';
static const String chatList = '/chat-list';
static const String chat = '/chat';
}

View File

@ -1,15 +1,22 @@
import 'dart:io';
import 'package:didvan/models/settings_data.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
class AppInitializer {
static Future<void> setupServices() async {
final Directory appDir = await getApplicationDocumentsDirectory();
Hive.init(appDir.path);
// late final Directory appDir;
// late final Directory appTempsDir;
// if (!kIsWeb) {
await Hive.initFlutter();
// appDir = await getApplicationDocumentsDirectory();
// appTempsDir = await getApplicationDocumentsDirectory();
// }
// Hive.init(appDir.path);
// StorageService.appDocsDir = appDir.path;
// StorageService.appTempsDir = appTempsDir.path;
}
static Future<ThemeMode> initilizeSettings() async {

View File

@ -1,6 +1,9 @@
import 'package:hive/hive.dart';
class StorageService {
static late final String appDocsDir;
static late final String appTempsDir;
static Future<void> setValue({
required String key,
required dynamic value,

View File

@ -9,9 +9,8 @@ class DidvanAppBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
final MediaQueryData d = MediaQuery.of(context);
return Padding(
padding: EdgeInsets.only(top: d.padding.top, right: 4, left: 20),
padding: const EdgeInsets.only(right: 4, left: 20),
child: Row(
children: [
IconButton(
@ -34,7 +33,7 @@ class DidvanAppBar extends StatelessWidget {
),
if (appBarData.subtitle != null)
DidvanText(
appBarData.title!,
appBarData.subtitle!,
style: Theme.of(context).textTheme.overline,
color: Theme.of(context).colorScheme.caption,
),

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
@ -24,6 +25,7 @@ class DidvanBadge extends StatelessWidget {
text,
isEnglishFont: true,
style: Theme.of(context).textTheme.overline,
color: Theme.of(context).colorScheme.white,
),
),
);

View File

@ -15,10 +15,14 @@ class DidvanScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
return Scaffold(
body: CustomScrollView(
body: Padding(
padding: EdgeInsets.only(top: statusBarHeight),
child: CustomScrollView(
slivers: [
SliverAppBar(
toolbarHeight: kToolbarHeight,
backgroundColor: Theme.of(context).backgroundColor,
automaticallyImplyLeading: false,
pinned: true,
@ -39,6 +43,7 @@ class DidvanScaffold extends StatelessWidget {
),
],
),
),
);
}
}

View File

@ -8,6 +8,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
audio_session:
dependency: transitive
description:
name: audio_session
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.6+1"
boolean_selector:
dependency: transitive
description:
@ -85,6 +92,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.1"
cupertino_icons:
dependency: "direct main"
description:
@ -98,7 +112,7 @@ packages:
name: day_night_time_picker
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3+1"
version: "1.0.4+1"
fake_async:
dependency: transitive
description:
@ -177,6 +191,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_vibrate:
dependency: "direct main"
description:
name: flutter_vibrate
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
flutter_web_plugins:
dependency: transitive
description: flutter
@ -196,6 +217,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.15.0"
http:
dependency: transitive
description:
@ -245,6 +280,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
just_audio:
dependency: "direct main"
description:
name: just_audio
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.18"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
lints:
dependency: transitive
description:
@ -314,7 +370,7 @@ packages:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
version: "2.0.11"
path_provider_ios:
dependency: transitive
description:
@ -357,6 +413,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
url: "https://pub.dartlang.org"
source: hosted
version: "8.3.0"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "3.7.0"
petitparser:
dependency: transitive
description:
@ -398,7 +468,28 @@ packages:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
version: "6.0.2"
record:
dependency: "direct main"
description:
name: record
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
record_platform_interface:
dependency: transitive
description:
name: record_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
record_web:
dependency: "direct main"
description:
name: record_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1"
rive:
dependency: "direct main"
description:
@ -495,6 +586,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
universal_html:
dependency: "direct main"
description:
name: universal_html
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
universal_io:
dependency: transitive
description:
name: universal_io
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
uuid:
dependency: transitive
description:
@ -515,7 +620,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.2"
version: "2.3.3"
xdg_directories:
dependency: transitive
description:

View File

@ -48,6 +48,14 @@ dependencies:
cached_network_image: ^3.2.0
skeleton_text: ^3.0.0
carousel_slider: ^4.0.0
flutter_vibrate: ^1.3.0
hive_flutter: ^1.1.0
# flutter_sound: ^8.4.2
permission_handler: ^8.3.0
universal_html: ^2.0.8
record: ^3.0.2
just_audio: ^0.9.18
record_web: ^0.2.1
dev_dependencies:
flutter_test: