fixed story index bug
This commit is contained in:
parent
283938d759
commit
5f02802ad1
|
|
@ -17,6 +17,7 @@
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="Didvan"
|
android:label="Didvan"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
|
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".FavWidget"
|
android:name=".FavWidget"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ class MainPageBannerType {
|
||||||
|
|
||||||
factory MainPageBannerType.fromJson(Map<String, dynamic> json) {
|
factory MainPageBannerType.fromJson(Map<String, dynamic> json) {
|
||||||
return MainPageBannerType(
|
return MainPageBannerType(
|
||||||
// fix if it null
|
|
||||||
image: json['image'] ?? '',
|
image: json['image'] ?? '',
|
||||||
link: json['link'],
|
link: json['link'],
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
|
||||||
class MainPageContentType {
|
class MainPageContentType {
|
||||||
final int id;
|
final int id;
|
||||||
final String title;
|
final String title;
|
||||||
final String image;
|
final String image;
|
||||||
final String link;
|
final String link;
|
||||||
bool marked;
|
bool marked;
|
||||||
|
bool isViewed;
|
||||||
final List<String> subtitles;
|
final List<String> subtitles;
|
||||||
final int? duration;
|
final int? duration;
|
||||||
|
|
||||||
|
|
@ -13,6 +15,7 @@ class MainPageContentType {
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.link,
|
required this.link,
|
||||||
required this.marked,
|
required this.marked,
|
||||||
|
required this.isViewed,
|
||||||
required this.subtitles,
|
required this.subtitles,
|
||||||
this.duration,
|
this.duration,
|
||||||
});
|
});
|
||||||
|
|
@ -24,7 +27,8 @@ class MainPageContentType {
|
||||||
image: json['image'],
|
image: json['image'],
|
||||||
link: json['link'],
|
link: json['link'],
|
||||||
marked: json['marked'],
|
marked: json['marked'],
|
||||||
|
isViewed: json['isViewed'] ?? false,
|
||||||
subtitles: List<String>.from(json['subtitles']),
|
subtitles: List<String>.from(json['subtitles']),
|
||||||
duration: json['duration'],
|
duration: json['duration'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
|
|
||||||
class SliderData {
|
class SliderData {
|
||||||
final int id;
|
final int id;
|
||||||
final String title;
|
final String title;
|
||||||
final String image;
|
final String image;
|
||||||
final String link;
|
final String link;
|
||||||
|
final bool isViewed;
|
||||||
const SliderData({
|
const SliderData({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.link,
|
required this.link,
|
||||||
|
required this.isViewed,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory SliderData.fromJson(Map<String, dynamic> json) => SliderData(
|
factory SliderData.fromJson(Map<String, dynamic> json) => SliderData(
|
||||||
|
|
@ -16,11 +18,14 @@ class SliderData {
|
||||||
title: json['title'],
|
title: json['title'],
|
||||||
image: json['image'],
|
image: json['image'],
|
||||||
link: json['link'],
|
link: json['link'],
|
||||||
|
isViewed: json['isViewed'] ?? false,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'id': id,
|
'id': id,
|
||||||
'title': title,
|
'title': title,
|
||||||
'image': image,
|
'image': image,
|
||||||
|
'link': link,
|
||||||
|
'isViewed': isViewed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:didvan/models/ai/ai_chat_args.dart';
|
import 'package:didvan/models/ai/ai_chat_args.dart';
|
||||||
import 'package:didvan/models/story_model.dart';
|
import 'package:didvan/models/story_model.dart';
|
||||||
import 'package:didvan/views/ai/ai_chat_page.dart';
|
import 'package:didvan/views/ai/ai_chat_page.dart';
|
||||||
|
|
@ -494,6 +496,7 @@ class RouteGenerator {
|
||||||
textScaler: const TextScaler.linear(1.0),
|
textScaler: const TextScaler.linear(1.0),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: AspectRatio(aspectRatio: 9 / 16, child: page),
|
child: AspectRatio(aspectRatio: 9 / 16, child: page),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// ignore_for_file: depend_on_referenced_packages, avoid_web_libraries_in_flutter
|
// ignore_for_file: depend_on_referenced_packages, avoid_web_libraries_in_flutter, avoid_print
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
import 'package:didvan/models/studio_details_data.dart';
|
import 'package:didvan/models/studio_details_data.dart';
|
||||||
|
|
@ -9,7 +10,6 @@ import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
import 'package:didvan/services/storage/storage.dart';
|
import 'package:didvan/services/storage/storage.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
@ -90,17 +90,7 @@ class MediaService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await audioPlayer.play();
|
await audioPlayer.play();
|
||||||
// await audioPlayer.open(
|
|
||||||
// audio,
|
|
||||||
// showNotification: !isVoiceMessage,
|
|
||||||
// notificationSettings: NotificationSettings(
|
|
||||||
// customStopAction: (_) => resetAudioPlayer(),
|
|
||||||
// customNextAction: (_) => onTrackChanged?.call(true),
|
|
||||||
// customPrevAction: (_) => onTrackChanged?.call(false),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// resetAudioPlayer();
|
|
||||||
// rethrow;
|
// rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +123,6 @@ class MediaService {
|
||||||
return result;
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
e.printError(info: 'Pick PDF Fail');
|
e.printError(info: 'Pick PDF Fail');
|
||||||
// navigatorKey.currentState!.pop();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,30 +132,11 @@ class MediaService {
|
||||||
return await FilePicker.platform
|
return await FilePicker.platform
|
||||||
.pickFiles(
|
.pickFiles(
|
||||||
type: FileType.any,
|
type: FileType.any,
|
||||||
// allowedExtensions: [
|
|
||||||
// 'pdf',
|
|
||||||
// 'doc',
|
|
||||||
// 'docx',
|
|
||||||
// 'xls',
|
|
||||||
// 'xlsx',
|
|
||||||
// 'ppt',
|
|
||||||
// 'pptx',
|
|
||||||
// 'txt',
|
|
||||||
// 'mp3',
|
|
||||||
// 'wav',
|
|
||||||
// 'aac',
|
|
||||||
// 'ogg',
|
|
||||||
// 'flac'
|
|
||||||
// ], // You can specify allowed extensions if needed
|
|
||||||
allowMultiple: true,
|
allowMultiple: true,
|
||||||
// Note: The maxFiles parameter is not directly supported by FilePicker.
|
|
||||||
// You will need to handle the limit after selection if necessary.
|
|
||||||
)
|
)
|
||||||
.then((result) {
|
.then((result) {
|
||||||
if (result != null && result.files.length > 3) {
|
if (result != null && result.files.length > 3) {
|
||||||
// Handle the case where the selected files exceed the max limit
|
return null;
|
||||||
// You can show an error message or return null
|
|
||||||
return null; // or show a message to the user
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
@ -189,47 +159,75 @@ class MediaService {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String?> downloadFile(String url, {final String? name}) async {
|
static Future<String?> downloadFile(String url, {final String? name}) async {
|
||||||
|
debugPrint("Attempting to download file from URL: $url");
|
||||||
final basename = name ?? p.basename(url).split('?accessToken=').first;
|
final basename = name ?? p.basename(url).split('?accessToken=').first;
|
||||||
Directory? dir;
|
|
||||||
try {
|
PermissionStatus status;
|
||||||
if (Platform.isIOS) {
|
if (Platform.isAndroid) {
|
||||||
dir = await getApplicationDocumentsDirectory(); // for iOS
|
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
} else {
|
if (androidInfo.version.sdkInt >= 33) {
|
||||||
dir = Directory('/storage/emulated/0/Download/'); // for android
|
debugPrint("Android 13+ detected. Requesting Photos permission.");
|
||||||
if (!await dir.exists()) dir = (await getExternalStorageDirectory())!;
|
status = await Permission.photos.request();
|
||||||
}
|
} else {
|
||||||
} catch (err) {
|
debugPrint("Older Android version detected. Requesting Storage permission.");
|
||||||
if (kDebugMode) {
|
status = await Permission.storage.request();
|
||||||
print("Cannot get download folder path $err");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 if (Platform.isIOS) {
|
||||||
}
|
debugPrint("iOS detected. Requesting Photos permission.");
|
||||||
|
status = await Permission.photos.request();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
status = PermissionStatus.granted;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
debugPrint("Permission status after request: $status");
|
||||||
|
|
||||||
|
if (status.isGranted) {
|
||||||
|
Directory? dir;
|
||||||
|
try {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
dir = await getApplicationDocumentsDirectory();
|
||||||
|
} else {
|
||||||
|
dir = await getExternalStorageDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == null) {
|
||||||
|
debugPrint("Error: Could not determine download directory.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final path = dir.path;
|
||||||
|
debugPrint("Download directory determined: $path");
|
||||||
|
|
||||||
|
final taskId = await FlutterDownloader.enqueue(
|
||||||
|
url: url,
|
||||||
|
savedDir: path,
|
||||||
|
fileName: basename,
|
||||||
|
showNotification: true,
|
||||||
|
openFileFromNotification: true,
|
||||||
|
saveInPublicStorage: true,
|
||||||
|
);
|
||||||
|
debugPrint("Download successfully enqueued with taskId: $taskId");
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error during download process: $e");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (status.isPermanentlyDenied) {
|
||||||
|
debugPrint("Storage permission is permanently denied. Opening app settings.");
|
||||||
|
await openAppSettings();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
debugPrint("Storage permission was denied.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static String downloadFileFromWeb(String url) {
|
static String downloadFileFromWeb(String url) {
|
||||||
|
final filename = url.split('/').last.split('?').first;
|
||||||
html.AnchorElement anchorElement = html.AnchorElement(href: url);
|
html.AnchorElement anchorElement = html.AnchorElement(href: url);
|
||||||
anchorElement.download = url;
|
anchorElement.download = filename;
|
||||||
anchorElement.click();
|
anchorElement.click();
|
||||||
return anchorElement.pathname!;
|
return anchorElement.pathname!;
|
||||||
}
|
}
|
||||||
|
|
@ -249,4 +247,4 @@ class MediaService {
|
||||||
hasDismissButton: false,
|
hasDismissButton: false,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:didvan/models/requests/studio.dart';
|
||||||
|
|
||||||
class RequestHelper {
|
class RequestHelper {
|
||||||
static const String baseUrl = 'https://api.didvan.app';
|
static const String baseUrl = 'https://api.didvan.app';
|
||||||
static const String baseUrl2 = 'http://opportunity-threat.didvan.com';
|
static const String baseUrl2 = 'https://opportunity-threat.didvan.com';
|
||||||
static const String storiesV1 = '$baseUrl2/api/v1/stories';
|
static const String storiesV1 = '$baseUrl2/api/v1/stories';
|
||||||
static const String storyActivity = '$baseUrl2/api/v1/stories/activity';
|
static const String storyActivity = '$baseUrl2/api/v1/stories/activity';
|
||||||
static const String _baseUserUrl = '$baseUrl/user';
|
static const String _baseUserUrl = '$baseUrl/user';
|
||||||
|
|
@ -20,7 +20,7 @@ class RequestHelper {
|
||||||
static const String _baseHomeUrl = '$baseUrl/home';
|
static const String _baseHomeUrl = '$baseUrl/home';
|
||||||
static const String _baseNewStats = '$baseUrl/home/statistic';
|
static const String _baseNewStats = '$baseUrl/home/statistic';
|
||||||
static const String _baseNewStatsSearch = '$baseUrl/home/statistic/search';
|
static const String _baseNewStatsSearch = '$baseUrl/home/statistic/search';
|
||||||
static const String checkHasPassword = '$_baseUserUrl/checkHasPassword';
|
static const String checkHasPassword = '$_baseUserUrl/checkHasPassword';
|
||||||
|
|
||||||
static const String mainPageContent = _baseHomeUrl;
|
static const String mainPageContent = _baseHomeUrl;
|
||||||
static String searchAll({
|
static String searchAll({
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:didvan/models/note.dart';
|
import 'package:didvan/models/note.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
// ignore: library_prefixes
|
||||||
import 'package:http/http.dart' as RequestServices;
|
import 'package:http/http.dart' as RequestServices;
|
||||||
|
|
||||||
class NoteService {
|
class NoteService {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:didvan/models/home_page_content/swot.dart';
|
import 'package:didvan/models/home_page_content/swot.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class NativeWebViewLauncher {
|
class NativeWebViewLauncher {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
const Ai({Key? key}) : super(key: key);
|
const Ai({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
// ignore: library_private_types_in_public_api
|
||||||
_AiState createState() => _AiState();
|
_AiState createState() => _AiState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
// lib/views/ai/ai_chat_page.dart
|
|
||||||
|
|
||||||
// ignore_for_file: library_private_types_in_public_api, deprecated_member_use, depend_on_referenced_packages, unnecessary_import
|
// ignore_for_file: library_private_types_in_public_api, deprecated_member_use, depend_on_referenced_packages, unnecessary_import
|
||||||
|
|
||||||
import 'dart:io' show Platform;
|
|
||||||
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
||||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||||
|
|
||||||
|
|
@ -599,27 +596,26 @@ class _AiChatPageState extends State<AiChatPage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (message.file != null && !kIsWeb)
|
if (message.file != null && !kIsWeb)
|
||||||
!Platform.isIOS
|
Padding(
|
||||||
? Padding(
|
padding: const EdgeInsets.all(8.0),
|
||||||
padding: const EdgeInsets.all(8.0),
|
child: InkWell(
|
||||||
child: InkWell(
|
onTap: () async {
|
||||||
onTap: () async {
|
debugPrint(
|
||||||
final url =
|
"Download button tapped on iOS");
|
||||||
'${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
|
final url =
|
||||||
await MediaService.downloadFile(
|
'${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
|
||||||
url,
|
await MediaService.downloadFile(url,
|
||||||
name: message.fileName);
|
name: message.fileName);
|
||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
DidvanIcons.download_solid,
|
DidvanIcons.download_solid,
|
||||||
size: 18,
|
size: 18,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.focusedBorder,
|
.focusedBorder,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: const SizedBox.shrink(),
|
|
||||||
if (message.error != null && message.error!)
|
if (message.error != null && message.error!)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
@ -645,14 +641,7 @@ class _AiChatPageState extends State<AiChatPage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (state.messages[mIndex].prompts[index]
|
if (message.text != null && message.text!.isNotEmpty && (file == null || !file.isImage()))
|
||||||
.text !=
|
|
||||||
null ||
|
|
||||||
(state.messages[mIndex].prompts[index]
|
|
||||||
.text !=
|
|
||||||
null &&
|
|
||||||
state.messages[mIndex].prompts[index]
|
|
||||||
.text!.isNotEmpty))
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// ignore_for_file: body_might_complete_normally_catch_error
|
// ignore_for_file: body_might_complete_normally_catch_error, avoid_print
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/models/view/alert_data.dart';
|
import 'package:didvan/models/view/alert_data.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/divider.dart';
|
import 'package:didvan/views/widgets/didvan/divider.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// lib/views/ai_section/ai_section_page.dart
|
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
|
@ -185,15 +184,8 @@ class _AiSectionPageState extends State<AiSectionPage> {
|
||||||
key: _aiSectionScaffoldKey,
|
key: _aiSectionScaffoldKey,
|
||||||
appBar: HoshanAppBar(
|
appBar: HoshanAppBar(
|
||||||
onBack: () {
|
onBack: () {
|
||||||
if (aiState.isChatting) {
|
|
||||||
aiState.endChat();
|
|
||||||
setState(() {
|
|
||||||
_currentTabIndex = 2;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
},
|
||||||
},
|
|
||||||
withActions: true,
|
withActions: true,
|
||||||
),
|
),
|
||||||
drawer: HoshanDrawer(scaffKey: _aiSectionScaffoldKey),
|
drawer: HoshanDrawer(scaffKey: _aiSectionScaffoldKey),
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:didvan/services/media/voice.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_sound/public/flutter_sound_player.dart';
|
import 'package:flutter_sound/public/flutter_sound_player.dart';
|
||||||
import 'package:flutter_sound/public/flutter_sound_recorder.dart';
|
import 'package:flutter_sound/public/flutter_sound_recorder.dart';
|
||||||
import 'package:flutter_sound_platform_interface/flutter_sound_platform_interface.dart';
|
import 'package:flutter_sound_platform_interface/flutter_sound_platform_interface.dart';
|
||||||
|
|
@ -24,7 +25,7 @@ class DirectState extends CoreProvier {
|
||||||
final Map<String, List<int>> dailyMessages = {};
|
final Map<String, List<int>> dailyMessages = {};
|
||||||
final List<int> deletionQueue = [];
|
final List<int> deletionQueue = [];
|
||||||
|
|
||||||
String? text;
|
final TextEditingController textController = TextEditingController();
|
||||||
NewsAttachment? replyNews;
|
NewsAttachment? replyNews;
|
||||||
RadarAttachment? replyRadar;
|
RadarAttachment? replyRadar;
|
||||||
int? audioDuration;
|
int? audioDuration;
|
||||||
|
|
@ -104,6 +105,7 @@ class DirectState extends CoreProvier {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
textController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
mPlayer!.closePlayer();
|
mPlayer!.closePlayer();
|
||||||
mPlayer = null;
|
mPlayer = null;
|
||||||
|
|
@ -172,7 +174,7 @@ class DirectState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startRecording() async {
|
Future<void> startRecording() async {
|
||||||
text = null;
|
textController.text.isEmpty;
|
||||||
// await _recorder.hasPermission();
|
// await _recorder.hasPermission();
|
||||||
record();
|
record();
|
||||||
|
|
||||||
|
|
@ -228,13 +230,14 @@ class DirectState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sendMessage() async {
|
Future<void> sendMessage() async {
|
||||||
if ((text == null || text!.isEmpty) && path == null) return;
|
|
||||||
|
if ((textController.text.isEmpty) && path == null) return;
|
||||||
VoiceService.audioPlayer.stop();
|
VoiceService.audioPlayer.stop();
|
||||||
|
|
||||||
final body = {};
|
final body = {};
|
||||||
|
|
||||||
if (text != null) {
|
if (textController.text.isNotEmpty) {
|
||||||
body.addAll({'text': text});
|
body.addAll({'text': textController.text});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replyRadar != null) {
|
if (replyRadar != null) {
|
||||||
|
|
@ -253,7 +256,7 @@ class DirectState extends CoreProvier {
|
||||||
body.addAll({'duration': countTimer.value.inSeconds.toString()});
|
body.addAll({'duration': countTimer.value.inSeconds.toString()});
|
||||||
}
|
}
|
||||||
|
|
||||||
text = null;
|
textController.clear();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
|
@ -9,54 +10,60 @@ import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MessageBox extends StatelessWidget {
|
class MessageBox extends StatefulWidget {
|
||||||
const MessageBox({Key? key}) : super(key: key);
|
const MessageBox({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MessageBox> createState() => _MessageBoxState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MessageBoxState extends State<MessageBox> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Consumer<DirectState>(
|
Consumer<DirectState>(
|
||||||
builder: (context, state, child) => state.replyRadar != null ||
|
builder: (context, state, child) =>
|
||||||
state.replyNews != null
|
state.replyRadar != null || state.replyNews != null
|
||||||
? _MessageBoxContainer(
|
? _MessageBoxContainer(
|
||||||
isMessage: false,
|
isMessage: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const DidvanText(
|
const DidvanText(
|
||||||
'لینک به مطلب:',
|
'لینک به مطلب:',
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
state.replyRadar != null
|
||||||
|
? state.replyRadar!.title
|
||||||
|
: state.replyNews!.title,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
DidvanText(
|
),
|
||||||
state.replyRadar != null
|
DidvanIconButton(
|
||||||
? state.replyRadar!.title
|
icon: DidvanIcons.close_regular,
|
||||||
: state.replyNews!.title,
|
gestureSize: 24,
|
||||||
overflow: TextOverflow.ellipsis,
|
onPressed: () {
|
||||||
maxLines: 1,
|
state.replyRadar = null;
|
||||||
color: Theme.of(context).colorScheme.primary,
|
state.replyNews = null;
|
||||||
),
|
state.update();
|
||||||
],
|
},
|
||||||
),
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
DidvanIconButton(
|
),
|
||||||
icon: DidvanIcons.close_regular,
|
)
|
||||||
gestureSize: 24,
|
: const SizedBox(),
|
||||||
onPressed: () {
|
|
||||||
state.replyRadar = null;
|
|
||||||
state.replyNews = null;
|
|
||||||
state.update();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const SizedBox(),
|
|
||||||
),
|
),
|
||||||
_MessageBoxContainer(
|
_MessageBoxContainer(
|
||||||
isMessage: true,
|
isMessage: true,
|
||||||
|
|
@ -111,7 +118,21 @@ class _Typing extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TypingState extends State<_Typing> {
|
class _TypingState extends State<_Typing> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
context.read<DirectState>().textController.addListener(_rebuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
context.read<DirectState>().textController.removeListener(_rebuild);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rebuild() {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -126,13 +147,11 @@ class _TypingState extends State<_Typing> {
|
||||||
scale: animation,
|
scale: animation,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
child: state.text != null && state.text!.isNotEmpty
|
child: state.textController.text.isNotEmpty
|
||||||
? DidvanIconButton(
|
? DidvanIconButton(
|
||||||
icon: DidvanIcons.send_solid,
|
icon: DidvanIcons.send_solid,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await state.sendMessage();
|
await state.sendMessage();
|
||||||
state.update();
|
|
||||||
_formKey.currentState!.reset();
|
|
||||||
},
|
},
|
||||||
size: 32,
|
size: 32,
|
||||||
color: Theme.of(context).colorScheme.focusedBorder,
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
|
@ -147,23 +166,17 @@ class _TypingState extends State<_Typing> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 15,
|
flex: 15,
|
||||||
child: Form(
|
child: TextFormField(
|
||||||
key: _formKey,
|
controller: state.textController,
|
||||||
child: TextFormField(
|
textInputAction: TextInputAction.send,
|
||||||
textInputAction: TextInputAction.send,
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
decoration: InputDecoration(
|
||||||
decoration: InputDecoration(
|
border: InputBorder.none,
|
||||||
border: InputBorder.none,
|
hintText: 'بنویسید یا پیام صوتی بگذارید...',
|
||||||
hintText: 'بنویسید یا پیام صوتی بگذارید...',
|
hintStyle: Theme.of(context)
|
||||||
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
|
.textTheme
|
||||||
color: Theme.of(context).colorScheme.disabledText),
|
.bodySmall!
|
||||||
),
|
.copyWith(color: Theme.of(context).colorScheme.disabledText),
|
||||||
onChanged: (value) {
|
|
||||||
if (value.length <= 1) {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
state.text = value;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -227,7 +240,6 @@ class _RecordChecking extends StatelessWidget {
|
||||||
child: AudioWave(
|
child: AudioWave(
|
||||||
file: state.path!,
|
file: state.path!,
|
||||||
totalDuration: state.countTimer.value,
|
totalDuration: state.countTimer.value,
|
||||||
// deleteClidk: () => state.deleteRecordedFile,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -245,4 +257,4 @@ class _RecordChecking extends StatelessWidget {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:didvan/models/home_page_content/swot.dart';
|
import 'package:didvan/models/home_page_content/swot.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:http/http.dart' as RequestServicess;
|
|
||||||
|
|
||||||
class BookmarkService {
|
class BookmarkService {
|
||||||
static Future<List<int>> fetchBookmarks() async {
|
static Future<List<int>> fetchBookmarks() async {
|
||||||
|
|
@ -69,7 +70,7 @@ class BookmarkService {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<SwotItem>> fetchBookmarkedSwotItems() async {
|
static Future<List<SwotItem>> fetchBookmarkedSwotItems() async {
|
||||||
final postIds = await fetchBookmarks(); // استفاده از همان لیست بوکمارکها
|
final postIds = await fetchBookmarks();
|
||||||
final List<SwotItem> items = [];
|
final List<SwotItem> items = [];
|
||||||
|
|
||||||
for (final postId in postIds) {
|
for (final postId in postIds) {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ class _BookmarksState extends State<Bookmarks> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ignore: unused_element
|
||||||
void _onSearchChanged(String value) {
|
void _onSearchChanged(String value) {
|
||||||
final state = context.read<BookmarksState>();
|
final state = context.read<BookmarksState>();
|
||||||
if (value.length < 3 && value.isNotEmpty) {
|
if (value.length < 3 && value.isNotEmpty) {
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ class _HomeState extends State<Home>
|
||||||
)
|
)
|
||||||
.then((value) => ActionSheetUtils(context).openDialog(
|
.then((value) => ActionSheetUtils(context).openDialog(
|
||||||
data: ActionSheetData(
|
data: ActionSheetData(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
isBackgroundDropBlur: true,
|
isBackgroundDropBlur: true,
|
||||||
content: Stack(
|
content: Stack(
|
||||||
|
|
@ -208,6 +209,7 @@ class _HomeState extends State<Home>
|
||||||
scaffKey: homeScaffKey,
|
scaffKey: homeScaffKey,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
// ignore: deprecated_member_use
|
||||||
body: WillPopScope(
|
body: WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
if (context.read<HomeState>().tabController.index == 0) {
|
if (context.read<HomeState>().tabController.index == 0) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/main.dart';
|
import 'package:didvan/main.dart';
|
||||||
import 'package:didvan/models/home_page_content/home_page_list.dart';
|
import 'package:didvan/models/home_page_content/home_page_list.dart';
|
||||||
import 'package:didvan/models/home_page_content/swot.dart';
|
import 'package:didvan/models/home_page_content/swot.dart';
|
||||||
import 'package:didvan/services/swot_service.dart';
|
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/services/app_initalizer.dart';
|
import 'package:didvan/services/app_initalizer.dart';
|
||||||
import 'package:didvan/views/home/main/main_page_state.dart';
|
import 'package:didvan/views/home/main/main_page_state.dart';
|
||||||
|
|
@ -48,10 +47,8 @@ class _MainPageState extends State<MainPage> {
|
||||||
children: [
|
children: [
|
||||||
if (state.stories.isNotEmpty) StorySection(stories: state.stories),
|
if (state.stories.isNotEmpty) StorySection(stories: state.stories),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
// Main page content
|
|
||||||
const MainPageMainContent(),
|
const MainPageMainContent(),
|
||||||
|
|
||||||
// START: MODIFIED SECTION
|
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
final List<Widget> pageContent = [];
|
final List<Widget> pageContent = [];
|
||||||
if (state.content != null && state.content!.lists.isNotEmpty) {
|
if (state.content != null && state.content!.lists.isNotEmpty) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:didvan/main.dart';
|
import 'package:didvan/main.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/home_page_content/content.dart';
|
||||||
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
||||||
import 'package:didvan/models/home_page_content/swot.dart';
|
import 'package:didvan/models/home_page_content/swot.dart';
|
||||||
import 'package:didvan/models/requests/infography.dart';
|
import 'package:didvan/models/requests/infography.dart';
|
||||||
|
|
@ -33,7 +34,12 @@ class MainPageState extends CoreProvier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _getSwotItems() async { // این متد را اضافه کنید
|
int getStoryStartIndex(List<MainPageContentType> stories) {
|
||||||
|
final firstUnreadIndex = stories.indexWhere((story) => !story.isViewed);
|
||||||
|
return firstUnreadIndex != -1 ? firstUnreadIndex : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getSwotItems() async {
|
||||||
try {
|
try {
|
||||||
swotItems = await SwotService.fetchSwotItems();
|
swotItems = await SwotService.fetchSwotItems();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -44,6 +50,7 @@ class MainPageState extends CoreProvier {
|
||||||
Future<void> _fetchStories() async {
|
Future<void> _fetchStories() async {
|
||||||
try {
|
try {
|
||||||
stories = await StoryService.getStories();
|
stories = await StoryService.getStories();
|
||||||
|
// ignore: avoid_print
|
||||||
print("Fetched ${stories.length} stories.");
|
print("Fetched ${stories.length} stories.");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
stories = [];
|
stories = [];
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/views/home/bookmarks/bookmark_service.dart';
|
import 'package:didvan/views/home/bookmarks/bookmark_service.dart';
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ class _BookmarkedIconState extends State<BookmarkedIcon> {
|
||||||
widget.onBookmarkChanged?.call(newBookmarkStatus);
|
widget.onBookmarkChanged?.call(newBookmarkStatus);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// ignore: avoid_print
|
||||||
print("Error toggling bookmark for post ${widget.postId}: $e");
|
print("Error toggling bookmark for post ${widget.postId}: $e");
|
||||||
} finally {
|
} finally {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,14 @@ class StorySection extends StatelessWidget {
|
||||||
child: _StoryCircle(
|
child: _StoryCircle(
|
||||||
userStories: userStories,
|
userStories: userStories,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
bool allStoriesViewed = stories.every((userStories) =>
|
||||||
|
userStories.stories.every((story) => story.isViewed.value));
|
||||||
|
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
Routes.storyViewer,
|
Routes.storyViewer,
|
||||||
arguments: {
|
arguments: {
|
||||||
'stories': stories,
|
'stories': stories,
|
||||||
'tappedIndex': index,
|
'tappedIndex': allStoriesViewed ? 0 : index,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class _SwotBookmark extends State<SwotBookmark> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveOrUpdateNote(String content) async {
|
void saveOrUpdateNote(String content) async {
|
||||||
|
// ignore: avoid_print
|
||||||
print('Processing note for PostId: ${widget.item.id}, Content: $content');
|
print('Processing note for PostId: ${widget.item.id}, Content: $content');
|
||||||
setState(() {
|
setState(() {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ class MainCategories extends StatelessWidget {
|
||||||
'$link?accessToken=${RequestService.token}',
|
'$link?accessToken=${RequestService.token}',
|
||||||
mode: LaunchMode.inAppWebView,
|
mode: LaunchMode.inAppWebView,
|
||||||
);
|
);
|
||||||
|
// ignore: avoid_print
|
||||||
print("your goddamn token is :${RequestService.token}");
|
print("your goddamn token is :${RequestService.token}");
|
||||||
} else if (link.startsWith('tab-')) {
|
} else if (link.startsWith('tab-')) {
|
||||||
final state = context.read<HomeState>();
|
final state = context.read<HomeState>();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: unnecessary_this
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
|
|
@ -22,9 +24,7 @@ class StudioDetailsState extends CoreProvier {
|
||||||
int _trackingTimerCounter = 0;
|
int _trackingTimerCounter = 0;
|
||||||
Timer? _trackingTimer;
|
Timer? _trackingTimer;
|
||||||
|
|
||||||
// BEGIN: ADD THIS LINE
|
|
||||||
StreamSubscription? _positionSubscription;
|
StreamSubscription? _positionSubscription;
|
||||||
// END: ADD THIS LINE
|
|
||||||
|
|
||||||
int _selectedDetailsIndex = 0;
|
int _selectedDetailsIndex = 0;
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,18 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final firstUnreadIndex =
|
||||||
|
state.sliders.indexWhere((story) => !story.isViewed);
|
||||||
|
|
||||||
|
final startId = (firstUnreadIndex == -1)
|
||||||
|
? state.sliders.first.id
|
||||||
|
: state.sliders[firstUnreadIndex].id;
|
||||||
|
|
||||||
if (state.videosSelected) {
|
if (state.videosSelected) {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.pushNamed(Routes.studioDetails, arguments: {
|
.pushNamed(Routes.studioDetails, arguments: {
|
||||||
'onMarkChanged': state.changeMark,
|
'onMarkChanged': state.changeMark,
|
||||||
'id': state.sliders[i].id,
|
'id': startId,
|
||||||
'args':
|
'args':
|
||||||
const StudioRequestArgs(page: 0, type: 'video'),
|
const StudioRequestArgs(page: 0, type: 'video'),
|
||||||
'hasUnmarkConfirmation': false,
|
'hasUnmarkConfirmation': false,
|
||||||
|
|
@ -54,7 +61,7 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
context.read<StudioDetailsState>().getStudioDetails(
|
context.read<StudioDetailsState>().getStudioDetails(
|
||||||
state.sliders[i].id,
|
startId,
|
||||||
args: const StudioRequestArgs(
|
args: const StudioRequestArgs(
|
||||||
page: 0,
|
page: 0,
|
||||||
type: 'podcast',
|
type: 'podcast',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:didvan/models/story_model.dart';
|
import 'package:didvan/models/story_model.dart';
|
||||||
import 'package:didvan/services/story_service.dart';
|
import 'package:didvan/services/story_service.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
||||||
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
@ -92,7 +92,24 @@ class _UserStoryViewerState extends State<UserStoryViewer>
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_animationController = AnimationController(vsync: this);
|
_animationController = AnimationController(vsync: this);
|
||||||
_loadStory(story: widget.userStories.stories.first);
|
|
||||||
|
final allStoriesInGroupViewed =
|
||||||
|
widget.userStories.stories.every((story) => story.isViewed.value);
|
||||||
|
|
||||||
|
if (allStoriesInGroupViewed) {
|
||||||
|
for (final story in widget.userStories.stories) {
|
||||||
|
story.isViewed.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentStoryIndex =
|
||||||
|
widget.userStories.stories.indexWhere((story) => !story.isViewed.value);
|
||||||
|
|
||||||
|
if (_currentStoryIndex == -1) {
|
||||||
|
_currentStoryIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadStory(story: widget.userStories.stories[_currentStoryIndex]);
|
||||||
|
|
||||||
_animationController.addStatusListener((status) {
|
_animationController.addStatusListener((status) {
|
||||||
if (status == AnimationStatus.completed) {
|
if (status == AnimationStatus.completed) {
|
||||||
|
|
@ -314,6 +331,7 @@ class _AnimatedBar extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: position < currentIndex
|
color: position < currentIndex
|
||||||
? Colors.white
|
? Colors.white
|
||||||
|
// ignore: deprecated_member_use
|
||||||
: Colors.white.withOpacity(0.5),
|
: Colors.white.withOpacity(0.5),
|
||||||
border: Border.all(color: Colors.black26, width: 0.8),
|
border: Border.all(color: Colors.black26, width: 0.8),
|
||||||
borderRadius: BorderRadius.circular(30.0),
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: unused_element
|
||||||
|
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -7,8 +9,6 @@ import 'package:provider/provider.dart';
|
||||||
import '../../../config/design_config.dart';
|
import '../../../config/design_config.dart';
|
||||||
import '../../../constants/app_icons.dart';
|
import '../../../constants/app_icons.dart';
|
||||||
import '../../../models/enums.dart';
|
import '../../../models/enums.dart';
|
||||||
import '../../../models/requests/radar.dart';
|
|
||||||
import '../../../routes/routes.dart';
|
|
||||||
import '../../../services/media/media.dart';
|
import '../../../services/media/media.dart';
|
||||||
import '../../../utils/action_sheet.dart';
|
import '../../../utils/action_sheet.dart';
|
||||||
import '../../podcasts/podcasts_state.dart';
|
import '../../podcasts/podcasts_state.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,8 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
|
||||||
import 'package:didvan/views/ai/ai_state.dart';
|
|
||||||
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
final Function()? onBack;
|
final Function()? onBack;
|
||||||
|
|
@ -55,14 +50,14 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
if (withInfo)
|
// if (withInfo)
|
||||||
DidvanIconButton(
|
// DidvanIconButton(
|
||||||
icon: DidvanIcons.info_circle_light,
|
// icon: DidvanIcons.info_circle_light,
|
||||||
size: 32,
|
// size: 32,
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
Navigator.pushNamed(context, Routes.info);
|
// Navigator.pushNamed(context, Routes.info);
|
||||||
}),
|
// }),
|
||||||
if (withActions)
|
// if (withActions)
|
||||||
// Stack(
|
// Stack(
|
||||||
// children: [
|
// children: [
|
||||||
// DidvanIconButton(
|
// DidvanIconButton(
|
||||||
|
|
@ -81,15 +76,13 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
// )
|
// )
|
||||||
// ],
|
// ],
|
||||||
// ),
|
// ),
|
||||||
if (context.watch<AiState>().page != 0 || !withActions)
|
if (withInfo)
|
||||||
Transform.rotate(
|
DidvanIconButton(
|
||||||
angle: 180 * pi / 180,
|
icon: DidvanIcons.angle_left_light,
|
||||||
child: DidvanIconButton(
|
size: 32,
|
||||||
icon: DidvanIcons.back_light,
|
onPressed: () => onBack?.call(),
|
||||||
size: 32,
|
|
||||||
onPressed: () => onBack?.call(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -98,4 +91,4 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Size get preferredSize => const Size(double.infinity, 144);
|
Size get preferredSize => const Size(double.infinity, 144);
|
||||||
}
|
}
|
||||||
26
pubspec.lock
26
pubspec.lock
|
|
@ -201,6 +201,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.11"
|
version: "0.7.11"
|
||||||
|
device_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: device_info_plus
|
||||||
|
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.5.0"
|
||||||
|
device_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_platform_interface
|
||||||
|
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.3"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1650,6 +1666,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.12.0"
|
version: "5.12.0"
|
||||||
|
win32_registry:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32_registry
|
||||||
|
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1668,4 +1692,4 @@ packages:
|
||||||
version: "6.5.0"
|
version: "6.5.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.7.0 <4.0.0"
|
dart: ">=3.7.0 <4.0.0"
|
||||||
flutter: ">=3.27.0"
|
flutter: ">=3.29.0"
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 3.3.8+3380
|
version: 4.0.1+4380
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <3.0.0"
|
sdk: ">=2.19.0 <3.0.0"
|
||||||
|
|
@ -112,6 +112,8 @@ dependencies:
|
||||||
flutter_inappwebview: ^6.1.5
|
flutter_inappwebview: ^6.1.5
|
||||||
sms_autofill: ^2.4.1
|
sms_autofill: ^2.4.1
|
||||||
shimmer: ^3.0.0
|
shimmer: ^3.0.0
|
||||||
|
device_info_plus: ^11.5.0
|
||||||
|
# image_gallery_saver: ^2.0.3
|
||||||
# fading_edge_scrollview: ^4.1.1
|
# fading_edge_scrollview: ^4.1.1
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue