"Updated AndroidManifest.xml, added FlutterDownloader dependency, and modified various Dart files for UI and functionality changes."
This commit is contained in:
parent
4aebc144fa
commit
7c74587785
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.didvan.didvanapp">
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
|
@ -39,6 +40,40 @@
|
|||
<service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
|
||||
|
||||
<provider
|
||||
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
|
||||
android:authorities="${applicationId}.flutter_downloader.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- Begin FlutterDownloader customization -->
|
||||
<!-- disable default Initializer -->
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
android:exported="false"
|
||||
tools:node="merge">
|
||||
<meta-data
|
||||
android:name="androidx.work.WorkManagerInitializer"
|
||||
android:value="androidx.startup"
|
||||
tools:node="remove" />
|
||||
</provider>
|
||||
|
||||
<!-- declare customized Initializer -->
|
||||
<provider
|
||||
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
|
||||
android:authorities="${applicationId}.flutter-downloader-init"
|
||||
android:exported="false">
|
||||
<!-- changes this number to configure the maximum number of concurrent tasks -->
|
||||
<meta-data
|
||||
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
|
||||
android:value="5" />
|
||||
</provider>
|
||||
<!-- End FlutterDownloader customization -->
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
|
|
@ -66,6 +67,12 @@ void main() async {
|
|||
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
|
||||
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
|
||||
await NotificationService.initializeNotification();
|
||||
await FlutterDownloader.initialize(
|
||||
debug:
|
||||
true, // optional: set to false to disable printing logs to console (default: true)
|
||||
ignoreSsl:
|
||||
true // option: set to false to disable working with http links (default: false)
|
||||
);
|
||||
}
|
||||
|
||||
// FirebaseMessaging.onBackgroundMessage(_initPushNotification);
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ import 'package:didvan/services/storage/storage.dart';
|
|||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
class MediaService {
|
||||
|
|
@ -148,8 +149,8 @@ class MediaService {
|
|||
}
|
||||
}
|
||||
|
||||
static Future<String?> downloadFile(String url) async {
|
||||
final basename = p.basename(url).split('?accessToken=').first;
|
||||
static Future<String?> downloadFile(String url, {final String? name}) async {
|
||||
final basename = name ?? p.basename(url).split('?accessToken=').first;
|
||||
Directory? dir;
|
||||
try {
|
||||
if (Platform.isIOS) {
|
||||
|
|
@ -163,18 +164,24 @@ class MediaService {
|
|||
print("Cannot get download folder path $err");
|
||||
}
|
||||
}
|
||||
String path = "${dir?.path}${Platform.isIOS ? '/' : ''}$basename";
|
||||
|
||||
File file = File(path);
|
||||
|
||||
try {
|
||||
final http.Response audioResponse = await http.get(Uri.parse(url));
|
||||
final bytes = audioResponse.bodyBytes;
|
||||
file.writeAsBytes(bytes);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print("Exception$e");
|
||||
String path = "${dir?.path}${Platform.isIOS ? '/' : ''}";
|
||||
final status = await Permission.storage.request();
|
||||
if (status.isGranted) {
|
||||
try {
|
||||
await FlutterDownloader.enqueue(
|
||||
url: url,
|
||||
savedDir: path,
|
||||
fileName: basename,
|
||||
showNotification: true,
|
||||
openFileFromNotification: true,
|
||||
);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print("Exception$e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ class _AiState extends State<Ai> {
|
|||
const Padding(
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||
child: DidvanText(
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید و از وارد کردن اطلاعات حساس بپرهیزید.',
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید.',
|
||||
fontSize: 12,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -261,8 +261,6 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
style:
|
||||
ButtonStyleMode.primary,
|
||||
onPressed: () async {
|
||||
final state = context
|
||||
.read<AiChatState>();
|
||||
await state
|
||||
.changePlaceHolder(
|
||||
placeholder.text);
|
||||
|
|
@ -688,25 +686,12 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
onTap: () async {
|
||||
final url =
|
||||
'${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
|
||||
final download = kIsWeb
|
||||
kIsWeb
|
||||
? MediaService
|
||||
.downloadFileFromWeb(url)
|
||||
: await MediaService.downloadFile(
|
||||
url);
|
||||
AlertData alertData = AlertData(
|
||||
message: 'دانلود موفقیت آمیز بود',
|
||||
aLertType: ALertType.success);
|
||||
if (download == null) {
|
||||
alertData = AlertData(
|
||||
message:
|
||||
'دانلود موفقیت آمیز نبود',
|
||||
aLertType: ALertType.error);
|
||||
}
|
||||
Future.delayed(
|
||||
Duration.zero,
|
||||
() => ActionSheetUtils(context)
|
||||
.showAlert(alertData),
|
||||
);
|
||||
url,
|
||||
name: message.fileName);
|
||||
},
|
||||
child: Icon(
|
||||
DidvanIcons.download_solid,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.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';
|
||||
|
|
@ -184,14 +185,21 @@ class _HistoryAiChatPageState extends State<HistoryAiChatPage> {
|
|||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.text),
|
||||
.text,
|
||||
fontFamily:
|
||||
DesignConfig.fontFamily),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "\"${chat.title}\"",
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontFamily: DesignConfig
|
||||
.fontFamily,
|
||||
fontWeight:
|
||||
FontWeight.bold)),
|
||||
const TextSpan(
|
||||
TextSpan(
|
||||
style: TextStyle(
|
||||
fontFamily: DesignConfig
|
||||
.fontFamily),
|
||||
text:
|
||||
' با هوشان اطمینان دارید؟ '),
|
||||
]),
|
||||
|
|
@ -371,12 +379,15 @@ class _HistoryAiChatPageState extends State<HistoryAiChatPage> {
|
|||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 16,
|
||||
),
|
||||
DidvanText(
|
||||
chat.prompts![0].text.toString(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
fontSize: 12,
|
||||
),
|
||||
if (chat.prompts != null &&
|
||||
chat.prompts!.isNotEmpty &&
|
||||
chat.prompts![0].text != null)
|
||||
DidvanText(
|
||||
chat.prompts![0].text.toString(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
fontSize: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
? const Padding(
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||
child: DidvanText(
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید و از وارد کردن اطلاعات حساس بپرهیزید.',
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید.',
|
||||
fontSize: 12,
|
||||
),
|
||||
)
|
||||
|
|
@ -680,10 +680,11 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
MediaService.onLoadingPickFile(context);
|
||||
FilePickerResult? result = await MediaService.pickPdfFile();
|
||||
if (result != null) {
|
||||
String? name = result.files.first.name;
|
||||
|
||||
if (kIsWeb) {
|
||||
Uint8List? bytes =
|
||||
result.files.first.bytes; // Access the bytes property
|
||||
String? name = result.files.first.name;
|
||||
|
||||
// Store bytes and file name directly in your state or model
|
||||
state.file = FilesModel(
|
||||
|
|
@ -695,7 +696,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
);
|
||||
} else {
|
||||
state.file = FilesModel(result.files.single.path!,
|
||||
audio: false, image: false);
|
||||
audio: false, image: false, name: name);
|
||||
}
|
||||
}
|
||||
Future.delayed(
|
||||
|
|
@ -752,7 +753,8 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
state.file = kIsWeb
|
||||
? FilesModel(pickedFile.path,
|
||||
name: pickedFile.name, image: true, audio: false)
|
||||
: FilesModel(file!.path, image: true, audio: false);
|
||||
: FilesModel(file!.path,
|
||||
name: pickedFile.name, image: true, audio: false);
|
||||
await Future.delayed(
|
||||
Duration.zero,
|
||||
() => ActionSheetUtils(context).pop(),
|
||||
|
|
@ -773,10 +775,11 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
|
||||
FilePickerResult? result = await MediaService.pickAudioFile();
|
||||
if (result != null) {
|
||||
String? name = result.files.first.name;
|
||||
|
||||
if (kIsWeb) {
|
||||
Uint8List? bytes =
|
||||
result.files.first.bytes; // Access the bytes property
|
||||
String? name = result.files.first.name;
|
||||
|
||||
final blob = html.Blob([bytes]);
|
||||
final blobUrl = html.Url.createObjectUrlFromBlob(blob);
|
||||
|
|
@ -790,7 +793,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
);
|
||||
} else {
|
||||
state.file = FilesModel(result.files.single.path!,
|
||||
audio: true, image: false);
|
||||
name: name, audio: true, image: false);
|
||||
}
|
||||
}
|
||||
await Future.delayed(
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ class _AiMessageBarIOSState extends State<AiMessageBarIOS> {
|
|||
? const Padding(
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||
child: DidvanText(
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید و از وارد کردن اطلاعات حساس بپرهیزید.',
|
||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید.',
|
||||
fontSize: 12,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:didvan/services/app_initalizer.dart';
|
||||
import 'package:didvan/views/authentication/authentication_state.dart';
|
||||
import 'package:didvan/views/authentication/widgets/authentication_layout.dart';
|
||||
import 'package:didvan/views/widgets/didvan/button.dart';
|
||||
|
|
@ -7,6 +6,7 @@ import 'package:didvan/views/widgets/didvan/text_field.dart';
|
|||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
// import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class UsernameInput extends StatefulWidget {
|
||||
|
|
@ -79,10 +79,9 @@ class _UsernameInputState extends State<UsernameInput> {
|
|||
.bodySmall!
|
||||
.copyWith(color: Theme.of(context).colorScheme.primary),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => AppInitializer.openWebLink(
|
||||
context,
|
||||
'https://didvan.com/terms-of-use#conditions',
|
||||
),
|
||||
..onTap = () => launchUrlString(
|
||||
'https://didvan.com/terms-of-use#conditions',
|
||||
mode: LaunchMode.inAppWebView),
|
||||
),
|
||||
const TextSpan(text: 'و\n'),
|
||||
TextSpan(
|
||||
|
|
@ -92,10 +91,9 @@ class _UsernameInputState extends State<UsernameInput> {
|
|||
.bodySmall!
|
||||
.copyWith(color: Theme.of(context).colorScheme.primary),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => AppInitializer.openWebLink(
|
||||
context,
|
||||
'https://didvan.com/terms-of-use#privacy',
|
||||
),
|
||||
..onTap = () => launchUrlString(
|
||||
'https://didvan.com/terms-of-use#privacy',
|
||||
mode: LaunchMode.inAppWebView),
|
||||
),
|
||||
const TextSpan(text: 'را میپذیرم'),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -259,8 +259,7 @@ class DirectState extends CoreProvier {
|
|||
}
|
||||
|
||||
text = null;
|
||||
replyRadar = null;
|
||||
replyNews = null;
|
||||
|
||||
notifyListeners();
|
||||
|
||||
final service =
|
||||
|
|
@ -271,7 +270,11 @@ class DirectState extends CoreProvier {
|
|||
|
||||
if (service.isSuccess) {
|
||||
final message = service.result['message'];
|
||||
messages.insert(0, MessageData.fromJson(message));
|
||||
|
||||
messages.insert(
|
||||
0,
|
||||
MessageData.fromJson(message)
|
||||
.copyWith(news: replyNews, radar: replyRadar));
|
||||
|
||||
dailyMessages.clear();
|
||||
|
||||
|
|
@ -303,8 +306,10 @@ class DirectState extends CoreProvier {
|
|||
_addToDailyGrouped(messages[i]);
|
||||
}
|
||||
}
|
||||
path = null;
|
||||
}
|
||||
path = null;
|
||||
replyRadar = null;
|
||||
replyNews = null;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,77 +315,76 @@ class _HomeState extends State<Home>
|
|||
// height: 12,
|
||||
// ),
|
||||
Expanded(
|
||||
child: state.chats.isEmpty
|
||||
? Padding(
|
||||
child: state.loadingdeleteAll ||
|
||||
state.appState == AppState.busy
|
||||
? ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: 10,
|
||||
padding:
|
||||
const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.emptyResult,
|
||||
height: MediaQuery.sizeOf(
|
||||
context)
|
||||
.height /
|
||||
10,
|
||||
),
|
||||
const DidvanText(
|
||||
'لیست خالی است',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: state.loadingdeleteAll ||
|
||||
state.appState ==
|
||||
AppState.busy
|
||||
? ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: 10,
|
||||
padding: const EdgeInsets
|
||||
.symmetric(
|
||||
const EdgeInsets.symmetric(
|
||||
horizontal: 12),
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(),
|
||||
itemBuilder:
|
||||
(context, index) {
|
||||
return const Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(
|
||||
vertical: 12.0),
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
ClipOval(
|
||||
child:
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child:
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 12,
|
||||
),
|
||||
],
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 12.0),
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
ClipOval(
|
||||
child:
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child:
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
ShimmerPlaceholder(
|
||||
height: 24,
|
||||
width: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
: state.chats.isEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(
|
||||
12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.emptyResult,
|
||||
height:
|
||||
MediaQuery.sizeOf(
|
||||
context)
|
||||
.height /
|
||||
10,
|
||||
),
|
||||
const DidvanText(
|
||||
'لیست خالی است',
|
||||
fontSize: 14,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
|
|
@ -542,62 +541,62 @@ class _HomeState extends State<Home>
|
|||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: chat.isEditing != null && chat.isEditing!
|
||||
? TextFormField(
|
||||
controller: title,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
textAlignVertical: TextAlignVertical.bottom,
|
||||
maxLines: 1,
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
border: OutlineInputBorder(),
|
||||
))
|
||||
: Text(
|
||||
chat.title.toString(),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
child: Text(
|
||||
chat.title.toString(),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 24,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
chat.isEditing != null &&
|
||||
chat.isEditing! &&
|
||||
state.loadingchangeTitle
|
||||
? const SizedBox(
|
||||
width: 12,
|
||||
height: 12,
|
||||
child: CircularProgressIndicator())
|
||||
: InkWell(
|
||||
onTap: () async {
|
||||
if (title.text.isNotEmpty) {
|
||||
await state.changeNameChat(
|
||||
chat.id!, index, title.text,
|
||||
refresh: false);
|
||||
title.clear();
|
||||
}
|
||||
if (chat.isEditing != null) {
|
||||
chat.isEditing = !chat.isEditing!;
|
||||
state.update();
|
||||
return;
|
||||
}
|
||||
chat.isEditing = true;
|
||||
|
||||
state.update();
|
||||
},
|
||||
child: Icon(
|
||||
chat.isEditing != null && chat.isEditing!
|
||||
? Icons.save
|
||||
: Icons.edit_outlined,
|
||||
size: 18,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
ActionSheetUtils(context).openDialog(
|
||||
data: ActionSheetData(
|
||||
content: Center(
|
||||
child: TextFormField(
|
||||
controller: title,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
textAlignVertical: TextAlignVertical.bottom,
|
||||
maxLines: 3,
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 5, horizontal: 10),
|
||||
border: OutlineInputBorder(),
|
||||
)),
|
||||
),
|
||||
title: 'تغییر نام',
|
||||
onConfirmed: () async {
|
||||
if (title.text.isNotEmpty) {
|
||||
await state.changeNameChat(
|
||||
chat.id!, index, title.text,
|
||||
refresh: false);
|
||||
title.clear();
|
||||
}
|
||||
if (chat.isEditing != null) {
|
||||
chat.isEditing = !chat.isEditing!;
|
||||
state.update();
|
||||
return;
|
||||
}
|
||||
|
||||
state.update();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.edit_outlined,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
width: 4,
|
||||
),
|
||||
PopupMenuButton(
|
||||
onSelected: (value) async {
|
||||
|
|
@ -621,22 +620,25 @@ class _HomeState extends State<Home>
|
|||
value: 'حذف پیام',
|
||||
icon: DidvanIcons.trash_regular,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
height: 24,
|
||||
size: 12),
|
||||
height: 32,
|
||||
size: 16),
|
||||
ActionSheetUtils.popUpBtns(
|
||||
value: 'آرشیو',
|
||||
icon: Icons.folder_copy,
|
||||
height: 24,
|
||||
size: 12,
|
||||
height: 32,
|
||||
size: 16,
|
||||
),
|
||||
];
|
||||
},
|
||||
offset: const Offset(0, 0),
|
||||
position: PopupMenuPosition.under,
|
||||
useRootNavigator: true,
|
||||
child: const Icon(
|
||||
Icons.more_vert,
|
||||
size: 18,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.more_vert,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class _EditProfileState extends State<EditProfile> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: DidvanText(
|
||||
'نام کاربری میتواند شامل کاراکترهای کوچک و بزرگ انگلیسی و اعداد باشد.',
|
||||
'نام کاربری میتواند شامل کاراکترهای انگلیسی و اعداد باشد.',
|
||||
style: Theme.of(context).textTheme.labelSmall,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import 'package:didvan/models/view/app_bar_data.dart';
|
|||
import 'package:didvan/providers/theme.dart';
|
||||
import 'package:didvan/providers/user.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/services/app_initalizer.dart';
|
||||
import 'package:didvan/services/storage/storage.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/views/profile/general_settings/settings_state.dart';
|
||||
|
|
@ -23,6 +22,7 @@ import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class ProfilePage extends StatefulWidget {
|
||||
const ProfilePage({Key? key}) : super(key: key);
|
||||
|
|
@ -221,8 +221,9 @@ class _ProfilePageState extends State<ProfilePage> {
|
|||
MenuOption(
|
||||
icon: DidvanIcons.info_circle_regular,
|
||||
title: 'معرفی دیدوان',
|
||||
onTap: () => AppInitializer.openWebLink(
|
||||
context, 'https://didvan.com/#info'),
|
||||
onTap: () => launchUrlString(
|
||||
'https://didvan.com/#info',
|
||||
mode: LaunchMode.inAppWebView),
|
||||
),
|
||||
const DidvanDivider(),
|
||||
MenuOption(
|
||||
|
|
@ -338,10 +339,9 @@ class _ProfilePageState extends State<ProfilePage> {
|
|||
MenuOption(
|
||||
icon: DidvanIcons.alert_regular,
|
||||
title: 'حریم خصوصی',
|
||||
onTap: () => AppInitializer.openWebLink(
|
||||
context,
|
||||
'https://didvan.com/terms-of-use#privacy',
|
||||
),
|
||||
onTap: () => launchUrlString(
|
||||
'https://didvan.com/terms-of-use#privacy',
|
||||
mode: LaunchMode.inAppWebView),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -406,6 +406,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
flutter_downloader:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_downloader
|
||||
sha256: b6da5495b6258aa7c243d0f0a5281e3430b385bccac11cc508f981e653b25aa6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.8"
|
||||
flutter_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ dependencies:
|
|||
|
||||
js: any
|
||||
flutter_sound_platform_interface: any
|
||||
flutter_downloader: ^1.11.8
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
|||
Loading…
Reference in New Issue