last version 3.3.0 houshvan
This commit is contained in:
parent
9ea80f21fb
commit
1708bcffc8
Binary file not shown.
|
After Width: | Height: | Size: 333 KiB |
|
|
@ -42,6 +42,7 @@ class Assets {
|
||||||
static String get studioLogo => '$_baseLogosPath/studio-$_themeSuffix.svg';
|
static String get studioLogo => '$_baseLogosPath/studio-$_themeSuffix.svg';
|
||||||
|
|
||||||
static String loadingAnimation = '$_baseAnimationsPath/loading.gif';
|
static String loadingAnimation = '$_baseAnimationsPath/loading.gif';
|
||||||
|
static String bookmarkAnimation = '$_baseAnimationsPath/bookmark.gif';
|
||||||
|
|
||||||
static String get businessCategoryIcon =>
|
static String get businessCategoryIcon =>
|
||||||
'$_baseCategoriesPath/business-$_themeSuffix.svg';
|
'$_baseCategoriesPath/business-$_themeSuffix.svg';
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await runZonedGuarded(() async {
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -80,9 +79,6 @@ void main() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
runApp(const Didvan());
|
runApp(const Didvan());
|
||||||
}, (error, stack) async {
|
|
||||||
error.printError();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Didvan extends StatefulWidget {
|
class Didvan extends StatefulWidget {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ class Content {
|
||||||
final String createdAt;
|
final String createdAt;
|
||||||
bool marked;
|
bool marked;
|
||||||
bool liked;
|
bool liked;
|
||||||
|
int likes;
|
||||||
|
|
||||||
final List<Tag> tags;
|
final List<Tag> tags;
|
||||||
|
|
||||||
|
|
@ -30,6 +31,7 @@ class Content {
|
||||||
{required this.id,
|
{required this.id,
|
||||||
required this.marked,
|
required this.marked,
|
||||||
required this.liked,
|
required this.liked,
|
||||||
|
required this.likes,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.image,
|
required this.image,
|
||||||
|
|
@ -41,6 +43,7 @@ class Content {
|
||||||
id: json['id'],
|
id: json['id'],
|
||||||
marked: json['marked'],
|
marked: json['marked'],
|
||||||
liked: json['liked'],
|
liked: json['liked'],
|
||||||
|
likes: json['likes'],
|
||||||
createdAt: json['createdAt'],
|
createdAt: json['createdAt'],
|
||||||
title: json['title'],
|
title: json['title'],
|
||||||
image: json['image'],
|
image: json['image'],
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class NewsDetailsData {
|
||||||
final String createdAt;
|
final String createdAt;
|
||||||
bool marked;
|
bool marked;
|
||||||
bool liked;
|
bool liked;
|
||||||
|
int likes;
|
||||||
int comments;
|
int comments;
|
||||||
final int order;
|
final int order;
|
||||||
final List<Tag> tags;
|
final List<Tag> tags;
|
||||||
|
|
@ -25,6 +26,7 @@ class NewsDetailsData {
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.marked,
|
required this.marked,
|
||||||
required this.liked,
|
required this.liked,
|
||||||
|
required this.likes,
|
||||||
required this.comments,
|
required this.comments,
|
||||||
required this.tags,
|
required this.tags,
|
||||||
required this.contents,
|
required this.contents,
|
||||||
|
|
@ -41,6 +43,7 @@ class NewsDetailsData {
|
||||||
createdAt: json['createdAt'],
|
createdAt: json['createdAt'],
|
||||||
marked: json['marked'],
|
marked: json['marked'],
|
||||||
liked: json['liked'] ?? false,
|
liked: json['liked'] ?? false,
|
||||||
|
likes: json['likes'],
|
||||||
comments: json['comments'],
|
comments: json['comments'],
|
||||||
order: json['order'],
|
order: json['order'],
|
||||||
tags: List<Tag>.from(json['tags'].map((tag) => Tag.fromJson(tag))),
|
tags: List<Tag>.from(json['tags'].map((tag) => Tag.fromJson(tag))),
|
||||||
|
|
@ -59,6 +62,7 @@ class NewsDetailsData {
|
||||||
'createdAt': createdAt,
|
'createdAt': createdAt,
|
||||||
'marked': marked,
|
'marked': marked,
|
||||||
'liked': liked,
|
'liked': liked,
|
||||||
|
'likes': likes,
|
||||||
'comments': comments,
|
'comments': comments,
|
||||||
'tags': tags.map((e) => e.toJson()).toList(),
|
'tags': tags.map((e) => e.toJson()).toList(),
|
||||||
'contents': contents.map((e) => e.toJson()).toList(),
|
'contents': contents.map((e) => e.toJson()).toList(),
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class OverviewData {
|
||||||
int comments;
|
int comments;
|
||||||
bool marked;
|
bool marked;
|
||||||
bool liked;
|
bool liked;
|
||||||
|
int likes;
|
||||||
final List<CategoryData>? categories;
|
final List<CategoryData>? categories;
|
||||||
|
|
||||||
OverviewData({
|
OverviewData({
|
||||||
|
|
@ -31,6 +32,7 @@ class OverviewData {
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.marked,
|
required this.marked,
|
||||||
required this.liked,
|
required this.liked,
|
||||||
|
required this.likes,
|
||||||
required this.comments,
|
required this.comments,
|
||||||
required this.forManagers,
|
required this.forManagers,
|
||||||
this.category,
|
this.category,
|
||||||
|
|
@ -87,6 +89,7 @@ class OverviewData {
|
||||||
type: json['type'] ?? '',
|
type: json['type'] ?? '',
|
||||||
marked: json['marked'] ?? true,
|
marked: json['marked'] ?? true,
|
||||||
liked: json['liked'] ?? true,
|
liked: json['liked'] ?? true,
|
||||||
|
likes: json['likes'] ?? 0,
|
||||||
link: json['link'],
|
link: json['link'],
|
||||||
iframe: json['iframe'],
|
iframe: json['iframe'],
|
||||||
categories: json['categories'] != null
|
categories: json['categories'] != null
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ class ActionSheetData {
|
||||||
final Widget content;
|
final Widget content;
|
||||||
final String? confrimTitle;
|
final String? confrimTitle;
|
||||||
final String? dismissTitle;
|
final String? dismissTitle;
|
||||||
final VoidCallback? onConfirmed;
|
final Function()? onConfirmed;
|
||||||
final VoidCallback? onDismissed;
|
final Function()? onDismissed;
|
||||||
final String? title;
|
final String? title;
|
||||||
final bool hasPadding;
|
final bool hasPadding;
|
||||||
final IconData? titleIcon;
|
final IconData? titleIcon;
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,9 @@ class RouteGenerator {
|
||||||
ChangeNotifierProvider<NewStatisticState>(
|
ChangeNotifierProvider<NewStatisticState>(
|
||||||
create: (context) => NewStatisticState())
|
create: (context) => NewStatisticState())
|
||||||
],
|
],
|
||||||
child: const Home(),
|
child: Home(
|
||||||
|
showDialogs: settings.arguments as bool?,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case Routes.editProfile:
|
case Routes.editProfile:
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class FirebaseApi {
|
||||||
e.printError();
|
e.printError();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _firebaseMessaging.requestPermission(
|
_firebaseMessaging.requestPermission(
|
||||||
alert: true,
|
alert: true,
|
||||||
announcement: true,
|
announcement: true,
|
||||||
badge: true,
|
badge: true,
|
||||||
|
|
|
||||||
|
|
@ -169,8 +169,8 @@ class ActionSheetUtils {
|
||||||
child: DidvanButton(
|
child: DidvanButton(
|
||||||
style: ButtonStyleMode.primary,
|
style: ButtonStyleMode.primary,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
|
||||||
data.onConfirmed?.call();
|
data.onConfirmed?.call();
|
||||||
|
pop();
|
||||||
},
|
},
|
||||||
title: data.confrimTitle ?? 'تایید',
|
title: data.confrimTitle ?? 'تایید',
|
||||||
),
|
),
|
||||||
|
|
@ -251,7 +251,10 @@ class ActionSheetUtils {
|
||||||
if (data.hasDismissButton)
|
if (data.hasDismissButton)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DidvanButton(
|
child: DidvanButton(
|
||||||
onPressed: data.onDismissed ?? () => pop(),
|
onPressed: () {
|
||||||
|
data.onDismissed?.call();
|
||||||
|
pop();
|
||||||
|
},
|
||||||
title: data.dismissTitle ?? 'بازگشت',
|
title: data.dismissTitle ?? 'بازگشت',
|
||||||
style: ButtonStyleMode.flat,
|
style: ButtonStyleMode.flat,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class _AiState extends State<Ai> {
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 12,
|
height: 24,
|
||||||
),
|
),
|
||||||
Icon(
|
Icon(
|
||||||
DidvanIcons.ai_solid,
|
DidvanIcons.ai_solid,
|
||||||
|
|
@ -134,16 +134,6 @@ class _AiState extends State<Ai> {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 8,
|
width: 8,
|
||||||
),
|
),
|
||||||
Container(
|
|
||||||
width: 32,
|
|
||||||
height: 32,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Theme.of(context).colorScheme.border),
|
|
||||||
child: const Icon(
|
|
||||||
DidvanIcons.mic_regular,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
|
|
|
||||||
|
|
@ -409,9 +409,13 @@ class _AiChatPageState extends State<AiChatPage> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
SpinKitThreeBounce(
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: SpinKitThreeBounce(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
size: 18,
|
size: 18,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,6 @@ class AiChatState extends CoreProvier {
|
||||||
FilesModel? file;
|
FilesModel? file;
|
||||||
TextEditingController message = TextEditingController();
|
TextEditingController message = TextEditingController();
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _scrolledEnd() async {
|
Future<void> _scrolledEnd() async {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
await scrollController.animateTo(
|
await scrollController.animateTo(
|
||||||
|
|
@ -166,12 +161,8 @@ class AiChatState extends CoreProvier {
|
||||||
file = null;
|
file = null;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
final stream = res
|
final r = res.listen((value) async {
|
||||||
.transform(utf8.decoder)
|
var str = utf8.decode(value);
|
||||||
.transform(const LineSplitter()); // <--- Add this line
|
|
||||||
|
|
||||||
final r = stream.listen((str) {
|
|
||||||
// var str = utf8.decode(value);
|
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
if (str.contains('{{{')) {
|
if (str.contains('{{{')) {
|
||||||
dataMessgae += str;
|
dataMessgae += str;
|
||||||
|
|
@ -197,6 +188,7 @@ class AiChatState extends CoreProvier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
messageOnstream.value = Stream.value(responseMessgae);
|
messageOnstream.value = Stream.value(responseMessgae);
|
||||||
|
|
||||||
print("responseMessgae: $str");
|
print("responseMessgae: $str");
|
||||||
// update();
|
// update();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import 'package:get/get.dart';
|
||||||
import 'package:image_cropper/image_cropper.dart';
|
import 'package:image_cropper/image_cropper.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:record/record.dart';
|
import 'package:record/record.dart';
|
||||||
|
|
@ -161,23 +160,25 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
FilePickerResult? result =
|
FilePickerResult? result =
|
||||||
await MediaService.pickPdfFile();
|
await MediaService.pickPdfFile();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
// if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
// Uint8List bytes = result.files.first
|
Uint8List? bytes = result.files.first
|
||||||
// .bytes!; // Access the bytes property
|
.bytes; // Access the bytes property
|
||||||
|
String? name = result.files.first.name;
|
||||||
|
|
||||||
// File file = File.fromRawPath(bytes);
|
// Store bytes and file name directly in your state or model
|
||||||
// state.file = FilesModel(file.path,
|
state.file = FilesModel(
|
||||||
// name: result.files.first.name,
|
'', // No need for a file path on web
|
||||||
// bytes: bytes,
|
name: name,
|
||||||
// audio: false,
|
bytes: bytes,
|
||||||
// image: false);
|
audio: false,
|
||||||
// print(result.files.first.name);
|
image: false,
|
||||||
// } else {
|
);
|
||||||
|
} else {
|
||||||
state.file = FilesModel(
|
state.file = FilesModel(
|
||||||
result.files.single.path!,
|
result.files.single.path!,
|
||||||
audio: false,
|
audio: false,
|
||||||
image: false);
|
image: false);
|
||||||
// }
|
}
|
||||||
|
|
||||||
openAttach = false;
|
openAttach = false;
|
||||||
}
|
}
|
||||||
|
|
@ -243,6 +244,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (!kIsWeb || !Platform.isIOS)
|
||||||
if (historyState.bot!.attachmentType!
|
if (historyState.bot!.attachmentType!
|
||||||
.contains('audio'))
|
.contains('audio'))
|
||||||
attachBtn(
|
attachBtn(
|
||||||
|
|
@ -319,7 +321,8 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
bottom: 8.0),
|
bottom: 8.0),
|
||||||
child: (snapshot.hasData &&
|
child: (!kIsWeb &&
|
||||||
|
snapshot.hasData &&
|
||||||
snapshot.data! !=
|
snapshot.data! !=
|
||||||
RecordState.stop)
|
RecordState.stop)
|
||||||
? MessageBarBtn(
|
? MessageBarBtn(
|
||||||
|
|
@ -342,7 +345,9 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
state.update();
|
state.update();
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: widget.bot.attachmentType!
|
: (!kIsWeb || !Platform.isIOS) &&
|
||||||
|
widget.bot
|
||||||
|
.attachmentType!
|
||||||
.contains(
|
.contains(
|
||||||
'audio') &&
|
'audio') &&
|
||||||
value.isEmpty &&
|
value.isEmpty &&
|
||||||
|
|
@ -523,11 +528,23 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment
|
MainAxisAlignment
|
||||||
.center,
|
.center,
|
||||||
children: List
|
children: List.generate(
|
||||||
.generate(
|
4,
|
||||||
3,
|
(index) => snapshot.data! == RecordState.pause
|
||||||
(index) =>
|
? Row(
|
||||||
SpinKitWave(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(
|
||||||
|
8,
|
||||||
|
(index) => Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 1.0, vertical: 12),
|
||||||
|
child: Container(
|
||||||
|
width: 3,
|
||||||
|
height: 8,
|
||||||
|
decoration: BoxDecoration(color: Theme.of(context).colorScheme.primary.withOpacity(0.4)),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
: SpinKitWave(
|
||||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.4),
|
color: Theme.of(context).colorScheme.primary.withOpacity(0.4),
|
||||||
size: 32,
|
size: 32,
|
||||||
itemCount: 10,
|
itemCount: 10,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:just_audio/just_audio.dart';
|
import 'package:just_audio/just_audio.dart';
|
||||||
|
|
@ -35,6 +36,7 @@ class _AudioWaveState extends State<AudioWave> {
|
||||||
double currentPosition = 0;
|
double currentPosition = 0;
|
||||||
bool loading = true;
|
bool loading = true;
|
||||||
bool faile = false;
|
bool faile = false;
|
||||||
|
bool onChanging = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -56,7 +58,7 @@ class _AudioWaveState extends State<AudioWave> {
|
||||||
void setRandoms() {
|
void setRandoms() {
|
||||||
for (var i = 0; i < itemCount; i++) {
|
for (var i = 0; i < itemCount; i++) {
|
||||||
randoms.value.add(0);
|
randoms.value.add(0);
|
||||||
randomsDisable.value.add(2 + Random().nextDouble() * (42 - 2));
|
randomsDisable.value.add(1 + Random().nextDouble() * (38 - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,7 +96,7 @@ class _AudioWaveState extends State<AudioWave> {
|
||||||
|
|
||||||
Future<void> listeners() async {
|
Future<void> listeners() async {
|
||||||
audioPlayer.positionStream.listen((position) async {
|
audioPlayer.positionStream.listen((position) async {
|
||||||
if (randomsDisable.value.isEmpty) return;
|
if (randomsDisable.value.isEmpty || onChanging) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (var i = 0; i < itemCount; i++) {
|
for (var i = 0; i < itemCount; i++) {
|
||||||
|
|
@ -219,12 +221,9 @@ class _AudioWaveState extends State<AudioWave> {
|
||||||
.primary
|
.primary
|
||||||
.withOpacity(0.4)),
|
.withOpacity(0.4)),
|
||||||
if (totalDuration != Duration.zero)
|
if (totalDuration != Duration.zero)
|
||||||
Opacity(
|
Positioned.fill(
|
||||||
|
child: Opacity(
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
child: Container(
|
|
||||||
width: 12,
|
|
||||||
color: Colors.transparent
|
|
||||||
.withOpacity(1),
|
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: Theme.of(context)
|
data: Theme.of(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
|
|
@ -252,22 +251,22 @@ class _AudioWaveState extends State<AudioWave> {
|
||||||
// audioPlayer.pause();
|
// audioPlayer.pause();
|
||||||
},
|
},
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
for (var i = 0;
|
// for (var i = 0;
|
||||||
i < itemCount;
|
// i < itemCount;
|
||||||
i++) {
|
// i++) {
|
||||||
if (i <
|
// if (i <
|
||||||
((value * 40) /
|
// ((value * 40) /
|
||||||
totalDuration
|
// totalDuration
|
||||||
.inMilliseconds)) {
|
// .inMilliseconds)) {
|
||||||
final ran =
|
// final ran =
|
||||||
randomsDisable
|
// randomsDisable
|
||||||
.value[i];
|
// .value[i];
|
||||||
randoms.value[i] =
|
// randoms.value[i] =
|
||||||
ran;
|
// ran;
|
||||||
} else {
|
// } else {
|
||||||
randoms.value[i] = 0;
|
// randoms.value[i] = 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
setState(() {
|
setState(() {
|
||||||
currentPosition = value;
|
currentPosition = value;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -80,78 +80,11 @@ class _PasswordInputState extends State<PasswordInput> {
|
||||||
await ServerDataProvider.getData();
|
await ServerDataProvider.getData();
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Future.delayed(Duration.zero,
|
await Future.delayed(
|
||||||
() => Navigator.of(context).pushReplacementNamed(Routes.home));
|
Duration.zero,
|
||||||
}
|
() => Navigator.of(context)
|
||||||
|
.pushReplacementNamed(Routes.home, arguments: true));
|
||||||
_showResetPasswordDialog();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showResetPasswordDialog() {
|
|
||||||
ActionSheetUtils(context).openDialog(
|
|
||||||
data: ActionSheetData(
|
|
||||||
content: const DidvanText(
|
|
||||||
'خوش آمدید!\nبرای امنیت بیشتر، رمز عبور خود را تغییر دهید.',
|
|
||||||
),
|
|
||||||
onConfirmed: () => Navigator.of(navigatorKey.currentContext!).pushNamed(
|
|
||||||
Routes.authenticaion,
|
|
||||||
arguments: true,
|
|
||||||
),
|
|
||||||
isBackgroundDropBlur: false,
|
|
||||||
confrimTitle: 'تغییر رمز عبور',
|
|
||||||
onDismissed: Navigator.of(navigatorKey.currentContext!).pop,
|
|
||||||
dismissTitle: 'بعدا',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_showCustomizeDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showCustomizeDialog() {
|
|
||||||
ActionSheetUtils(context).openDialog(
|
|
||||||
data: ActionSheetData(
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
|
||||||
isBackgroundDropBlur: true,
|
|
||||||
content: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
InkWrapper(
|
|
||||||
onPressed: Navigator.of(navigatorKey.currentContext!).pop,
|
|
||||||
child: const Icon(
|
|
||||||
DidvanIcons.close_solid,
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DidvanText(
|
|
||||||
'شخصی سازی محتوا',
|
|
||||||
style: Theme.of(context).textTheme.displaySmall,
|
|
||||||
color: Theme.of(context).colorScheme.text,
|
|
||||||
),
|
|
||||||
const InkWrapper(
|
|
||||||
child: Icon(
|
|
||||||
DidvanIcons.close_regular,
|
|
||||||
size: 24,
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
const DidvanText(
|
|
||||||
"کاربر گرامی\nلطفا جهت شخصیسازی و استفاده بهتر از برنامه، دستهبندیهای مورد علاقه خود و زمان دریافت اعلانات را انتخاب نمایید.")
|
|
||||||
],
|
|
||||||
),
|
|
||||||
hasDismissButton: false,
|
|
||||||
onConfirmed: () => Navigator.of(navigatorKey.currentContext!).pushNamed(
|
|
||||||
Routes.favouritesStep,
|
|
||||||
arguments: {"toTimer": true},
|
|
||||||
),
|
|
||||||
confrimTitle: 'تایید',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class _UsernameInputState extends State<UsernameInput> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: DidvanText(
|
child: DidvanText(
|
||||||
'نام کاربری میتواند شامل کاراکترهای کوچک و بزرگ انگلیسی و اعداد باشد.',
|
'نام کاربری میتواند شامل کاراکترهای انگلیسی و اعداد باشد.',
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
style: Theme.of(context).textTheme.labelSmall,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ class _HashtagState extends State<Hashtag> {
|
||||||
liked: item.liked,
|
liked: item.liked,
|
||||||
onLikedChanged: (_, value, __) =>
|
onLikedChanged: (_, value, __) =>
|
||||||
_changeLiked(item.id, value, 'banner'),
|
_changeLiked(item.id, value, 'banner'),
|
||||||
|
likes: item.likes,
|
||||||
);
|
);
|
||||||
|
|
||||||
case 'radar':
|
case 'radar':
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:didvan/config/design_config.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/app_icons.dart';
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
import 'package:didvan/models/view/app_bar_data.dart';
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/views/home/bookmarks/bookmark_state.dart';
|
import 'package:didvan/views/home/bookmarks/bookmark_state.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:didvan/views/widgets/menu_item.dart';
|
import 'package:didvan/views/widgets/menu_item.dart';
|
||||||
import 'package:didvan/views/widgets/overview/multitype.dart';
|
import 'package:didvan/views/widgets/overview/multitype.dart';
|
||||||
// import 'package:didvan/views/widgets/search_field.dart';
|
// import 'package:didvan/views/widgets/search_field.dart';
|
||||||
|
|
@ -124,7 +127,9 @@ class _BookmarksState extends State<Bookmarks> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
),
|
||||||
sliver: SliverStateHandler<BookmarksState>(
|
sliver: SliverStateHandler<BookmarksState>(
|
||||||
state: state,
|
state: state,
|
||||||
centerEmptyState: state.searching,
|
centerEmptyState: state.searching,
|
||||||
|
|
@ -144,9 +149,24 @@ class _BookmarksState extends State<Bookmarks> {
|
||||||
},
|
},
|
||||||
placeholder: MultitypeOverview.placeholder,
|
placeholder: MultitypeOverview.placeholder,
|
||||||
itemPadding: const EdgeInsets.only(bottom: 8),
|
itemPadding: const EdgeInsets.only(bottom: 8),
|
||||||
|
paddingEmptyState: 0,
|
||||||
emptyState: state.searching
|
emptyState: state.searching
|
||||||
? EmptyResult(onNewSearch: _focuseNode.requestFocus)
|
? EmptyResult(onNewSearch: _focuseNode.requestFocus)
|
||||||
: const EmptyList(),
|
: Column(
|
||||||
|
children: [
|
||||||
|
DidvanText(
|
||||||
|
'در قسمت رصدخانه من، تمامی محتواهایی که در قسمتهای مختلف سوپراپلیکیشن دیدوان، بوکمارک (نشاندار) کردهاید، به تفکیک نمایش داده میشوند. همچنین امکان درج یادداشت شخصی بصورت ضمیمه برای هر محتوا وجود دارد.',
|
||||||
|
fontSize: 14,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
textAlign: TextAlign.justify,
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
Assets.bookmarkAnimation,
|
||||||
|
width: MediaQuery.sizeOf(context).width,
|
||||||
|
height: 180,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
enableEmptyState: state.bookmarks.isEmpty,
|
enableEmptyState: state.bookmarks.isEmpty,
|
||||||
childCount:
|
childCount:
|
||||||
state.bookmarks.length + (state.page != state.lastPage ? 1 : 0),
|
state.bookmarks.length + (state.page != state.lastPage ? 1 : 0),
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import 'package:didvan/views/home/new_statistic/new_statistic.dart';
|
||||||
import 'package:didvan/views/home/search/search.dart';
|
import 'package:didvan/views/home/search/search.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';
|
||||||
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/bnb.dart';
|
import 'package:didvan/views/widgets/didvan/bnb.dart';
|
||||||
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
|
|
@ -35,13 +36,15 @@ import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../../services/app_home_widget/home_widget_repository.dart';
|
import '../../services/app_home_widget/home_widget_repository.dart';
|
||||||
|
|
||||||
final GlobalKey<ScaffoldState> homeScaffKey = GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> homeScaffKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
class Home extends StatefulWidget {
|
class Home extends StatefulWidget {
|
||||||
const Home({Key? key}) : super(key: key);
|
final bool? showDialogs;
|
||||||
|
const Home({Key? key, this.showDialogs}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<Home> createState() => _HomeState();
|
State<Home> createState() => _HomeState();
|
||||||
|
|
@ -51,8 +54,90 @@ class _HomeState extends State<Home>
|
||||||
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
|
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
|
|
||||||
|
Future<void> _showDialog(BuildContext context) async {
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||||
|
ActionSheetUtils(context)
|
||||||
|
.openDialog(
|
||||||
|
data: ActionSheetData(
|
||||||
|
content: const DidvanText(
|
||||||
|
'خوش آمدید!\nبرای امنیت بیشتر، رمز عبور خود را تغییر دهید.',
|
||||||
|
),
|
||||||
|
onConfirmed: () {
|
||||||
|
Future.delayed(
|
||||||
|
Duration.zero,
|
||||||
|
() => Navigator.of(context)
|
||||||
|
.pushNamed(Routes.authenticaion, arguments: true),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
isBackgroundDropBlur: false,
|
||||||
|
confrimTitle: 'تغییر رمز عبور',
|
||||||
|
dismissTitle: 'بعدا',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => ActionSheetUtils(context).openDialog(
|
||||||
|
data: ActionSheetData(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
isBackgroundDropBlur: true,
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
InkWrapper(
|
||||||
|
onPressed: () {
|
||||||
|
Future.delayed(
|
||||||
|
Duration.zero,
|
||||||
|
() => Navigator.of(context).pop(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
DidvanIcons.close_solid,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'شخصی سازی محتوا',
|
||||||
|
style: Theme.of(context).textTheme.displaySmall,
|
||||||
|
color: Theme.of(context).colorScheme.text,
|
||||||
|
),
|
||||||
|
const InkWrapper(
|
||||||
|
child: Icon(
|
||||||
|
DidvanIcons.close_regular,
|
||||||
|
size: 24,
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
const DidvanText(
|
||||||
|
"کاربر گرامی\nلطفا جهت شخصیسازی و استفاده بهتر از برنامه، دستهبندیهای مورد علاقه خود و زمان دریافت اعلانات را انتخاب نمایید.")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// hasDismissButton: false,
|
||||||
|
onConfirmed: () {
|
||||||
|
Future.delayed(
|
||||||
|
Duration.zero,
|
||||||
|
() =>
|
||||||
|
Navigator.of(navigatorKey.currentContext!).pushNamed(
|
||||||
|
Routes.favouritesStep,
|
||||||
|
arguments: {"toTimer": true},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
confrimTitle: 'تایید',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
if (widget.showDialogs ?? false) {
|
||||||
|
_showDialog(context);
|
||||||
|
}
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
NotificationService.startListeningNotificationEvents();
|
NotificationService.startListeningNotificationEvents();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ class _InfographyScreenState extends State<InfographyScreen> {
|
||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < state.categories.length; i++)
|
for (var i = 0; i < state.categories.length; i++)
|
||||||
|
if (state.categories[i].label != 'هوشان')
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
child: DidvanCheckbox(
|
child: DidvanCheckbox(
|
||||||
|
|
@ -232,6 +233,7 @@ class _InfographyScreenState extends State<InfographyScreen> {
|
||||||
liked: state.contents[index].liked,
|
liked: state.contents[index].liked,
|
||||||
onLikedChanged: (id, value, _) =>
|
onLikedChanged: (id, value, _) =>
|
||||||
state.changeLiked(id, value),
|
state.changeLiked(id, value),
|
||||||
|
likes: state.contents[index].likes,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ class InfographyItem extends StatelessWidget {
|
||||||
final int id;
|
final int id;
|
||||||
final bool marked;
|
final bool marked;
|
||||||
final bool liked;
|
final bool liked;
|
||||||
|
final int likes;
|
||||||
final void Function(int id, bool value, bool shouldUpdate) onMarkChanged;
|
final void Function(int id, bool value, bool shouldUpdate) onMarkChanged;
|
||||||
final void Function(int id, bool value, bool shouldUpdate) onLikedChanged;
|
final void Function(int id, bool value, bool shouldUpdate) onLikedChanged;
|
||||||
|
|
||||||
|
|
@ -72,6 +73,7 @@ class InfographyItem extends StatelessWidget {
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.marked,
|
required this.marked,
|
||||||
required this.liked,
|
required this.liked,
|
||||||
|
required this.likes,
|
||||||
required this.onLikedChanged});
|
required this.onLikedChanged});
|
||||||
|
|
||||||
void _openInteractiveViewer(BuildContext context, String image) {
|
void _openInteractiveViewer(BuildContext context, String image) {
|
||||||
|
|
@ -152,6 +154,17 @@ class InfographyItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
LikedButton(
|
||||||
|
itemId: id,
|
||||||
|
type: 'infography',
|
||||||
|
gestureSize: 32,
|
||||||
|
value: liked,
|
||||||
|
onMarkChanged: (value) => onLikedChanged(id, value, true),
|
||||||
|
likes: likes,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4.0,
|
||||||
|
),
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
gestureSize: 32,
|
gestureSize: 32,
|
||||||
onPressed: () => Navigator.of(context).pushNamed(
|
onPressed: () => Navigator.of(context).pushNamed(
|
||||||
|
|
@ -164,19 +177,6 @@ class InfographyItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
icon: DidvanIcons.mention_icon,
|
icon: DidvanIcons.mention_icon,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
|
||||||
width: 8.0,
|
|
||||||
),
|
|
||||||
LikedButton(
|
|
||||||
itemId: id,
|
|
||||||
type: 'infography',
|
|
||||||
gestureSize: 32,
|
|
||||||
value: liked,
|
|
||||||
onMarkChanged: (value) => onLikedChanged(id, value, true),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 8.0,
|
|
||||||
),
|
|
||||||
BookmarkButton(
|
BookmarkButton(
|
||||||
itemId: id,
|
itemId: id,
|
||||||
type: 'infography',
|
type: 'infography',
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class SearchPage extends StatelessWidget {
|
||||||
isColapsed: state.selectedCats.length <= 1,
|
isColapsed: state.selectedCats.length <= 1,
|
||||||
selectedCats: state.selectedCats,
|
selectedCats: state.selectedCats,
|
||||||
categories: state.categoryFilters,
|
categories: state.categoryFilters,
|
||||||
|
disableHoushan: true,
|
||||||
onSelected: (id) {
|
onSelected: (id) {
|
||||||
state.selectedCats.clear();
|
state.selectedCats.clear();
|
||||||
final cat = state.categoryFilters
|
final cat = state.categoryFilters
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,18 @@ class _MentionsState extends State<Mentions> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_bottomPadding = bottomViewInset;
|
_bottomPadding = bottomViewInset;
|
||||||
return Material(
|
return WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
if (mentionsState.showUsersForMentionsLayout) {
|
||||||
|
mentionsState.showUsersForMentionsLayout = false;
|
||||||
|
mentionsState.searchUsers.text = '';
|
||||||
|
|
||||||
|
mentionsState.update();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
child: Material(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
DidvanScaffold(
|
DidvanScaffold(
|
||||||
|
|
@ -119,9 +130,12 @@ class _MentionsState extends State<Mentions> {
|
||||||
filter: ImageFilter.blur(sigmaX: 8.0, sigmaY: 8.0),
|
filter: ImageFilter.blur(sigmaX: 8.0, sigmaY: 8.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color: Theme.of(context)
|
||||||
Theme.of(context).colorScheme.focused.withOpacity(0.5)),
|
.colorScheme
|
||||||
|
.focused
|
||||||
|
.withOpacity(0.5)),
|
||||||
child: DidvanScaffold(
|
child: DidvanScaffold(
|
||||||
|
hidePlayer: true,
|
||||||
appBarData: null,
|
appBarData: null,
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 16, right: 16, top: 16, bottom: 92),
|
left: 16, right: 16, top: 16, bottom: 92),
|
||||||
|
|
@ -182,7 +196,8 @@ class _MentionsState extends State<Mentions> {
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
icon: DidvanIcons.close_regular,
|
icon: DidvanIcons.close_regular,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
mentionsState.showUsersForMentionsLayout = false;
|
mentionsState.showUsersForMentionsLayout =
|
||||||
|
false;
|
||||||
mentionsState.searchUsers.text = '';
|
mentionsState.searchUsers.text = '';
|
||||||
|
|
||||||
mentionsState.update();
|
mentionsState.update();
|
||||||
|
|
@ -215,6 +230,7 @@ class _MentionsState extends State<Mentions> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,9 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
horizontal: 8,
|
horizontal: 8,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: (state.videosSelected
|
color: Theme.of(context)
|
||||||
? Theme.of(context)
|
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.secondaryDisabled
|
.focused
|
||||||
: Theme.of(context).colorScheme.focused)
|
|
||||||
.withOpacity(0.9),
|
.withOpacity(0.9),
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
bottom: Radius.circular(10),
|
bottom: Radius.circular(10),
|
||||||
|
|
@ -103,9 +101,11 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
width: 52,
|
width: 52,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Theme.of(context)
|
color: (state.videosSelected
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.secondary
|
.focusedBorder)
|
||||||
.withOpacity(0.7),
|
.withOpacity(0.7),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
|
|
@ -155,13 +155,6 @@ class _SliderIndicator extends StatelessWidget {
|
||||||
required this.isVideo,
|
required this.isVideo,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
Color _color(BuildContext context) {
|
|
||||||
if (isVideo) {
|
|
||||||
return Theme.of(context).colorScheme.secondary;
|
|
||||||
}
|
|
||||||
return Theme.of(context).colorScheme.focusedBorder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
|
|
@ -171,10 +164,11 @@ class _SliderIndicator extends StatelessWidget {
|
||||||
margin: const EdgeInsets.only(left: 4),
|
margin: const EdgeInsets.only(left: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: _color(context),
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
),
|
),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: isCurrentIndex ? _color(context) : null,
|
color:
|
||||||
|
isCurrentIndex ? Theme.of(context).colorScheme.focusedBorder : null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class StudioTabBar extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _StudioTypeButton(
|
child: _StudioTypeButton(
|
||||||
icon: DidvanIcons.video_solid,
|
icon: DidvanIcons.video_solid,
|
||||||
selectedColor: Theme.of(context).colorScheme.secondary,
|
selectedColor: Theme.of(context).colorScheme.focusedBorder,
|
||||||
title: 'ویدیو',
|
title: 'ویدیو',
|
||||||
onTap: () => state.videosSelected = true,
|
onTap: () => state.videosSelected = true,
|
||||||
isSelected: state.videosSelected,
|
isSelected: state.videosSelected,
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ class _ProfilePageState extends State<ProfilePage> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
DidvanText(
|
DidvanText(
|
||||||
'نسخه نرمافزار: 3.2.2',
|
'نسخه نرمافزار: 3.3.0',
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// ignore_for_file: library_private_types_in_public_api, deprecated_member_use
|
// ignore_for_file: library_private_types_in_public_api, deprecated_member_use
|
||||||
|
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
|
|
@ -62,7 +63,18 @@ class _WebViewState extends State<WebView> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: loading
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Padding(
|
||||||
|
padding: EdgeInsets.only(top: 12.0),
|
||||||
|
child: DidvanText(
|
||||||
|
'بازگشت به دیدوان',
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
toolbarHeight: 32,
|
||||||
|
),
|
||||||
|
body: loading
|
||||||
? Center(
|
? Center(
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
Assets.loadingAnimation,
|
Assets.loadingAnimation,
|
||||||
|
|
@ -70,6 +82,7 @@ class _WebViewState extends State<WebView> {
|
||||||
height: 60,
|
height: 60,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: WebViewWidget(controller: controller));
|
: WebViewWidget(controller: controller),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class CategoriesList extends StatefulWidget {
|
||||||
final bool isAppBar;
|
final bool isAppBar;
|
||||||
final List<CategoryData> selectedCats;
|
final List<CategoryData> selectedCats;
|
||||||
final List<CategoryData> categories;
|
final List<CategoryData> categories;
|
||||||
|
final bool disableHoushan;
|
||||||
final void Function(int id) onSelected;
|
final void Function(int id) onSelected;
|
||||||
final double top;
|
final double top;
|
||||||
const CategoriesList({
|
const CategoriesList({
|
||||||
|
|
@ -19,6 +20,7 @@ class CategoriesList extends StatefulWidget {
|
||||||
required this.categories,
|
required this.categories,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
this.isAppBar = true,
|
this.isAppBar = true,
|
||||||
|
this.disableHoushan = false,
|
||||||
required this.top,
|
required this.top,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
|
@ -69,7 +71,9 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
context,
|
context,
|
||||||
),
|
),
|
||||||
for (var i = 0; i < widget.categories.length; i++)
|
for (var i = 0; i < widget.categories.length; i++)
|
||||||
_itemBuilder(widget.categories[i], context),
|
widget.disableHoushan && widget.categories[i].label == 'هوشان'
|
||||||
|
? const SizedBox()
|
||||||
|
: _itemBuilder(widget.categories[i], context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:didvan/providers/user.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.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/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class LikedButton extends StatefulWidget {
|
class LikedButton extends StatefulWidget {
|
||||||
|
|
@ -15,6 +16,7 @@ class LikedButton extends StatefulWidget {
|
||||||
final double gestureSize;
|
final double gestureSize;
|
||||||
final String type;
|
final String type;
|
||||||
final int itemId;
|
final int itemId;
|
||||||
|
final int likes;
|
||||||
const LikedButton({
|
const LikedButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.value,
|
required this.value,
|
||||||
|
|
@ -22,6 +24,7 @@ class LikedButton extends StatefulWidget {
|
||||||
required this.gestureSize,
|
required this.gestureSize,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.itemId,
|
required this.itemId,
|
||||||
|
required this.likes,
|
||||||
this.askForConfirmation = false,
|
this.askForConfirmation = false,
|
||||||
this.color,
|
this.color,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
@ -45,16 +48,23 @@ class _LikedButtonState extends State<LikedButton> {
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
late int likes = widget.likes;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DidvanIconButton(
|
return Row(
|
||||||
gestureSize: widget.gestureSize,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
color: widget.color ??
|
children: [
|
||||||
(DesignConfig.isDark || !_value
|
if (likes != 0)
|
||||||
? null
|
SizedBox(
|
||||||
: Theme.of(context).colorScheme.primary),
|
height: 16,
|
||||||
icon: _value ? DidvanIcons.like_solid : DidvanIcons.like_regular,
|
child: DidvanText(
|
||||||
onPressed: () async {
|
likes.toString(),
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
bool confirm = false;
|
bool confirm = false;
|
||||||
if (widget.askForConfirmation) {
|
if (widget.askForConfirmation) {
|
||||||
await ActionSheetUtils(context).openDialog(
|
await ActionSheetUtils(context).openDialog(
|
||||||
|
|
@ -72,11 +82,24 @@ class _LikedButtonState extends State<LikedButton> {
|
||||||
if (!widget.askForConfirmation || confirm) {
|
if (!widget.askForConfirmation || confirm) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_value = !_value;
|
_value = !_value;
|
||||||
|
if (_value) {
|
||||||
|
likes += 1;
|
||||||
|
} else {
|
||||||
|
likes -= 1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
widget.onMarkChanged(_value);
|
widget.onMarkChanged(_value);
|
||||||
UserProvider.changeItemLiked(widget.type, widget.itemId, _value);
|
UserProvider.changeItemLiked(widget.type, widget.itemId, _value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
child: Icon(
|
||||||
|
_value ? CupertinoIcons.heart_fill : CupertinoIcons.heart,
|
||||||
|
size: 24,
|
||||||
|
color: widget.color ??
|
||||||
|
(!_value ? null : Theme.of(context).colorScheme.error),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,12 +193,13 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < state.categoryFilters.length; i++)
|
for (var i = 0; i < state.categoryFilters.length; i++)
|
||||||
|
if (state.categoryFilters[i].label != 'هوشان')
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
child: DidvanCheckbox(
|
child: DidvanCheckbox(
|
||||||
title: state.categoryFilters[i].label,
|
title: state.categoryFilters[i].label,
|
||||||
value:
|
value: state.selectedCats
|
||||||
state.selectedCats.contains(state.categoryFilters[i]),
|
.contains(state.categoryFilters[i]),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
state.selectedCats.add(state.categoryFilters[i]);
|
state.selectedCats.add(state.categoryFilters[i]);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ class MultitypeOverview extends StatelessWidget {
|
||||||
case 'podcast':
|
case 'podcast':
|
||||||
return DidvanIcons.podcast_light;
|
return DidvanIcons.podcast_light;
|
||||||
case 'delphi':
|
case 'delphi':
|
||||||
|
case 'survey':
|
||||||
return DidvanIcons.saha_light;
|
return DidvanIcons.saha_light;
|
||||||
case 'infography':
|
case 'infography':
|
||||||
return DidvanIcons.infography_regular;
|
return DidvanIcons.infography_regular;
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ class NewsOverview extends StatelessWidget {
|
||||||
onMarkChanged: (value) =>
|
onMarkChanged: (value) =>
|
||||||
onLikedChanged(news.id, value, false),
|
onLikedChanged(news.id, value, false),
|
||||||
askForConfirmation: hasUnmarkConfirmation,
|
askForConfirmation: hasUnmarkConfirmation,
|
||||||
|
likes: news.likes,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4.0,
|
||||||
),
|
),
|
||||||
BookmarkButton(
|
BookmarkButton(
|
||||||
itemId: news.id,
|
itemId: news.id,
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,10 @@ class RadarOverview extends StatelessWidget {
|
||||||
onMarkChanged: (value) =>
|
onMarkChanged: (value) =>
|
||||||
onLikedChanged(radar.id, value, false),
|
onLikedChanged(radar.id, value, false),
|
||||||
askForConfirmation: hasUnmarkConfirmation,
|
askForConfirmation: hasUnmarkConfirmation,
|
||||||
|
likes: radar.likes,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4.0,
|
||||||
),
|
),
|
||||||
BookmarkButton(
|
BookmarkButton(
|
||||||
itemId: radar.id,
|
itemId: radar.id,
|
||||||
|
|
|
||||||
|
|
@ -133,12 +133,13 @@ class SearchAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < state.categoryFilters.length; i++)
|
for (var i = 0; i < state.categoryFilters.length; i++)
|
||||||
|
if (state.categoryFilters[i].label != 'هوشان')
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
child: DidvanCheckbox(
|
child: DidvanCheckbox(
|
||||||
title: state.categoryFilters[i].label,
|
title: state.categoryFilters[i].label,
|
||||||
value:
|
value: state.selectedCats
|
||||||
state.selectedCats.contains(state.categoryFilters[i]),
|
.contains(state.categoryFilters[i]),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
state.selectedCats.add(state.categoryFilters[i]);
|
state.selectedCats.add(state.categoryFilters[i]);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
||||||
final bool centerEmptyState;
|
final bool centerEmptyState;
|
||||||
final bool hasConstraints;
|
final bool hasConstraints;
|
||||||
final int placeholderCount;
|
final int placeholderCount;
|
||||||
|
final double? paddingEmptyState;
|
||||||
SliverStateHandler({
|
SliverStateHandler({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.state,
|
required this.state,
|
||||||
|
|
@ -28,6 +29,7 @@ class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
||||||
this.centerEmptyState = true,
|
this.centerEmptyState = true,
|
||||||
this.hasConstraints = false,
|
this.hasConstraints = false,
|
||||||
this.placeholderCount = 3,
|
this.placeholderCount = 3,
|
||||||
|
this.paddingEmptyState,
|
||||||
}) : super(
|
}) : super(
|
||||||
key: key,
|
key: key,
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
|
@ -45,7 +47,8 @@ class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
||||||
if (enableEmptyState && state.appState == AppState.idle) {
|
if (enableEmptyState && state.appState == AppState.idle) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: centerEmptyState ? deviceHight / 4 : deviceHight / 8,
|
top: paddingEmptyState ??
|
||||||
|
(centerEmptyState ? deviceHight / 4 : deviceHight / 8),
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
),
|
),
|
||||||
child: emptyState,
|
child: emptyState,
|
||||||
|
|
|
||||||
|
|
@ -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.2.2+3220
|
version: 3.3.0+3300
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <3.0.0"
|
sdk: ">=2.19.0 <3.0.0"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue