design updates + bug fixes
This commit is contained in:
parent
9b221c4463
commit
1d401b3ba0
|
|
@ -3,7 +3,7 @@ import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
class CoreProvier with ChangeNotifier {
|
class CoreProvier with ChangeNotifier {
|
||||||
AppState _appState = AppState.idle;
|
AppState _appState = AppState.busy;
|
||||||
|
|
||||||
set appState(AppState newState) {
|
set appState(AppState newState) {
|
||||||
if (newState == AppState.isolatedBusy) {
|
if (newState == AppState.isolatedBusy) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
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:collection/collection.dart';
|
||||||
|
|
||||||
class ServerDataProvider {
|
class ServerDataProvider {
|
||||||
static final List<MapEntry> directTypes = [];
|
static final List<MapEntry> directTypes = [];
|
||||||
|
|
@ -10,7 +11,10 @@ class ServerDataProvider {
|
||||||
|
|
||||||
static int labelToTypeId(String label) => label.contains('پشتیبانی')
|
static int labelToTypeId(String label) => label.contains('پشتیبانی')
|
||||||
? 7
|
? 7
|
||||||
: directTypes.firstWhere((element) => element.value.contains(label)).key;
|
: directTypes
|
||||||
|
.firstWhereOrNull((element) => element.value.contains(label))
|
||||||
|
?.key ??
|
||||||
|
7;
|
||||||
|
|
||||||
static Future<void> _getDirectTypes() async {
|
static Future<void> _getDirectTypes() async {
|
||||||
final service = RequestService(RequestHelper.directTypes);
|
final service = RequestService(RequestHelper.directTypes);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ class UserProvider extends CoreProvier {
|
||||||
isAuthenticated = true;
|
isAuthenticated = true;
|
||||||
final RequestService service = RequestService(RequestHelper.userInfo);
|
final RequestService service = RequestService(RequestHelper.userInfo);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.statusCode == 401 || service.result['user'] == null) {
|
if (service.statusCode == 401 ||
|
||||||
|
(service.isSuccess && service.result['user'] == null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
|
|
|
||||||
|
|
@ -180,18 +180,24 @@ class RouteGenerator {
|
||||||
final shortestSide = MediaQuery.of(context).size.shortestSide;
|
final shortestSide = MediaQuery.of(context).size.shortestSide;
|
||||||
final bool useMobileLayout = shortestSide < 600;
|
final bool useMobileLayout = shortestSide < 600;
|
||||||
if (kIsWeb && !useMobileLayout) {
|
if (kIsWeb && !useMobileLayout) {
|
||||||
return Container(
|
return MediaQuery(
|
||||||
|
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
||||||
|
child: Container(
|
||||||
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),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Container(
|
return MediaQuery(
|
||||||
|
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
||||||
|
child: Container(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: page,
|
child: page,
|
||||||
top: false,
|
top: false,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ class CommentsState extends CoreProvier {
|
||||||
int itemId = 0;
|
int itemId = 0;
|
||||||
|
|
||||||
Future<void> getComments() async {
|
Future<void> getComments() async {
|
||||||
appState = AppState.busy;
|
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
RequestHelper.comments(itemId, type),
|
RequestHelper.comments(itemId, type),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ class _NewsDetailsState extends State<NewsDetails> {
|
||||||
state: state,
|
state: state,
|
||||||
builder: (context, state) => Stack(
|
builder: (context, state) => Stack(
|
||||||
children: [
|
children: [
|
||||||
if (state.news.isNotEmpty)
|
|
||||||
IgnorePointer(
|
IgnorePointer(
|
||||||
ignoring: state.isFetchingNewItem,
|
ignoring: state.isFetchingNewItem,
|
||||||
child: DidvanPageView(
|
child: DidvanPageView(
|
||||||
|
|
@ -55,7 +54,6 @@ class _NewsDetailsState extends State<NewsDetails> {
|
||||||
currentIndex: state.currentIndex,
|
currentIndex: state.currentIndex,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (state.news.isNotEmpty)
|
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ class _RadarDetailsState extends State<RadarDetails> {
|
||||||
state: state,
|
state: state,
|
||||||
builder: (context, state) => Stack(
|
builder: (context, state) => Stack(
|
||||||
children: [
|
children: [
|
||||||
if (state.radars.isNotEmpty)
|
|
||||||
IgnorePointer(
|
IgnorePointer(
|
||||||
ignoring: state.isFetchingNewItem,
|
ignoring: state.isFetchingNewItem,
|
||||||
child: DidvanPageView(
|
child: DidvanPageView(
|
||||||
|
|
@ -55,7 +54,6 @@ class _RadarDetailsState extends State<RadarDetails> {
|
||||||
currentIndex: state.currentIndex,
|
currentIndex: state.currentIndex,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (state.radars.isNotEmpty)
|
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
|
||||||
class FilteredBookmarksState extends CoreProvier {
|
class FilteredBookmarksState extends CoreProvier {
|
||||||
String search = '';
|
|
||||||
String lastSearch = '';
|
|
||||||
final List<OverviewData> bookmarks = [];
|
final List<OverviewData> bookmarks = [];
|
||||||
final String type;
|
final String type;
|
||||||
int page = 1;
|
int page = 1;
|
||||||
|
|
@ -15,17 +13,8 @@ class FilteredBookmarksState extends CoreProvier {
|
||||||
|
|
||||||
FilteredBookmarksState(this.type);
|
FilteredBookmarksState(this.type);
|
||||||
|
|
||||||
bool get searching => search != '';
|
|
||||||
|
|
||||||
Future<void> getBookmarks({required int page}) async {
|
Future<void> getBookmarks({required int page}) async {
|
||||||
if (search != '') {
|
|
||||||
lastSearch = search;
|
|
||||||
}
|
|
||||||
if (page == 1) {
|
|
||||||
bookmarks.clear();
|
|
||||||
}
|
|
||||||
this.page = page;
|
this.page = page;
|
||||||
appState = AppState.busy;
|
|
||||||
String typeString = '';
|
String typeString = '';
|
||||||
if (type == 'video' || type == 'podcast') {
|
if (type == 'video' || type == 'podcast') {
|
||||||
typeString = 'studios';
|
typeString = 'studios';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ class DirectListState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getDirectsList() async {
|
Future<void> getDirectsList() async {
|
||||||
appState = AppState.busy;
|
|
||||||
final RequestService service = RequestService(RequestHelper.directs);
|
final RequestService service = RequestService(RequestHelper.directs);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/models/view/app_bar_data.dart';
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
||||||
|
import 'package:didvan/views/home/studio/studio_details/widgets/details_tab_bar.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart';
|
import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/bookmark_button.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
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';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
@ -39,7 +41,7 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
() => state.getStudioDetails(widget.pageData['id']),
|
() => state.getStudioDetails(widget.pageData['id']),
|
||||||
);
|
);
|
||||||
state.args = widget.pageData['args'];
|
state.args = widget.pageData['args'];
|
||||||
if (!kIsWeb && Platform.isAndroid) WebView.platform = AndroidWebView();
|
if (Platform.isAndroid) WebView.platform = AndroidWebView();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,9 +109,27 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
appBarData: _isFullScreen
|
appBarData: _isFullScreen
|
||||||
? null
|
? null
|
||||||
: AppBarData(
|
: AppBarData(
|
||||||
|
trailing: BookmarkButton(
|
||||||
|
value: state.studio.marked,
|
||||||
|
onMarkChanged: (value) => widget
|
||||||
|
.pageData['onMarkChanged'](state.studio.id, value),
|
||||||
|
gestureSize: 48,
|
||||||
|
),
|
||||||
isSmall: true,
|
isSmall: true,
|
||||||
title: state.studio.title,
|
title: state.studio.title,
|
||||||
),
|
),
|
||||||
|
showSliversFirst: true,
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
pinned: true,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
toolbarHeight:
|
||||||
|
(_isFullScreen ? ds.height : ds.width * 9 / 16) +
|
||||||
|
72 -
|
||||||
|
MediaQuery.of(context).padding.top,
|
||||||
|
elevation: 0,
|
||||||
|
flexibleSpace: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: ds.width,
|
width: ds.width,
|
||||||
|
|
@ -117,7 +137,8 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
WebView(
|
WebView(
|
||||||
backgroundColor: Theme.of(context).colorScheme.black,
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.black,
|
||||||
allowsInlineMediaPlayback: true,
|
allowsInlineMediaPlayback: true,
|
||||||
initialUrl: Uri.dataFromString(
|
initialUrl: Uri.dataFromString(
|
||||||
'''
|
'''
|
||||||
|
|
@ -172,9 +193,8 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
DetailsTabBar(
|
||||||
StudioDetailsWidget(
|
isVideo: true,
|
||||||
scrollController: _scrollController,
|
|
||||||
onCommentsTabSelected: () => Future.delayed(
|
onCommentsTabSelected: () => Future.delayed(
|
||||||
const Duration(milliseconds: 100),
|
const Duration(milliseconds: 100),
|
||||||
() => _scrollController.animateTo(
|
() => _scrollController.animateTo(
|
||||||
|
|
@ -183,6 +203,14 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
StudioDetailsWidget(
|
||||||
|
scrollController: _scrollController,
|
||||||
studio: state.studio,
|
studio: state.studio,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,17 @@ import 'dart:io';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
|
||||||
import 'package:didvan/models/view/app_bar_data.dart';
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
||||||
|
import 'package:didvan/views/home/studio/studio_details/widgets/details_tab_bar.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart';
|
import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/bookmark_button.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
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';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
|
||||||
|
|
||||||
class StudioDetails extends StatefulWidget {
|
class StudioDetails extends StatefulWidget {
|
||||||
final Map<String, dynamic> pageData;
|
final Map<String, dynamic> pageData;
|
||||||
|
|
@ -28,10 +27,6 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
|
|
||||||
bool _isFullScreen = false;
|
bool _isFullScreen = false;
|
||||||
bool _isInit = true;
|
|
||||||
|
|
||||||
double _dwInPortrait = 0;
|
|
||||||
double _scaleInPortrait = 1;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -41,7 +36,6 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
() => state.getStudioDetails(widget.pageData['id']),
|
() => state.getStudioDetails(widget.pageData['id']),
|
||||||
);
|
);
|
||||||
state.args = widget.pageData['args'];
|
state.args = widget.pageData['args'];
|
||||||
if (!kIsWeb && Platform.isAndroid) WebView.platform = AndroidWebView();
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,12 +71,6 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ds = MediaQuery.of(context).size;
|
final ds = MediaQuery.of(context).size;
|
||||||
if (_isInit) {
|
|
||||||
_dwInPortrait = MediaQuery.of(context).size.width;
|
|
||||||
_scaleInPortrait = _dwInPortrait / 576;
|
|
||||||
_isInit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Consumer<StudioDetailsState>(
|
return Consumer<StudioDetailsState>(
|
||||||
builder: (context, state, child) => StateHandler<StudioDetailsState>(
|
builder: (context, state, child) => StateHandler<StudioDetailsState>(
|
||||||
state: state,
|
state: state,
|
||||||
|
|
@ -121,79 +109,31 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
: AppBarData(
|
: AppBarData(
|
||||||
isSmall: true,
|
isSmall: true,
|
||||||
title: state.studio.title,
|
title: state.studio.title,
|
||||||
|
trailing: BookmarkButton(
|
||||||
|
value: state.studio.marked,
|
||||||
|
onMarkChanged: (value) => widget
|
||||||
|
.pageData['onMarkChanged'](state.studio.id, value),
|
||||||
|
gestureSize: 48,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
showSliversFirst: true,
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
pinned: true,
|
||||||
|
elevation: 0,
|
||||||
|
toolbarHeight:
|
||||||
|
(_isFullScreen ? ds.height : ds.width * 9 / 16) +
|
||||||
|
72 -
|
||||||
|
MediaQuery.of(context).padding.top,
|
||||||
|
flexibleSpace: Column(
|
||||||
children: [
|
children: [
|
||||||
if (kIsWeb)
|
|
||||||
const AspectRatio(
|
const AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: HtmlElementView(viewType: 'video'),
|
child: HtmlElementView(viewType: 'video'),
|
||||||
),
|
),
|
||||||
if (!kIsWeb)
|
DetailsTabBar(
|
||||||
SizedBox(
|
isVideo: true,
|
||||||
width: ds.width,
|
|
||||||
height: _isFullScreen ? ds.height : ds.width * 9 / 16,
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
WebView(
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.black,
|
|
||||||
allowsInlineMediaPlayback: true,
|
|
||||||
initialUrl: Uri.dataFromString(
|
|
||||||
'''
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width, initial-scale=$_scaleInPortrait"
|
|
||||||
/>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
iframe {
|
|
||||||
max-height: 100vh;
|
|
||||||
}
|
|
||||||
.r1_iframe_embed {
|
|
||||||
height: ${MediaQuery.of(context).size.width / _scaleInPortrait}px !important;
|
|
||||||
padding-top: 0 !important;
|
|
||||||
}
|
|
||||||
@media(max-width:580px){
|
|
||||||
.r1_iframe_embed {
|
|
||||||
height: ${_dwInPortrait * 9 / 16 / _scaleInPortrait}px !important;
|
|
||||||
padding-top: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${state.studio.media}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
''',
|
|
||||||
mimeType: 'text/html',
|
|
||||||
).toString(),
|
|
||||||
javascriptMode: JavascriptMode.unrestricted,
|
|
||||||
),
|
|
||||||
if (!kIsWeb)
|
|
||||||
Positioned(
|
|
||||||
right: 42,
|
|
||||||
bottom: 8,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => _changeFullSceen(!_isFullScreen),
|
|
||||||
child: Container(
|
|
||||||
color: Colors.transparent,
|
|
||||||
width: 24,
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
StudioDetailsWidget(
|
|
||||||
scrollController: _scrollController,
|
|
||||||
onCommentsTabSelected: () => Future.delayed(
|
onCommentsTabSelected: () => Future.delayed(
|
||||||
const Duration(milliseconds: 100),
|
const Duration(milliseconds: 100),
|
||||||
() => _scrollController.animateTo(
|
() => _scrollController.animateTo(
|
||||||
|
|
@ -202,6 +142,14 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
StudioDetailsWidget(
|
||||||
|
scrollController: _scrollController,
|
||||||
studio: state.studio,
|
studio: state.studio,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ class StudioDetailsState extends CoreProvier {
|
||||||
final service = RequestService(RequestHelper.tag(
|
final service = RequestService(RequestHelper.tag(
|
||||||
ids: studio.tags.map((tag) => tag.id).toList(),
|
ids: studio.tags.map((tag) => tag.id).toList(),
|
||||||
itemId: studio.id,
|
itemId: studio.id,
|
||||||
type: studio.media.contains('iframe') ? 'video' : 'podcast',
|
type: args.type,
|
||||||
));
|
));
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class DetailsTabBar extends StatelessWidget {
|
||||||
|
final bool isVideo;
|
||||||
|
final VoidCallback onCommentsTabSelected;
|
||||||
|
|
||||||
|
const DetailsTabBar({
|
||||||
|
Key? key,
|
||||||
|
required this.isVideo,
|
||||||
|
required this.onCommentsTabSelected,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final state = context.read<StudioDetailsState>();
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
state.selectedDetailsIndex = 0;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 72,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color(0XFF1B3C59).withOpacity(0.15),
|
||||||
|
offset: const Offset(0, 8),
|
||||||
|
blurRadius: 8,
|
||||||
|
spreadRadius: 0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
_TabItem(
|
||||||
|
icon: DidvanIcons.description_solid,
|
||||||
|
title: 'توضیحات',
|
||||||
|
onTap: () => state.selectedDetailsIndex = 0,
|
||||||
|
isSelected: state.selectedDetailsIndex == 0,
|
||||||
|
isVideo: isVideo,
|
||||||
|
),
|
||||||
|
_TabItem(
|
||||||
|
icon: DidvanIcons.chats_solid,
|
||||||
|
title: 'نظرات',
|
||||||
|
onTap: () {
|
||||||
|
state.selectedDetailsIndex = 1;
|
||||||
|
onCommentsTabSelected();
|
||||||
|
},
|
||||||
|
isSelected: state.selectedDetailsIndex == 1,
|
||||||
|
isVideo: isVideo,
|
||||||
|
),
|
||||||
|
_TabItem(
|
||||||
|
icon: DidvanIcons.puzzle_solid,
|
||||||
|
title: 'مطالب مرتبط',
|
||||||
|
onTap: () => state.selectedDetailsIndex = 2,
|
||||||
|
isSelected: state.selectedDetailsIndex == 2,
|
||||||
|
isVideo: isVideo,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TabItem extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String title;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final bool isSelected;
|
||||||
|
final bool isVideo;
|
||||||
|
const _TabItem({
|
||||||
|
Key? key,
|
||||||
|
required this.icon,
|
||||||
|
required this.title,
|
||||||
|
required this.onTap,
|
||||||
|
required this.isSelected,
|
||||||
|
required this.isVideo,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
Color? _color(context) {
|
||||||
|
if (isSelected) {
|
||||||
|
if (isVideo) {
|
||||||
|
return Theme.of(context).colorScheme.secondary;
|
||||||
|
}
|
||||||
|
return Theme.of(context).colorScheme.focusedBorder;
|
||||||
|
}
|
||||||
|
return Theme.of(context).colorScheme.border;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: _color(context),
|
||||||
|
),
|
||||||
|
AnimatedContainer(
|
||||||
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
|
width: isSelected ? 64 : 0,
|
||||||
|
height: 1,
|
||||||
|
color: _color(context),
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
title,
|
||||||
|
color: _color(context),
|
||||||
|
style: Theme.of(context).textTheme.caption,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:didvan/models/studio_details_data.dart';
|
||||||
import 'package:didvan/views/home/comments/comments.dart';
|
import 'package:didvan/views/home/comments/comments.dart';
|
||||||
import 'package:didvan/views/home/comments/comments_state.dart';
|
import 'package:didvan/views/home/comments/comments_state.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
||||||
|
import 'package:didvan/views/home/studio/studio_details/widgets/details_tab_bar.dart';
|
||||||
import 'package:didvan/views/home/widgets/overview/multitype.dart';
|
import 'package:didvan/views/home/widgets/overview/multitype.dart';
|
||||||
import 'package:didvan/views/home/widgets/tag_item.dart';
|
import 'package:didvan/views/home/widgets/tag_item.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
|
@ -16,15 +17,15 @@ import 'package:provider/provider.dart';
|
||||||
class StudioDetailsWidget extends StatelessWidget {
|
class StudioDetailsWidget extends StatelessWidget {
|
||||||
final StudioDetailsData studio;
|
final StudioDetailsData studio;
|
||||||
final ScrollController? scrollController;
|
final ScrollController? scrollController;
|
||||||
final VoidCallback onCommentsTabSelected;
|
final VoidCallback? onCommentsTabSelected;
|
||||||
const StudioDetailsWidget({
|
const StudioDetailsWidget({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.studio,
|
required this.studio,
|
||||||
required this.onCommentsTabSelected,
|
this.onCommentsTabSelected,
|
||||||
this.scrollController,
|
this.scrollController,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
bool get _isVideo => studio.media.contains('ifram');
|
bool get _isVideo => studio.media.contains('iframe');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -35,38 +36,12 @@ class StudioDetailsWidget extends StatelessWidget {
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
if (!_isVideo)
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
DetailsTabBar(
|
||||||
children: [
|
|
||||||
const SizedBox(),
|
|
||||||
_TabItem(
|
|
||||||
icon: DidvanIcons.description_solid,
|
|
||||||
title: 'توضیحات',
|
|
||||||
onTap: () => state.selectedDetailsIndex = 0,
|
|
||||||
isSelected: state.selectedDetailsIndex == 0,
|
|
||||||
isVideo: _isVideo,
|
isVideo: _isVideo,
|
||||||
|
onCommentsTabSelected: onCommentsTabSelected ?? () {},
|
||||||
),
|
),
|
||||||
_TabItem(
|
if (state.selectedDetailsIndex != 1) const SizedBox(height: 16),
|
||||||
icon: DidvanIcons.chats_solid,
|
|
||||||
title: 'نظرات',
|
|
||||||
onTap: () {
|
|
||||||
state.selectedDetailsIndex = 1;
|
|
||||||
onCommentsTabSelected();
|
|
||||||
},
|
|
||||||
isSelected: state.selectedDetailsIndex == 1,
|
|
||||||
isVideo: _isVideo,
|
|
||||||
),
|
|
||||||
_TabItem(
|
|
||||||
icon: DidvanIcons.puzzle_solid,
|
|
||||||
title: 'مطالب مرتبط',
|
|
||||||
onTap: () => state.selectedDetailsIndex = 2,
|
|
||||||
isSelected: state.selectedDetailsIndex == 2,
|
|
||||||
isVideo: _isVideo,
|
|
||||||
),
|
|
||||||
const SizedBox(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
StateHandler<StudioDetailsState>(
|
StateHandler<StudioDetailsState>(
|
||||||
onRetry: () {},
|
onRetry: () {},
|
||||||
state: state,
|
state: state,
|
||||||
|
|
@ -116,7 +91,10 @@ class StudioDetailsWidget extends StatelessWidget {
|
||||||
return ChangeNotifierProvider<CommentsState>(
|
return ChangeNotifierProvider<CommentsState>(
|
||||||
create: (context) => CommentsState(),
|
create: (context) => CommentsState(),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: ds.height - 180,
|
height: ds.height -
|
||||||
|
ds.width * 9 / 16 -
|
||||||
|
128 -
|
||||||
|
MediaQuery.of(context).padding.top,
|
||||||
child: Comments(
|
child: Comments(
|
||||||
pageData: {
|
pageData: {
|
||||||
'id': studio.id,
|
'id': studio.id,
|
||||||
|
|
@ -164,63 +142,6 @@ class StudioDetailsWidget extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TabItem extends StatelessWidget {
|
|
||||||
final IconData icon;
|
|
||||||
final String title;
|
|
||||||
final VoidCallback onTap;
|
|
||||||
final bool isSelected;
|
|
||||||
final bool isVideo;
|
|
||||||
const _TabItem({
|
|
||||||
Key? key,
|
|
||||||
required this.icon,
|
|
||||||
required this.title,
|
|
||||||
required this.onTap,
|
|
||||||
required this.isSelected,
|
|
||||||
required this.isVideo,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
Color? _color(context) {
|
|
||||||
if (isSelected) {
|
|
||||||
if (isVideo) {
|
|
||||||
return Theme.of(context).colorScheme.secondary;
|
|
||||||
}
|
|
||||||
return Theme.of(context).colorScheme.focusedBorder;
|
|
||||||
}
|
|
||||||
return Theme.of(context).colorScheme.border;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Container(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
icon,
|
|
||||||
color: _color(context),
|
|
||||||
),
|
|
||||||
if (isSelected) const SizedBox(height: 8),
|
|
||||||
if (isSelected)
|
|
||||||
Container(
|
|
||||||
width: 64,
|
|
||||||
height: 1,
|
|
||||||
color: _color(context),
|
|
||||||
),
|
|
||||||
if (isSelected)
|
|
||||||
DidvanText(
|
|
||||||
title,
|
|
||||||
color: _color(context),
|
|
||||||
style: Theme.of(context).textTheme.caption,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StudioPreview extends StatelessWidget {
|
class _StudioPreview extends StatelessWidget {
|
||||||
final bool isNext;
|
final bool isNext;
|
||||||
final StudioDetailsData studio;
|
final StudioDetailsData studio;
|
||||||
|
|
@ -279,7 +200,7 @@ class _StudioPreview extends StatelessWidget {
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
DidvanText(
|
DidvanText(
|
||||||
studio.title,
|
studio.title,
|
||||||
maxLines: 3,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.overline,
|
style: Theme.of(context).textTheme.overline,
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,10 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < state.sliders.length; i++)
|
for (var i = 0; i < state.sliders.length; i++)
|
||||||
_SliderIndicator(isCurrentIndex: selectedIndex == i),
|
_SliderIndicator(
|
||||||
|
isCurrentIndex: selectedIndex == i,
|
||||||
|
isVideo: state.videosSelected,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
@ -125,8 +128,19 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
|
|
||||||
class _SliderIndicator extends StatelessWidget {
|
class _SliderIndicator extends StatelessWidget {
|
||||||
final bool isCurrentIndex;
|
final bool isCurrentIndex;
|
||||||
const _SliderIndicator({Key? key, required this.isCurrentIndex})
|
final bool isVideo;
|
||||||
: super(key: key);
|
const _SliderIndicator({
|
||||||
|
Key? key,
|
||||||
|
required this.isCurrentIndex,
|
||||||
|
required this.isVideo,
|
||||||
|
}) : 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) {
|
||||||
|
|
@ -137,11 +151,10 @@ 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: Theme.of(context).colorScheme.focusedBorder,
|
color: _color(context),
|
||||||
),
|
),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color:
|
color: isCurrentIndex ? _color(context) : null,
|
||||||
isCurrentIndex ? Theme.of(context).colorScheme.focusedBorder : null,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,7 @@ class StudioTabBar extends StatelessWidget {
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: state.videosSelected
|
color: Theme.of(context).colorScheme.border,
|
||||||
? Theme.of(context).colorScheme.secondary
|
|
||||||
: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
),
|
||||||
borderRadius: DesignConfig.lowBorderRadius,
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
),
|
),
|
||||||
|
|
@ -88,14 +86,12 @@ class _StudioTypeButton extends StatelessWidget {
|
||||||
size: 32,
|
size: 32,
|
||||||
color: _color(context),
|
color: _color(context),
|
||||||
),
|
),
|
||||||
if (!isSelected) const SizedBox(height: 18),
|
AnimatedContainer(
|
||||||
if (isSelected)
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
Container(
|
width: isSelected ? 88 : 0,
|
||||||
width: 88,
|
|
||||||
height: 1,
|
height: 1,
|
||||||
color: _color(context),
|
color: _color(context),
|
||||||
),
|
),
|
||||||
if (isSelected)
|
|
||||||
DidvanText(
|
DidvanText(
|
||||||
title,
|
title,
|
||||||
style: Theme.of(context).textTheme.overline,
|
style: Theme.of(context).textTheme.overline,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
|
@ -43,7 +44,10 @@ class _BookmarkButtonState extends State<BookmarkButton> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DidvanIconButton(
|
return DidvanIconButton(
|
||||||
gestureSize: widget.gestureSize,
|
gestureSize: widget.gestureSize,
|
||||||
color: widget.color,
|
color: widget.color ??
|
||||||
|
(DesignConfig.isDark || !_value
|
||||||
|
? null
|
||||||
|
: Theme.of(context).colorScheme.primary),
|
||||||
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
bool confirm = false;
|
bool confirm = false;
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,9 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (widget.isRadar)
|
if (widget.isRadar)
|
||||||
BookmarkButton(
|
BookmarkButton(
|
||||||
|
color: DesignConfig.isDark
|
||||||
|
? Theme.of(context).colorScheme.focusedBorder
|
||||||
|
: Theme.of(context).colorScheme.focused,
|
||||||
askForConfirmation: widget.hasUnmarkConfirmation,
|
askForConfirmation: widget.hasUnmarkConfirmation,
|
||||||
value: widget.item.marked,
|
value: widget.item.marked,
|
||||||
onMarkChanged: (value) {
|
onMarkChanged: (value) {
|
||||||
|
|
@ -143,6 +146,9 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
||||||
if (!widget.isRadar) const SizedBox(width: 12),
|
if (!widget.isRadar) const SizedBox(width: 12),
|
||||||
if (!widget.isRadar)
|
if (!widget.isRadar)
|
||||||
BookmarkButton(
|
BookmarkButton(
|
||||||
|
color: DesignConfig.isDark
|
||||||
|
? Theme.of(context).colorScheme.focusedBorder
|
||||||
|
: Theme.of(context).colorScheme.focused,
|
||||||
askForConfirmation: widget.hasUnmarkConfirmation,
|
askForConfirmation: widget.hasUnmarkConfirmation,
|
||||||
value: widget.item.marked,
|
value: widget.item.marked,
|
||||||
onMarkChanged: (value) {
|
onMarkChanged: (value) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:didvan/models/requests/news.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/utils/date_time.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/card.dart';
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
|
@ -127,7 +128,22 @@ class MultitypeOverview extends StatelessWidget {
|
||||||
DateTime.parse(item.createdAt).toPersianDateStr(),
|
DateTime.parse(item.createdAt).toPersianDateStr(),
|
||||||
style: Theme.of(context).textTheme.overline,
|
style: Theme.of(context).textTheme.overline,
|
||||||
),
|
),
|
||||||
// DidvanText('text'),
|
const Spacer(),
|
||||||
|
if ((item.timeToRead ?? item.duration) != null) ...[
|
||||||
|
const Icon(
|
||||||
|
DidvanIcons.timer_light,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
DidvanText(
|
||||||
|
item.timeToRead != null
|
||||||
|
? 'خواندن در ${item.timeToRead} دقیقه'
|
||||||
|
: DateTimeUtils.normalizeTimeDuration(
|
||||||
|
Duration(seconds: item.duration!),
|
||||||
|
),
|
||||||
|
style: Theme.of(context).textTheme.overline,
|
||||||
|
),
|
||||||
|
]
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ class DidvanAppBar extends StatelessWidget {
|
||||||
return Container(
|
return Container(
|
||||||
height: appBarData.isSmall ? 56 : 72,
|
height: appBarData.isSmall ? 56 : 72,
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
padding: const EdgeInsets.only(right: 4, left: 20),
|
padding:
|
||||||
|
EdgeInsets.only(right: 4, left: appBarData.trailing == null ? 20 : 0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: hasBorder
|
border: hasBorder
|
||||||
? Border(
|
? Border(
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,13 @@ class DidvanBNB extends StatelessWidget {
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
persistentHeader: Column(
|
persistentHeader: GestureDetector(
|
||||||
|
onVerticalDragUpdate: (details) {
|
||||||
|
if (details.delta.dy > 10) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
AudioPlayerWidget(
|
AudioPlayerWidget(
|
||||||
|
|
@ -228,6 +234,7 @@ class DidvanBNB extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
expandableContent: state.appState == AppState.busy
|
expandableContent: state.appState == AppState.busy
|
||||||
? const SizedBox()
|
? const SizedBox()
|
||||||
: StudioDetailsWidget(
|
: StudioDetailsWidget(
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class DidvanScaffold extends StatefulWidget {
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
final ScrollController? scrollController;
|
final ScrollController? scrollController;
|
||||||
|
final bool showSliversFirst;
|
||||||
|
|
||||||
const DidvanScaffold({
|
const DidvanScaffold({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
|
@ -20,6 +21,7 @@ class DidvanScaffold extends StatefulWidget {
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.scrollController,
|
this.scrollController,
|
||||||
|
this.showSliversFirst = false,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -60,7 +62,7 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
||||||
pinned: true,
|
pinned: true,
|
||||||
flexibleSpace: DidvanAppBar(appBarData: widget.appBarData!),
|
flexibleSpace: DidvanAppBar(appBarData: widget.appBarData!),
|
||||||
),
|
),
|
||||||
if (widget.children != null)
|
if (widget.children != null && !widget.showSliversFirst)
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
|
|
@ -76,6 +78,16 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
sliver: widget.slivers![i],
|
sliver: widget.slivers![i],
|
||||||
),
|
),
|
||||||
|
if (widget.children != null && widget.showSliversFirst)
|
||||||
|
SliverPadding(
|
||||||
|
padding: widget.padding,
|
||||||
|
sliver: SliverList(
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) => widget.children![index],
|
||||||
|
childCount: widget.children!.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
if (widget.reverse)
|
if (widget.reverse)
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,9 @@ 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 ? 120 : 20,
|
top: centerEmptyState
|
||||||
|
? MediaQuery.of(context).size.height / 4
|
||||||
|
: 20,
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
),
|
),
|
||||||
child: emptyState,
|
child: emptyState,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue