D1APP-31 basic ui + audio recording support
This commit is contained in:
parent
551061111e
commit
ba83575aaf
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import 'package:didvan/providers/core_provider.dart';
|
||||
|
||||
class ChatState extends CoreProvier {}
|
||||
|
|
@ -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: 'ساعت',
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
113
pubspec.lock
113
pubspec.lock
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue