Improve +
This commit is contained in:
parent
0c9f1d74a3
commit
64b37ad17e
9 changed files with 215 additions and 132 deletions
|
|
@ -214,8 +214,8 @@
|
|||
"page_preload_amount_subtitle":"The amount of pages to preload when reading. Higher values will result in a smoother reading experience, at the cost of higher cache and network usage.",
|
||||
"image_loading_error":"This image couldn't be loaded",
|
||||
"add_episodes":"Add Episodes",
|
||||
"select_video_quality":"Select video quality",
|
||||
"select_video_subtitle":"Select video subtitle",
|
||||
"change_video_quality":"Change video quality",
|
||||
"change_video_subtitle":"Change video subtitle",
|
||||
"check_for_extension_updates":"Check for extension updates",
|
||||
"auto_extensions_updates":"Auto extension updates",
|
||||
"auto_extensions_updates_subtitle":"Will automatically update the extension when a new version is available.",
|
||||
|
|
|
|||
|
|
@ -214,8 +214,8 @@
|
|||
"page_preload_amount_subtitle":"Le nombre de pages à précharger pendant la lecture. De plus grandes valeurs rendront la lecture plus fluide au coût d'un plus grand cache et d'une plus grande utilisation de données.",
|
||||
"image_loading_error":"L'image n'a pas pu être chargée",
|
||||
"add_episodes":"Ajouter Épisodes",
|
||||
"select_video_quality":"Selectionner une qualité video",
|
||||
"select_video_subtitle":"Selectionner un sous-titrage video",
|
||||
"change_video_quality":"Changer de qualité video",
|
||||
"change_video_subtitle":"Changer de sous-titrage video",
|
||||
"check_for_extension_updates":"Vérifier les mise à jour d'extensions",
|
||||
"auto_extensions_updates":"Mises à jour auto des extensions",
|
||||
"auto_extensions_updates_subtitle":"Mettra automatiquement à jour l'extension lorsqu'une nouvelle version est disponible.",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:draggable_menu/draggable_menu.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
|
@ -235,82 +236,110 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
|||
}
|
||||
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => CupertinoActionSheet(
|
||||
title: Text(l10n.select_video_quality,
|
||||
style: const TextStyle(fontSize: 30)),
|
||||
actions: videoQuality
|
||||
.map((quality) => CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Text(l10n.change_video_quality,
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge!
|
||||
.color!
|
||||
.withOpacity(0.8)),
|
||||
textAlign: TextAlign.center),
|
||||
),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
quality.isLocal && !widget.isLocal
|
||||
? "${_firstVid.quality} ${quality.videoTrack!.h}p"
|
||||
: widget.isLocal
|
||||
? _firstVid.quality
|
||||
: quality.videoTrack!.title!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: quality.isLocal &&
|
||||
!widget.isLocal &&
|
||||
"${quality.videoTrack!.title}${quality.videoTrack!.h}p" ==
|
||||
"${_video.value!.videoTrack!.title}${_video.value!.videoTrack!.h}p" ||
|
||||
"${_video.value!.videoTrack!.id}${_video.value!.videoTrack!.title}" ==
|
||||
"${quality.videoTrack!.id}${quality.videoTrack!.title}"
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
...videoQuality
|
||||
.map((quality) => TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(0))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
quality.isLocal && !widget.isLocal
|
||||
? "${_firstVid.quality} ${quality.videoTrack!.h}p"
|
||||
: widget.isLocal
|
||||
? _firstVid.quality
|
||||
: quality.videoTrack!.title!,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge!
|
||||
.color),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: quality.isLocal &&
|
||||
!widget.isLocal &&
|
||||
"${quality.videoTrack!.title}${quality.videoTrack!.h}p" ==
|
||||
"${_video.value!.videoTrack!.title}${_video.value!.videoTrack!.h}p" ||
|
||||
"${_video.value!.videoTrack!.id}${_video.value!.videoTrack!.title}" ==
|
||||
"${quality.videoTrack!.id}${quality.videoTrack!.title}"
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_video.value =
|
||||
quality; // change the video quality
|
||||
if (quality.isLocal) {
|
||||
if (widget.isLocal) {
|
||||
_player
|
||||
.setVideoTrack(quality.videoTrack!);
|
||||
} else {
|
||||
_player.open(Media(quality.videoTrack!.id,
|
||||
httpHeaders: quality.headers));
|
||||
}
|
||||
} else {
|
||||
_player.open(Media(quality.videoTrack!.id,
|
||||
httpHeaders: quality.headers));
|
||||
}
|
||||
_seekToCurrentPosition = true;
|
||||
_currentPositionSub =
|
||||
_player.stream.position.listen(
|
||||
(position) {
|
||||
if (_seekToCurrentPosition &&
|
||||
_currentPosition != Duration.zero) {
|
||||
_player.seek(_currentPosition);
|
||||
_seekToCurrentPosition = false;
|
||||
} else {
|
||||
_currentPosition = position;
|
||||
_streamController.setCurrentPosition(
|
||||
position.inMilliseconds);
|
||||
_streamController
|
||||
.setAnimeHistoryUpdate();
|
||||
}
|
||||
},
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
))
|
||||
.toList()
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_video.value = quality; // change the video quality
|
||||
if (quality.isLocal) {
|
||||
if (widget.isLocal) {
|
||||
_player.setVideoTrack(quality.videoTrack!);
|
||||
} else {
|
||||
_player.open(Media(quality.videoTrack!.id,
|
||||
httpHeaders: quality.headers));
|
||||
}
|
||||
} else {
|
||||
_player.open(Media(quality.videoTrack!.id,
|
||||
httpHeaders: quality.headers));
|
||||
}
|
||||
_seekToCurrentPosition = true;
|
||||
_currentPositionSub = _player.stream.position.listen(
|
||||
(position) {
|
||||
if (_seekToCurrentPosition &&
|
||||
_currentPosition != Duration.zero) {
|
||||
_player.seek(_currentPosition);
|
||||
_seekToCurrentPosition = false;
|
||||
} else {
|
||||
_currentPosition = position;
|
||||
_streamController
|
||||
.setCurrentPosition(position.inMilliseconds);
|
||||
_streamController.setAnimeHistoryUpdate();
|
||||
}
|
||||
},
|
||||
);
|
||||
Navigator.maybePop(_);
|
||||
},
|
||||
))
|
||||
.toList(),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () => Navigator.maybePop(_),
|
||||
isDestructiveAction: true,
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
void _onChangeVideoSubtitle() {
|
||||
|
|
@ -334,51 +363,77 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
|||
}
|
||||
_subtitle.value ??= videoSubtitle.first;
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => CupertinoActionSheet(
|
||||
title: Text(l10n.select_video_subtitle,
|
||||
style: const TextStyle(fontSize: 30)),
|
||||
actions: videoSubtitle
|
||||
.map((subtitle) => CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Text(l10n.change_video_subtitle,
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge!
|
||||
.color!
|
||||
.withOpacity(0.8)),
|
||||
textAlign: TextAlign.center),
|
||||
),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
subtitle.subtitle!.title ??
|
||||
subtitle.subtitle!.language ??
|
||||
subtitle.subtitle!.channels ??
|
||||
"N/A",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _subtitle.value != null &&
|
||||
"${_subtitle.value!.subtitle!.id}${_subtitle.value!.subtitle!.title}${_subtitle.value!.subtitle!.language}" ==
|
||||
"${subtitle.subtitle!.id}${subtitle.subtitle!.title}${subtitle.subtitle!.language}"
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
...videoSubtitle
|
||||
.map((subtitle) => TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(0))),
|
||||
onPressed: () {
|
||||
_subtitle.value = subtitle;
|
||||
_player.setSubtitleTrack(subtitle.subtitle!);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
subtitle.subtitle!.title ??
|
||||
subtitle.subtitle!.language ??
|
||||
subtitle.subtitle!.channels ??
|
||||
"N/A",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge!
|
||||
.color),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _subtitle.value != null &&
|
||||
"${_subtitle.value!.subtitle!.id}${_subtitle.value!.subtitle!.title}${_subtitle.value!.subtitle!.language}" ==
|
||||
"${subtitle.subtitle!.id}${subtitle.subtitle!.title}${subtitle.subtitle!.language}"
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_subtitle.value = subtitle;
|
||||
_player.setSubtitleTrack(subtitle.subtitle!);
|
||||
Navigator.maybePop(_);
|
||||
},
|
||||
))
|
||||
.toList(),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () => Navigator.maybePop(_),
|
||||
isDestructiveAction: true,
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
),
|
||||
);
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
Future<void> _setPlaybackSpeed(double speed) async {
|
||||
|
|
@ -804,3 +859,15 @@ class VideoPrefs {
|
|||
VideoPrefs(
|
||||
{this.videoTrack, this.isLocal = true, this.headers, this.subtitle});
|
||||
}
|
||||
|
||||
_showDrag(Widget child) {
|
||||
DraggableMenu(
|
||||
ui: SoftModernDraggableMenu(barItem: Container(), radius: 20),
|
||||
minimizeThreshold: 0.6,
|
||||
levels: [
|
||||
DraggableMenuLevel.ratio(ratio: 1.5 / 3),
|
||||
],
|
||||
minimizeBeforeFastDrag: true,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1716,7 +1716,9 @@ _importLocal(BuildContext context, bool isManga) {
|
|||
});
|
||||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
isManga: isManga, null)
|
||||
isManga: isManga,
|
||||
null,
|
||||
init: true)
|
||||
.future);
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part 'local_archive.g.dart';
|
|||
|
||||
@riverpod
|
||||
Future importArchivesFromFile(ImportArchivesFromFileRef ref, Manga? mManga,
|
||||
{required bool isManga}) async {
|
||||
{required bool isManga, required bool init}) async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: true,
|
||||
type: FileType.custom,
|
||||
|
|
@ -44,7 +44,11 @@ Future importArchivesFromFile(ImportArchivesFromFileRef ref, Manga? mManga,
|
|||
? await ref.watch(getArchivesDataFromFileProvider(file.path!).future)
|
||||
: null;
|
||||
String name = _getName(file.path!);
|
||||
manga.customCoverImage = isManga ? data!.$3 : null;
|
||||
|
||||
if (init) {
|
||||
manga.customCoverImage = isManga ? data!.$3 : null;
|
||||
}
|
||||
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.putSync(manga);
|
||||
final chapters = Chapter(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'local_archive.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$importArchivesFromFileHash() =>
|
||||
r'421b9f4f54cd22968cfc6447f174470712d684fc';
|
||||
r'25ff2ca889a31d482a95af7cb9be8ebd9cf0dc89';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -45,10 +45,12 @@ class ImportArchivesFromFileFamily extends Family<AsyncValue<dynamic>> {
|
|||
ImportArchivesFromFileProvider call(
|
||||
Manga? mManga, {
|
||||
required bool isManga,
|
||||
required bool init,
|
||||
}) {
|
||||
return ImportArchivesFromFileProvider(
|
||||
mManga,
|
||||
isManga: isManga,
|
||||
init: init,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +61,7 @@ class ImportArchivesFromFileFamily extends Family<AsyncValue<dynamic>> {
|
|||
return call(
|
||||
provider.mManga,
|
||||
isManga: provider.isManga,
|
||||
init: provider.init,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -84,11 +87,13 @@ class ImportArchivesFromFileProvider
|
|||
ImportArchivesFromFileProvider(
|
||||
this.mManga, {
|
||||
required this.isManga,
|
||||
required this.init,
|
||||
}) : super.internal(
|
||||
(ref) => importArchivesFromFile(
|
||||
ref,
|
||||
mManga,
|
||||
isManga: isManga,
|
||||
init: init,
|
||||
),
|
||||
from: importArchivesFromFileProvider,
|
||||
name: r'importArchivesFromFileProvider',
|
||||
|
|
@ -103,12 +108,14 @@ class ImportArchivesFromFileProvider
|
|||
|
||||
final Manga? mManga;
|
||||
final bool isManga;
|
||||
final bool init;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is ImportArchivesFromFileProvider &&
|
||||
other.mManga == mManga &&
|
||||
other.isManga == isManga;
|
||||
other.isManga == isManga &&
|
||||
other.init == init;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -116,6 +123,7 @@ class ImportArchivesFromFileProvider
|
|||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, mManga.hashCode);
|
||||
hash = _SystemHash.combine(hash, isManga.hashCode);
|
||||
hash = _SystemHash.combine(hash, init.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
import 'package:mangayomi/models/track_preference.dart';
|
||||
import 'package:mangayomi/models/track_search.dart';
|
||||
|
|
@ -21,6 +20,7 @@ import 'package:mangayomi/modules/library/providers/local_archive.dart';
|
|||
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/tracker_search_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/tracker_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
|
@ -508,7 +508,8 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
isManga: widget
|
||||
.manga!
|
||||
.isManga!,
|
||||
widget.manga)
|
||||
widget.manga,
|
||||
init: false)
|
||||
.future);
|
||||
},
|
||||
)
|
||||
|
|
@ -1112,7 +1113,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
right: 0,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
_editLocaleArchiveInfos();
|
||||
_editLocalArchiveInfos();
|
||||
},
|
||||
icon: const CircleAvatar(
|
||||
child: Icon(Icons.edit_outlined))))
|
||||
|
|
@ -1254,7 +1255,8 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
isManga: widget.manga!.isManga!,
|
||||
widget.manga)
|
||||
widget.manga,
|
||||
init: false)
|
||||
.future);
|
||||
},
|
||||
)
|
||||
|
|
@ -1570,7 +1572,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
});
|
||||
}
|
||||
|
||||
_editLocaleArchiveInfos() {
|
||||
_editLocalArchiveInfos() {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
TextEditingController? name =
|
||||
TextEditingController(text: widget.manga!.name!);
|
||||
|
|
@ -1659,7 +1661,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
child: Material(
|
||||
color: isLight(context)
|
||||
? Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9)
|
||||
: !isar.settings.getSync(227)!.pureBlackDarkMode!
|
||||
: !ref.watch(pureBlackDarkModeStateProvider)
|
||||
? Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9)
|
||||
: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||
? Colors.black
|
||||
: Colors.white,
|
||||
fit: BoxFit.fill,
|
||||
height: 130,
|
||||
height: 100,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class MoreScreen extends StatelessWidget {
|
|||
? Colors.black
|
||||
: Colors.white,
|
||||
fit: BoxFit.fill,
|
||||
height: 130,
|
||||
height: 100,
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue