Code refactor & some fix
This commit is contained in:
parent
1340ffa88c
commit
2eb4efe435
26 changed files with 255 additions and 334 deletions
|
|
@ -113,7 +113,7 @@
|
|||
"nsfw_sources_info":"This does not prevent unofficial or potentially incorrectly flagged extensions from surfacing NSFW (18+) content within the app",
|
||||
"version":"Version",
|
||||
"check_for_update":"Check for update",
|
||||
"n_days_ago":"{days} ago",
|
||||
"n_days_ago":"{days} days ago",
|
||||
"today":"Today",
|
||||
"yesterday":"Yesterday",
|
||||
"a_week_ago":"A week ago",
|
||||
|
|
@ -213,6 +213,8 @@
|
|||
"page_preload_amount":"Page preload amount",
|
||||
"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"
|
||||
"add_episodes":"Add Episodes",
|
||||
"select_video_quality":"Select video quality",
|
||||
"select_video_subtitle":"Select video subtitle"
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,5 +213,7 @@
|
|||
"page_preload_amount":"Nombre de page à précharger",
|
||||
"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"
|
||||
"add_episodes":"Ajouter Épisodes",
|
||||
"select_video_quality":"Selectionner une qualité video",
|
||||
"select_video_subtitle":"Selectionner un sous-titrage video"
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -8,7 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart' as riv;
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/video.dart' as vid;
|
||||
import 'package:mangayomi/modules/anime/providers/stream_controller_provider.dart';
|
||||
import 'package:mangayomi/modules/anime/providers/anime_player_controller_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -20,18 +19,18 @@ import 'package:media_kit_video/media_kit_video.dart';
|
|||
import 'package:media_kit_video/media_kit_video_controls/src/controls/extensions/duration.dart';
|
||||
import 'package:media_kit_video/media_kit_video_controls/src/controls/methods/video_state.dart';
|
||||
|
||||
class AnimeStreamView extends riv.ConsumerStatefulWidget {
|
||||
class AnimePlayerView extends riv.ConsumerStatefulWidget {
|
||||
final Chapter episode;
|
||||
const AnimeStreamView({
|
||||
const AnimePlayerView({
|
||||
super.key,
|
||||
required this.episode,
|
||||
});
|
||||
|
||||
@override
|
||||
riv.ConsumerState<AnimeStreamView> createState() => _AnimeStreamViewState();
|
||||
riv.ConsumerState<AnimePlayerView> createState() => _AnimePlayerViewState();
|
||||
}
|
||||
|
||||
class _AnimeStreamViewState extends riv.ConsumerState<AnimeStreamView> {
|
||||
class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||
@override
|
||||
void dispose() {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
|
|
@ -156,11 +155,8 @@ class AnimeStreamPage extends riv.ConsumerStatefulWidget {
|
|||
|
||||
class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
||||
late final Player _player = Player();
|
||||
late final VideoController _controller = VideoController(
|
||||
_player,
|
||||
configuration:
|
||||
const VideoControllerConfiguration(enableHardwareAcceleration: true),
|
||||
);
|
||||
|
||||
late final VideoController _controller = VideoController(_player);
|
||||
|
||||
late final _streamController = AnimeStreamController(episode: widget.episode);
|
||||
|
||||
|
|
@ -169,16 +165,18 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
|||
bool _seekToCurrentPosition = true;
|
||||
late Duration _currentPosition = _streamController.geTCurrentPosition();
|
||||
final _showFitLabel = StateProvider((ref) => false);
|
||||
|
||||
final ValueNotifier<bool> _isCompleted = ValueNotifier(false);
|
||||
final _fit = StateProvider((ref) => BoxFit.contain);
|
||||
final bool _isDesktop =
|
||||
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
|
||||
late StreamSubscription<Duration> _currentPositionSub =
|
||||
_player.stream.position.listen(
|
||||
(Duration position) {
|
||||
(position) {
|
||||
if (_seekToCurrentPosition && _currentPosition != Duration.zero) {
|
||||
_player.seek(_currentPosition);
|
||||
_seekToCurrentPosition = false;
|
||||
_isCompleted.value =
|
||||
_player.state.duration.inSeconds - _currentPosition.inSeconds <= 10;
|
||||
} else {
|
||||
_currentPosition = position;
|
||||
_streamController.setCurrentPosition(position.inMilliseconds);
|
||||
|
|
@ -204,59 +202,58 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
|||
}
|
||||
|
||||
void _onChangeVideoQuality() {
|
||||
log(_player.state.tracks.subtitle.toString());
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => CupertinoActionSheet(
|
||||
title: Text("Select video quality"),
|
||||
actions: List.generate(
|
||||
widget.videos.length,
|
||||
(index) {
|
||||
final quality = widget.videos[index];
|
||||
return CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
quality.quality,
|
||||
style: const TextStyle(),
|
||||
title: Text(l10n.select_video_quality,
|
||||
style: const TextStyle(fontSize: 30)),
|
||||
actions: widget.videos
|
||||
.map((quality) => CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
quality.quality,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _video.value == quality
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _video.value == quality
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_video.value = quality; // change the video quality
|
||||
_player.open(
|
||||
Media(quality.originalUrl, httpHeaders: quality.headers));
|
||||
_seekToCurrentPosition = true;
|
||||
_currentPositionSub = _player.stream.position.listen(
|
||||
(Duration position) {
|
||||
if (_seekToCurrentPosition &&
|
||||
_currentPosition != Duration.zero) {
|
||||
_player.seek(_currentPosition);
|
||||
_seekToCurrentPosition = false;
|
||||
} else {
|
||||
_currentPosition = position;
|
||||
_streamController
|
||||
.setCurrentPosition(position.inMilliseconds);
|
||||
_streamController.setAnimeHistoryUpdate();
|
||||
}
|
||||
onPressed: () {
|
||||
_video.value = quality; // change the video quality
|
||||
_player.open(Media(quality.originalUrl,
|
||||
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(_);
|
||||
},
|
||||
);
|
||||
Navigator.maybePop(_);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () => Navigator.maybePop(_),
|
||||
isDestructiveAction: true,
|
||||
|
|
@ -271,40 +268,38 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> {
|
|||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => CupertinoActionSheet(
|
||||
title: Text("Select sub"),
|
||||
actions: List.generate(
|
||||
_player.state.tracks.subtitle.length,
|
||||
(index) {
|
||||
final subtitle = _player.state.tracks.subtitle[index];
|
||||
return CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
subtitle.title ??
|
||||
subtitle.language ??
|
||||
subtitle.channels ??
|
||||
"N/A",
|
||||
style: const TextStyle(),
|
||||
title: Text(l10n.select_video_subtitle,
|
||||
style: const TextStyle(fontSize: 30)),
|
||||
actions: _player.state.tracks.subtitle
|
||||
.map((subtitle) => CupertinoActionSheetAction(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
subtitle.title ??
|
||||
subtitle.language ??
|
||||
subtitle.channels ??
|
||||
"N/A",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _player.state.track.subtitle == subtitle
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: _player.state.track.subtitle == subtitle
|
||||
? Theme.of(context).iconTheme.color
|
||||
: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_player.setSubtitleTrack(subtitle);
|
||||
Navigator.maybePop(_);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
_player.setSubtitleTrack(subtitle);
|
||||
Navigator.maybePop(_);
|
||||
},
|
||||
))
|
||||
.toList(),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () => Navigator.maybePop(_),
|
||||
isDestructiveAction: true,
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -13,6 +12,7 @@ import 'package:mangayomi/services/search_manga.dart';
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
import 'package:mangayomi/modules/library/search_text_form_field.dart';
|
||||
|
|
@ -230,8 +230,9 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.imageUrl !=
|
||||
null
|
||||
? snapshot.data!.first.imageUrl!
|
||||
: data.imageUrl!,
|
||||
? toImgUrl(
|
||||
snapshot.data!.first.imageUrl!)
|
||||
: toImgUrl(data.imageUrl!),
|
||||
width: 100,
|
||||
height: 140,
|
||||
fit: BoxFit.fill),
|
||||
|
|
|
|||
|
|
@ -490,22 +490,22 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
)),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
shadowColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () {},
|
||||
child: Icon(
|
||||
Icons.download_outlined,
|
||||
color: color,
|
||||
)),
|
||||
),
|
||||
),
|
||||
// Expanded(
|
||||
// child: SizedBox(
|
||||
// height: 70,
|
||||
// child: ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// elevation: 0,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// shadowColor: Colors.transparent,
|
||||
// ),
|
||||
// onPressed: () {},
|
||||
// child: Icon(
|
||||
// Icons.download_outlined,
|
||||
// color: color,
|
||||
// )),
|
||||
// ),
|
||||
// ),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 70,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Future importArchivesFromFile(ImportArchivesFromFileRef ref, Manga? mManga,
|
|||
description: '',
|
||||
isLocalArchive: true,
|
||||
);
|
||||
for (var file in result.files) {
|
||||
for (var file in result.files.reversed.toList()) {
|
||||
(String, LocalExtensionType, Uint8List, String)? data = isManga
|
||||
? await ref.watch(getArchivesDataFromFileProvider(file.path!).future)
|
||||
: null;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class LibraryGridViewWidget extends StatelessWidget {
|
|||
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
entry.imageUrl!.isEmpty ? emptyImg : entry.imageUrl!,
|
||||
toImgUrl(entry.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: entry.source!, lang: entry.lang!)),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -98,9 +98,7 @@ class LibraryListViewWidget extends StatelessWidget {
|
|||
? MemoryImage(entry.customCoverImage
|
||||
as Uint8List) as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
entry.imageUrl!.isEmpty
|
||||
? emptyImg
|
||||
: entry.imageUrl!,
|
||||
toImgUrl(entry.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: entry.source!,
|
||||
lang: entry.lang!)),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ class MainScreen extends ConsumerWidget {
|
|||
final location = ref.watch(
|
||||
routerCurrentLocationStateProvider(context),
|
||||
);
|
||||
bool isReadingScreen = location == '/mangareaderview';
|
||||
bool isReadingScreen =
|
||||
location == '/mangareaderview' || location == '/animePlayerView';
|
||||
int currentIndex = switch (location) {
|
||||
null => 0,
|
||||
'/MangaLibrary' => 0,
|
||||
|
|
@ -178,19 +179,18 @@ class MainScreen extends ConsumerWidget {
|
|||
height: isLongPressed
|
||||
? 0
|
||||
: location == null
|
||||
? 80
|
||||
? null
|
||||
: location != '/MangaLibrary' &&
|
||||
location != '/AnimeLibrary' &&
|
||||
location != '/history' &&
|
||||
location != '/browse' &&
|
||||
location != '/more'
|
||||
? 0
|
||||
: Platform.isIOS? 110:80,
|
||||
: null,
|
||||
child: NavigationBarTheme(
|
||||
data: NavigationBarThemeData(
|
||||
indicatorShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30)),
|
||||
height: 20,
|
||||
),
|
||||
child: NavigationBar(
|
||||
animationDuration: const Duration(milliseconds: 500),
|
||||
|
|
|
|||
|
|
@ -225,9 +225,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
headers: ref.watch(headersProvider(
|
||||
source: widget.manga!.source!,
|
||||
lang: widget.manga!.lang!)),
|
||||
imageUrl: widget.manga!.imageUrl!.isEmpty
|
||||
? emptyImg
|
||||
: widget.manga!.imageUrl!,
|
||||
imageUrl: toImgUrl(widget.manga!.imageUrl!),
|
||||
width: mediaWidth(context, 1),
|
||||
height: 300,
|
||||
fit: BoxFit.cover),
|
||||
|
|
@ -1282,10 +1280,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
final imageProvider = widget.manga!.customCoverImage != null
|
||||
? MemoryImage(widget.manga!.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
widget.manga!.imageUrl!.isEmpty
|
||||
? emptyImg
|
||||
: widget.manga!.imageUrl!,
|
||||
: CachedNetworkImageProvider(toImgUrl(widget.manga!.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: widget.manga!.source!, lang: widget.manga!.lang!)));
|
||||
return Padding(
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
|||
dense: true,
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
value: status,
|
||||
groupValue: toStatus(
|
||||
groupValue: toTrackStatus(
|
||||
widget.trackRes.status,
|
||||
widget.isManga,
|
||||
widget.trackRes.syncId!),
|
||||
|
|
@ -204,7 +204,7 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
|||
});
|
||||
},
|
||||
text: getTrackStatus(
|
||||
toStatus(widget.trackRes.status, widget.isManga,
|
||||
toTrackStatus(widget.trackRes.status, widget.isManga,
|
||||
widget.trackRes.syncId!),
|
||||
context)),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:io';
|
|||
import 'dart:isolate';
|
||||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
// import 'package:image/image.dart';
|
||||
// import 'package:image/image.dart' as img;
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'auto_crop_image_provider.g.dart';
|
||||
|
|
@ -85,86 +85,87 @@ class CropBorderClass {
|
|||
}
|
||||
|
||||
void _autocropImageIsolate(CropBorderClass cropData) async {
|
||||
// Image? croppedImage;
|
||||
// // Image? image = decodeImage(cropData.image!);
|
||||
// // final old = image;
|
||||
// // image = copyCrop(image!, 0, 0, image.width, image.height);
|
||||
// img.Image? croppedImage;
|
||||
// img.Image? image = img.decodeImage(cropData.image!);
|
||||
// final old = image;
|
||||
// image = img.copyCrop(image!,
|
||||
// x: 0, y: 0, width: image.width, height: image.height);
|
||||
|
||||
// // int left = 0;
|
||||
// // int top = 0;
|
||||
// // int right = image.width - 1;
|
||||
// // int bottom = image.height - 1;
|
||||
// int left = 0;
|
||||
// int top = 0;
|
||||
// int right = image.width - 1;
|
||||
// int bottom = image.height - 1;
|
||||
|
||||
// // // Find left coordinate
|
||||
// // for (int x = 0; x < image.width; x++) {
|
||||
// // bool stop = false;
|
||||
// // for (int y = 0; y < image.height; y++) {
|
||||
// // if (image.getPixel(x, y) != getColor(255, 255, 255, 255)) {
|
||||
// // stop = true;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // if (stop) {
|
||||
// // left = x;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // Find left coordinate
|
||||
// for (int x = 0; x < image.width; x++) {
|
||||
// bool stop = false;
|
||||
// for (int y = 0; y < image.height; y++) {
|
||||
// if (image.getPixel(x, y) != image.getColor(255, 255, 255, 255)) {
|
||||
// stop = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (stop) {
|
||||
// left = x;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // // Find top coordinate
|
||||
// // for (int y = 0; y < image.height; y++) {
|
||||
// // bool stop = false;
|
||||
// // for (int x = 0; x < image.width; x++) {
|
||||
// // if (image.getPixel(x, y) != getColor(255, 255, 255, 255)) {
|
||||
// // stop = true;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // if (stop) {
|
||||
// // top = y;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // Find top coordinate
|
||||
// for (int y = 0; y < image.height; y++) {
|
||||
// bool stop = false;
|
||||
// for (int x = 0; x < image.width; x++) {
|
||||
// if (image.getPixel(x, y) != image.getColor(255, 255, 255, 255)) {
|
||||
// stop = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (stop) {
|
||||
// top = y;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // // Find right coordinate
|
||||
// // for (int x = image.width - 1; x >= 0; x--) {
|
||||
// // bool stop = false;
|
||||
// // for (int y = 0; y < image.height; y++) {
|
||||
// // if (image.getPixel(x, y) != getColor(255, 255, 255, 255)) {
|
||||
// // stop = true;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // if (stop) {
|
||||
// // right = x;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // Find right coordinate
|
||||
// for (int x = image.width - 1; x >= 0; x--) {
|
||||
// bool stop = false;
|
||||
// for (int y = 0; y < image.height; y++) {
|
||||
// if (image.getPixel(x, y) != image.getColor(255, 255, 255, 255)) {
|
||||
// stop = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (stop) {
|
||||
// right = x;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // // Find bottom coordinate
|
||||
// // for (int y = image.height - 1; y >= 0; y--) {
|
||||
// // bool stop = false;
|
||||
// // for (int x = 0; x < image.width; x++) {
|
||||
// // if (image.getPixel(x, y) != getColor(255, 255, 255, 255)) {
|
||||
// // stop = true;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // if (stop) {
|
||||
// // bottom = y;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
// // Find bottom coordinate
|
||||
// for (int y = image.height - 1; y >= 0; y--) {
|
||||
// bool stop = false;
|
||||
// for (int x = 0; x < image.width; x++) {
|
||||
// if (image.getPixel(x, y) != image.getColor(255, 255, 255, 255)) {
|
||||
// stop = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (stop) {
|
||||
// bottom = y;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // // Crop the image
|
||||
// // croppedImage = copyCrop(
|
||||
// // image,
|
||||
// // left,
|
||||
// // top,
|
||||
// // right - left + 1,
|
||||
// // bottom - top + 1,
|
||||
// // );
|
||||
// // Crop the image
|
||||
// croppedImage = img.copyCrop(
|
||||
// image,
|
||||
// x: left,
|
||||
// y: top,
|
||||
// width: right - left + 1,
|
||||
// height: bottom - top + 1,
|
||||
// );
|
||||
// if (old != croppedImage) {
|
||||
// cropData.sendPort.send(encodeJpg(croppedImage) as Uint8List);
|
||||
// cropData.sendPort.send(img.encodeJpg(croppedImage));
|
||||
// } else {
|
||||
// cropData.sendPort.send(null);
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ pushMangaReaderView({
|
|||
if (chapter.manga.value!.isManga!) {
|
||||
context.push('/mangareaderview', extra: chapter);
|
||||
} else {
|
||||
context.push('/animestreamview', extra: chapter);
|
||||
context.push('/animePlayerView', extra: chapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,6 @@ pushReplacementMangaReaderView({
|
|||
if (chapter.manga.value!.isManga!) {
|
||||
context.pushReplacement('/mangareaderview', extra: chapter);
|
||||
} else {
|
||||
context.pushReplacement('/animestreamview', extra: chapter);
|
||||
context.pushReplacement('/animePlayerView', extra: chapter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ BoxFit getBoxFit(ScaleType scaleType) {
|
|||
ScaleType.fitScreen => BoxFit.contain,
|
||||
ScaleType.originalSize => BoxFit.cover,
|
||||
ScaleType.smartFit => BoxFit.contain,
|
||||
_ => BoxFit.none
|
||||
_ => BoxFit.fill
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
|||
import 'package:mangayomi/services/get_chapter_url.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/image_detail_info.dart';
|
||||
import 'package:mangayomi/utils/media_query.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_center.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_vertical.dart';
|
||||
|
|
@ -453,10 +452,11 @@ class _MangaChapterPageGalleryState
|
|||
// if (!isOk) {
|
||||
// isOk = true;
|
||||
// _cropImagesList = await ref.watch(autoCropBorderProvider(
|
||||
// archiveImages: _chapterUrlModel.archiveImages,
|
||||
// isLocaleList: _chapterUrlModel.isLocaleList,
|
||||
// path: _chapterUrlModel.path!,
|
||||
// url: _chapterUrlModel.pageUrls)
|
||||
// archiveImages:
|
||||
// _uChapDataPreload.map((e) => e.archiveImage).toList(),
|
||||
// isLocaleList: _uChapDataPreload.map((e) => e.isLocale!).toList(),
|
||||
// path: _uChapDataPreload[_currentIndex!].path!,
|
||||
// url: _uChapDataPreload.map((e) => e.url!).toList())
|
||||
// .future);
|
||||
// if (mounted) {
|
||||
// setState(() {});
|
||||
|
|
@ -883,9 +883,9 @@ class _MangaChapterPageGalleryState
|
|||
return IconButton(
|
||||
onPressed: () {
|
||||
// _cropImage();
|
||||
ref
|
||||
.read(cropBordersStateProvider.notifier)
|
||||
.set(!cropBorders);
|
||||
// ref
|
||||
// .read(cropBordersStateProvider.notifier)
|
||||
// .set(!cropBorders);
|
||||
},
|
||||
icon: Stack(
|
||||
children: [
|
||||
|
|
@ -1103,7 +1103,6 @@ class _MangaChapterPageGalleryState
|
|||
|
||||
final StreamController<double> _rebuildDetail =
|
||||
StreamController<double>.broadcast();
|
||||
final Map<int, ImageDetailInfo> detailKeys = <int, ImageDetailInfo>{};
|
||||
late AnimationController _doubleClickAnimationController;
|
||||
|
||||
Animation<double>? _doubleClickAnimation;
|
||||
|
|
@ -1375,37 +1374,18 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
return Container();
|
||||
},
|
||||
initGestureConfigHandler:
|
||||
(ExtendedImageState state) {
|
||||
double? initialScale = 1.0;
|
||||
final size = MediaQuery.of(context).size;
|
||||
if (state.extendedImageInfo != null) {
|
||||
initialScale = initScale(
|
||||
size: size,
|
||||
initialScale: initialScale,
|
||||
imageSize: Size(
|
||||
state.extendedImageInfo!.image
|
||||
.width
|
||||
.toDouble(),
|
||||
state.extendedImageInfo!.image
|
||||
.height
|
||||
.toDouble()));
|
||||
}
|
||||
initGestureConfigHandler: (state) {
|
||||
return GestureConfig(
|
||||
inertialSpeed: 200,
|
||||
inPageView: true,
|
||||
initialScale: initialScale!,
|
||||
maxScale: 8,
|
||||
animationMaxScale: 8,
|
||||
initialAlignment:
|
||||
InitialAlignment.center,
|
||||
cacheGesture: true,
|
||||
hitTestBehavior:
|
||||
HitTestBehavior.translucent,
|
||||
);
|
||||
},
|
||||
onDoubleTap:
|
||||
(ExtendedImageGestureState state) {
|
||||
onDoubleTap: (state) {
|
||||
final Offset? pointerDownPosition =
|
||||
state.pointerDownPosition;
|
||||
final double? begin =
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ List<String> getScaleTypeNames(BuildContext context) {
|
|||
final l10n = l10nLocalizations(context)!;
|
||||
return [
|
||||
l10n.scale_type_fit_screen,
|
||||
// l10n.scale_type_stretch,
|
||||
l10n.scale_type_stretch,
|
||||
l10n.scale_type_fit_width,
|
||||
l10n.scale_type_fit_height,
|
||||
// l10n.scale_type_original_size,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import 'package:mangayomi/models/settings.dart';
|
|||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/modules/widgets/bottom_text_widget.dart';
|
||||
import 'package:mangayomi/modules/widgets/cover_view_widget.dart';
|
||||
|
|
@ -48,8 +49,8 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.imageUrl != null
|
||||
? snapshot.data!.first.imageUrl!
|
||||
: getMangaDetail!.imageUrl!,
|
||||
? toImgUrl(snapshot.data!.first.imageUrl!)
|
||||
: toImgUrl(getMangaDetail!.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: getMangaDetail!.source!,
|
||||
lang: getMangaDetail!.lang!)),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/anime/anime_stream_view.dart';
|
||||
import 'package:mangayomi/modules/anime/anime_player_view.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/extension_detail.dart';
|
||||
import 'package:mangayomi/modules/browse/sources/sources_filter_screen.dart';
|
||||
import 'package:mangayomi/modules/more/categories/categories_screen.dart';
|
||||
|
|
@ -190,11 +190,11 @@ class RouterNotifier extends ChangeNotifier {
|
|||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/animestreamview",
|
||||
name: "animestreamview",
|
||||
path: "/animePlayerView",
|
||||
name: "animePlayerView",
|
||||
builder: (context, state) {
|
||||
final episode = state.extra as Chapter;
|
||||
return AnimeStreamView(
|
||||
return AnimePlayerView(
|
||||
episode: episode,
|
||||
);
|
||||
},
|
||||
|
|
@ -202,7 +202,7 @@ class RouterNotifier extends ChangeNotifier {
|
|||
final episode = state.extra as Chapter;
|
||||
return CustomTransition(
|
||||
key: state.pageKey,
|
||||
child: AnimeStreamView(
|
||||
child: AnimePlayerView(
|
||||
episode: episode,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,32 +19,30 @@ Future<List<Video>> getAnimeServers(
|
|||
if (episode.manga.value!.isLocalArchive!) {
|
||||
return [Video(episode.archivePath!, episode.name!, episode.archivePath!)];
|
||||
}
|
||||
if (!episode.manga.value!.isLocalArchive!) {
|
||||
final source =
|
||||
getSource(episode.manga.value!.lang!, episode.manga.value!.source!);
|
||||
final source =
|
||||
getSource(episode.manga.value!.lang!, episode.manga.value!.source!);
|
||||
|
||||
final bytecode = compilerEval(source!.sourceCode!);
|
||||
final bytecode = compilerEval(source!.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
lang: source.lang,
|
||||
link: episode.url,
|
||||
baseUrl: source.baseUrl,
|
||||
source: source.name,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
))
|
||||
];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart', 'getVideoList');
|
||||
if (res is $List) {
|
||||
video = res.$reified
|
||||
.map(
|
||||
(e) => Video(e.url, e.quality, e.originalUrl, headers: e.headers),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
lang: source.lang,
|
||||
link: episode.url,
|
||||
baseUrl: source.baseUrl,
|
||||
source: source.name,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
))
|
||||
];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart', 'getVideoList');
|
||||
if (res is $List) {
|
||||
video = res.$reified
|
||||
.map(
|
||||
(e) => Video(e.url, e.quality, e.originalUrl, headers: e.headers),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
return video;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_latest_updates_manga.g.dart';
|
||||
|
||||
|
|
@ -41,7 +40,7 @@ Future<List<MangaModel?>> getLatestUpdatesManga(
|
|||
MangaModel newMangaa = MangaModel(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? emptyImg : value.images![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
baseUrl: value.baseUrl,
|
||||
apiUrl: value.apiUrl,
|
||||
lang: value.lang,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_popular_manga.g.dart';
|
||||
|
||||
|
|
@ -41,7 +40,7 @@ Future<List<MangaModel?>> getPopularManga(
|
|||
MangaModel newMangaa = MangaModel(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? emptyImg : value.images![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
baseUrl: value.baseUrl,
|
||||
apiUrl: value.apiUrl,
|
||||
lang: value.lang,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'search_manga.g.dart';
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ Future<List<MangaModel?>> searchManga(
|
|||
MangaModel newMangaa = MangaModel(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? emptyImg : value.images![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
baseUrl: value.baseUrl,
|
||||
apiUrl: value.apiUrl,
|
||||
lang: value.lang,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ String getTrackStatus(TrackStatus status, BuildContext context) {
|
|||
};
|
||||
}
|
||||
|
||||
TrackStatus toStatus(TrackStatus status, bool isManga, int syncId) {
|
||||
TrackStatus toTrackStatus(TrackStatus status, bool isManga, int syncId) {
|
||||
return !isManga && syncId == 2
|
||||
? switch (status) {
|
||||
TrackStatus.reading => TrackStatus.watching,
|
||||
|
|
@ -62,5 +62,9 @@ TrackStatus toStatus(TrackStatus status, bool isManga, int syncId) {
|
|||
};
|
||||
}
|
||||
|
||||
const emptyImg =
|
||||
String toImgUrl(String url) {
|
||||
return url.isEmpty ? _emptyImg : url;
|
||||
}
|
||||
|
||||
const _emptyImg =
|
||||
"https://upload.wikimedia.org/wikipedia/commons/1/12/White_background.png";
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
import 'dart:math';
|
||||
import 'package:flutter/material.dart' hide Image;
|
||||
|
||||
class ImageDetailInfo {
|
||||
ImageDetailInfo({
|
||||
required this.imageDRect,
|
||||
required this.pageSize,
|
||||
required this.imageInfo,
|
||||
});
|
||||
final GlobalKey<State<StatefulWidget>> key = GlobalKey<State>();
|
||||
|
||||
final Rect imageDRect;
|
||||
|
||||
final Size pageSize;
|
||||
|
||||
final ImageInfo imageInfo;
|
||||
|
||||
double? _maxImageDetailY;
|
||||
double get imageBottom => imageDRect.bottom - 20;
|
||||
double get maxImageDetailY {
|
||||
try {
|
||||
//
|
||||
return _maxImageDetailY ??= max(
|
||||
key.currentContext!.size!.height - (pageSize.height - imageBottom),
|
||||
0.1);
|
||||
} catch (e) {
|
||||
//currentContext is not ready
|
||||
return 100.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double? initScale({
|
||||
required Size imageSize,
|
||||
required Size size,
|
||||
double? initialScale,
|
||||
}) {
|
||||
final double n1 = imageSize.height / imageSize.width;
|
||||
final double n2 = size.height / size.width;
|
||||
if (n1 > n2) {
|
||||
final FittedSizes fittedSizes =
|
||||
applyBoxFit(BoxFit.contain, imageSize, size);
|
||||
final Size destinationSize = fittedSizes.destination;
|
||||
return size.width / destinationSize.width;
|
||||
} else if (n1 / n2 < 1 / 4) {
|
||||
final FittedSizes fittedSizes =
|
||||
applyBoxFit(BoxFit.contain, imageSize, size);
|
||||
final Size destinationSize = fittedSizes.destination;
|
||||
return size.height / destinationSize.height;
|
||||
}
|
||||
|
||||
return initialScale;
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ dependencies:
|
|||
archive: ^3.3.7
|
||||
file_picker: ^5.3.3
|
||||
path_provider: ^2.1.0
|
||||
# image: ^3.3.0
|
||||
# image: ^4.0.17
|
||||
scrollable_positioned_list: ^0.3.5
|
||||
dart_eval: ^0.6.0
|
||||
json_path: ^0.6.2
|
||||
|
|
|
|||
Loading…
Reference in a new issue