Compare commits

..

9 Commits

Author SHA1 Message Date
8ca0a7785f Fix alt_store workflow 2025-10-12 19:57:28 +08:00
0eb5d76687 fix android back gesture. Close #544 2025-10-12 19:49:33 +08:00
29d25f7fcd Update version code 2025-10-12 16:47:08 +08:00
7d60e78f27 ignore empty archive link 2025-10-12 16:44:13 +08:00
nyne
e93b56a008 Add Inno Setup installation to workflow 2025-10-09 22:06:21 +08:00
nyne
d10873a903 Update update_alt_store.yml 2025-10-09 21:39:42 +08:00
nyne
2d27f7d650 Merge pull request #541 from venera-app/v1.5.2-dev
V1.5.2
2025-10-08 20:06:56 +08:00
nyne
5a76a10fb2 Merge pull request #537 from lings03/master
Fix some issue when save or share image in reader.
2025-10-07 15:21:50 +08:00
角砂糖
f09e766a8a Fix some issue when save or share image in reader.
1. Change the image name with comic name and real index
2. Fix wrong equal check
3. Fix wrong selection when image per page > 1 and show single image in first page
2025-10-07 01:19:59 +08:00
9 changed files with 114 additions and 53 deletions

View File

@@ -116,6 +116,8 @@ jobs:
run: |
choco install yq -y
pip install httpx
- name: Install Inno Setup
run: choco install innosetup --no-progress
- uses: subosito/flutter-action@v2
with:
channel: "stable"

View File

@@ -31,19 +31,30 @@ jobs:
- name: Update AltStore source
id: update_source
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.ACTION_GITHUB_TOKEN }}
run: |
python update_alt_store.py
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add alt_store.json
if git diff --staged --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
git commit -m "Updated source with latest release"
git push
echo "changes=true" >> $GITHUB_OUTPUT
fi
python update_alt_store.py
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add alt_store.json
if git diff --staged --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
# Create a new branch for the PR
branch_name="update-altstore-$(date +%Y%m%d-%H%M%S)"
git checkout -b "$branch_name"
git commit -m "Updated source with latest release"
git push -u origin "$branch_name"
# Create PR using GitHub CLI
gh pr create \
--title "Update AltStore source with latest release" \
--body "This PR updates the alt_store.json file with the latest release information." \
--head "$branch_name" \
--base main
echo "changes=true" >> $GITHUB_OUTPUT
fi
- name: Calculate job duration
id: duration

View File

@@ -13,7 +13,7 @@ export "widget_utils.dart";
export "context.dart";
class _App {
final version = "1.5.2";
final version = "1.5.3";
bool get isAndroid => Platform.isAndroid;

View File

@@ -128,7 +128,7 @@ mixin _AppRouteTransitionMixin<T> on PageRoute<T> {
context,
animation,
secondaryAnimation,
enableIOSGesture
enableIOSGesture && App.isIOS
? IOSBackGestureDetector(
gestureWidth: _kBackGestureWidth,
enabledCallback: () => _isPopGestureEnabled<T>(this),
@@ -302,7 +302,7 @@ class _IOSBackGestureDetectorState extends State<IOSBackGestureDetector> {
assert(mounted);
assert(_backGestureController != null);
_backGestureController!.dragUpdate(
_convertToLogical(details.primaryDelta! / context.size!.width));
_convertToLogical(details.primaryDelta! / context.size!.width));
}
}

View File

@@ -237,10 +237,12 @@ abstract mixin class _ComicPageActions {
isGettingLink = false;
});
} else if (context.mounted) {
LocalManager()
if (res.data.isNotEmpty) {
LocalManager()
.addTask(ArchiveDownloadTask(res.data, comic));
App.rootContext
App.rootContext
.showMessage(message: "Download started".tl);
}
context.pop();
}
},

View File

@@ -140,12 +140,12 @@ class _GalleryModeState extends State<_GalleryMode>
int get totalPages {
if (!reader.showSingleImageOnFirstPage()) {
return (reader.images!.length /
reader.imagesPerPage())
reader.imagesPerPage)
.ceil();
} else {
return 1 +
((reader.images!.length - 1) /
reader.imagesPerPage())
reader.imagesPerPage)
.ceil();
}
}
@@ -169,7 +169,7 @@ class _GalleryModeState extends State<_GalleryMode>
/// Get the range of images for the given page. [page] is 1-based.
(int start, int end) getPageImagesRange(int page) {
var imagesPerPage = reader.imagesPerPage();
var imagesPerPage = reader.imagesPerPage;
if (reader.showSingleImageOnFirstPage()) {
if (page == 1) {
return (0, 1);
@@ -191,6 +191,16 @@ class _GalleryModeState extends State<_GalleryMode>
}
}
/// Get the image indices for current page. Returns null if no images.
/// Returns a single index if only one image, or a range if multiple images.
(int, int)? getCurrentPageImageRange() {
if (reader.images == null || reader.images!.isEmpty) {
return null;
}
var (startIndex, endIndex) = getPageImagesRange(reader.page);
return (startIndex, endIndex);
}
/// [cache] is used to cache the images.
/// The count of images to cache is determined by the [preCacheCount] setting.
/// For previous page and next page, it will do a memory cache.
@@ -259,7 +269,7 @@ class _GalleryModeState extends State<_GalleryMode>
photoViewControllers[index] ??= PhotoViewController();
if (reader.imagesPerPage() == 1 ||
if (reader.imagesPerPage == 1 ||
pageImages.length == 1) {
return PhotoViewGalleryPageOptions(
filterQuality: FilterQuality.medium,
@@ -533,17 +543,27 @@ class _GalleryModeState extends State<_GalleryMode>
@override
String? getImageKeyByOffset(Offset offset) {
String? imageKey;
if (reader.imagesPerPage() == 1) {
imageKey = reader.images![reader.page - 1];
} else {
for (var imageState in imageStates) {
if ((imageState as _ComicImageState).containsPoint(offset)) {
imageKey = (imageState.widget.image as ReaderImageProvider).imageKey;
var range = getCurrentPageImageRange();
if (range == null) return null;
var (startIndex, endIndex) = range;
int actualImageCount = endIndex - startIndex;
if (actualImageCount == 1) {
return reader.images![startIndex];
}
for (var imageState in imageStates) {
if ((imageState as _ComicImageState).containsPoint(offset)) {
var imageKey = (imageState.widget.image as ReaderImageProvider).imageKey;
int index = reader.images!.indexOf(imageKey);
if (index >= startIndex && index < endIndex) {
return imageKey;
}
}
}
return imageKey;
return reader.images![startIndex];
}
}

View File

@@ -116,9 +116,9 @@ class _ReaderState extends State<Reader>
return 1;
}
if (!showSingleImageOnFirstPage()) {
return (images!.length / imagesPerPage()).ceil();
return (images!.length / imagesPerPage).ceil();
} else {
return 1 + ((images!.length - 1) / imagesPerPage()).ceil();
return 1 + ((images!.length - 1) / imagesPerPage).ceil();
}
}
@@ -277,13 +277,13 @@ class _ReaderState extends State<Reader>
history!.page = images?.length ?? 1;
} else {
/// Record the first image of the page
if (!showSingleImageOnFirstPage() || imagesPerPage() == 1) {
history!.page = (page - 1) * imagesPerPage() + 1;
if (!showSingleImageOnFirstPage() || imagesPerPage == 1) {
history!.page = (page - 1) * imagesPerPage + 1;
} else {
if (page == 1) {
history!.page = 1;
} else {
history!.page = (page - 2) * imagesPerPage() + 2;
history!.page = (page - 2) * imagesPerPage + 2;
}
}
}
@@ -371,13 +371,13 @@ abstract mixin class _ImagePerPageHandler {
ComicType get type;
void initImagesPerPage(int initialPage) {
_lastImagesPerPage = imagesPerPage();
_lastImagesPerPage = imagesPerPage;
_lastOrientation = isPortrait;
if (imagesPerPage() != 1) {
if (imagesPerPage != 1) {
if (showSingleImageOnFirstPage()) {
page = ((initialPage - 1) / imagesPerPage()).ceil() + 1;
page = ((initialPage - 1) / imagesPerPage).ceil() + 1;
} else {
page = (initialPage / imagesPerPage()).ceil();
page = (initialPage / imagesPerPage).ceil();
}
}
}
@@ -386,7 +386,7 @@ abstract mixin class _ImagePerPageHandler {
appdata.settings.getReaderSetting(cid, type.sourceKey, 'showSingleImageOnFirstPage');
/// The number of images displayed on one screen
int imagesPerPage() {
int get imagesPerPage {
if (mode.isContinuous) return 1;
if (isPortrait) {
return appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerScreenPicNumberForPortrait') ?? 1;
@@ -397,7 +397,7 @@ abstract mixin class _ImagePerPageHandler {
/// Check if the number of images per page has changed
void _checkImagesPerPageChange() {
int currentImagesPerPage = imagesPerPage();
int currentImagesPerPage = imagesPerPage;
bool currentOrientation = isPortrait;
if (_lastImagesPerPage != currentImagesPerPage || _lastOrientation != currentOrientation) {

View File

@@ -599,22 +599,24 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
}
void saveCurrentImage() async {
var data = await selectImageToData();
if (data == null) {
var result = await selectImageToData();
if (result == null) {
return;
}
var (imageIndex, data) = result;
var fileType = detectFileType(data);
var filename = "${context.reader.page}${fileType.ext}";
var filename = "${context.reader.widget.name}_${imageIndex + 1}${fileType.ext}";
saveFile(data: data, filename: filename);
}
void share() async {
var data = await selectImageToData();
if (data == null) {
var result = await selectImageToData();
if (result == null) {
return;
}
var (imageIndex, data) = result;
var fileType = detectFileType(data);
var filename = "${context.reader.page}${fileType.ext}";
var filename = "${context.reader.widget.name}_${imageIndex + 1}${fileType.ext}";
Share.shareFile(data: data, filename: filename, mime: fileType.mime);
}
@@ -719,8 +721,29 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
Future<int?> selectImage() async {
var reader = context.reader;
var imageViewController = context.reader._imageViewController;
if (imageViewController is _GalleryModeState && reader.imagesPerPage == 1) {
return reader.page - 1;
bool needsSelection = false;
int? singleImageIndex;
if (imageViewController is _GalleryModeState) {
var range = imageViewController.getCurrentPageImageRange();
if (range != null) {
var (startIndex, endIndex) = range;
int actualImageCount = endIndex - startIndex;
if (actualImageCount == 1) {
needsSelection = false;
singleImageIndex = startIndex;
} else {
needsSelection = true;
}
}
} else if (imageViewController is _ContinuousModeState) {
needsSelection = false;
singleImageIndex = reader.page - 1;
}
if (!needsSelection && singleImageIndex != null) {
return singleImageIndex;
} else {
var location = await _showSelectImageOverlay();
if (location == null) {
@@ -734,20 +757,23 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
}
}
/// Same as [selectImage], but return the image data.
Future<Uint8List?> selectImageToData() async {
/// Same as [selectImage], but return the image data with its index.
/// Returns (imageIndex, imageData) or null if cancelled.
Future<(int, Uint8List)?> selectImageToData() async {
var i = await selectImage();
if (i == null) {
return null;
}
var imageKey = context.reader.images![i];
Uint8List data;
if (imageKey.startsWith("file://")) {
return await File(imageKey.substring(7)).readAsBytes();
data = await File(imageKey.substring(7)).readAsBytes();
} else {
return (await CacheManager().findCache(
data = await (await CacheManager().findCache(
"$imageKey@${context.reader.type.sourceKey}@${context.reader.cid}@${context.reader.eid}",
))!.readAsBytes();
}
return (i, data);
}
Future<Offset?> _showSelectImageOverlay() {

View File

@@ -2,7 +2,7 @@ name: venera
description: "A comic app."
publish_to: 'none'
version: 1.5.2+152
version: 1.5.3+153
environment:
sdk: '>=3.8.0 <4.0.0'