Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bb5b85b3e | ||
| 3e4051a846 | |||
|
|
24baeda80f | ||
| 9d4c8327b0 | |||
|
|
42125f89eb | ||
| 7d0c7932ea | |||
| 6f9f40a061 | |||
| 41bec3b656 | |||
| 8ba765e3be | |||
|
|
6cdb74a391 | ||
| eb797dd0e8 | |||
| 7243e43bbb | |||
| 82966695b4 | |||
| 322b3e29fa | |||
| 634ac0be6b | |||
|
|
2852e3ecf5 | ||
| 179c6d781c | |||
| daac6f56fd | |||
| a447fe1c8a | |||
| d73fa03a25 | |||
|
|
cb7133fcd7 | ||
| 64af382f10 | |||
| a535c6b49a | |||
| c15ad85d67 | |||
| d474663d44 | |||
|
|
b984aaf187 | ||
| fc8aa17c61 | |||
| 633a1979ce | |||
| 0cb6c06d9d | |||
| ff593aee6d | |||
| bd11f814d7 | |||
|
|
96059f219c | ||
| e7ff39a232 | |||
| 11972542da | |||
| 5dcd1f25b1 | |||
| 1e85d0c2a6 | |||
| 9555eaf636 | |||
| 69f3a4fef9 | |||
|
|
466f5a04b2 | ||
|
|
d44909c79f | ||
| 9d474a62fe | |||
| c72a655f6a | |||
| 32326beb8d | |||
| ce158ad4f8 | |||
| 7ec952620d | |||
| b0fcd93792 | |||
| d7e9b62730 | |||
|
|
f54f69cd3c | ||
| 4d99694109 | |||
| 7c572a6e64 | |||
| 9740997709 | |||
| da170001f0 | |||
|
|
4d0a75882d | ||
| 7c57b7bcbb | |||
| c5595c0d1a | |||
| ea8ff9aabd | |||
| e6284b9577 | |||
|
|
2545e421de | ||
| a5c8e5b479 | |||
| e69625e8af |
1
.flutter-version
Normal file
@@ -0,0 +1 @@
|
||||
3.41.7
|
||||
54
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: "3.41.7"
|
||||
cache: true
|
||||
|
||||
- name: Cache pub dependencies
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: "3.41.7"
|
||||
cache: true
|
||||
|
||||
- name: Cache pub dependencies
|
||||
@@ -83,18 +83,12 @@ jobs:
|
||||
release-please:
|
||||
needs: [lint, test]
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
tag_name: ${{ steps.release.outputs.tag_name }}
|
||||
version: ${{ steps.release.outputs.version }}
|
||||
|
||||
steps:
|
||||
- name: Release Please
|
||||
id: release
|
||||
uses: googleapis/release-please-action@v4
|
||||
with:
|
||||
release-type: dart
|
||||
uses: chenasraf/workflows/.github/workflows/release-please-fastlane-changelog.yml@master
|
||||
with:
|
||||
release-type: dart
|
||||
fastlane-changelog-dirs: |
|
||||
fastlane/metadata/android/en-US/changelogs
|
||||
fastlane/metadata/ios/en-US/changelogs
|
||||
|
||||
build-android:
|
||||
needs: release-please
|
||||
@@ -115,7 +109,7 @@ jobs:
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: "3.41.7"
|
||||
cache: true
|
||||
|
||||
- name: Cache pub dependencies
|
||||
@@ -132,6 +126,9 @@ jobs:
|
||||
- name: Create .env
|
||||
run: cp .env.example .env
|
||||
|
||||
- name: Remove JNI build-id for reproducible builds
|
||||
run: sed -i -e 's/-Wl,/-Wl,--build-id=none,/' $PUB_CACHE/hosted/pub.dev/jni-*/src/CMakeLists.txt
|
||||
|
||||
- name: Decode keystore
|
||||
run: echo ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | base64 -d > android/app/upload-keystore.jks
|
||||
|
||||
@@ -144,23 +141,36 @@ jobs:
|
||||
storeFile=upload-keystore.jks
|
||||
EOF
|
||||
|
||||
- name: Build APK
|
||||
run: flutter build apk --release --obfuscate --split-debug-info=build/debug-info-apk --dart-define-from-file=.env
|
||||
- name: Print signing key SHA-256
|
||||
run: |
|
||||
keytool -list -v -keystore android/app/upload-keystore.jks \
|
||||
-alias ${{ secrets.ANDROID_KEY_ALIAS }} \
|
||||
-storepass ${{ secrets.ANDROID_STORE_PASSWORD }} \
|
||||
2>/dev/null | grep "SHA256:" | awk '{print $2}'
|
||||
|
||||
- name: Build split APKs
|
||||
run: flutter build apk --release --split-per-abi --obfuscate --split-debug-info=build/debug-info-apk --dart-define-from-file=.env
|
||||
|
||||
- name: Build App Bundle
|
||||
run: flutter build appbundle --release --obfuscate --split-debug-info=build/debug-info-aab --dart-define-from-file=.env
|
||||
|
||||
- name: Rename artifacts
|
||||
run: |
|
||||
mv build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/pantry-${{ needs.release-please.outputs.version }}.apk
|
||||
mv build/app/outputs/bundle/release/app-release.aab build/app/outputs/bundle/release/pantry-${{ needs.release-please.outputs.version }}.aab
|
||||
VERSION=${{ needs.release-please.outputs.version }}
|
||||
APK_DIR=build/app/outputs/flutter-apk
|
||||
mv ${APK_DIR}/app-armeabi-v7a-release.apk ${APK_DIR}/pantry-${VERSION}-armeabi-v7a.apk
|
||||
mv ${APK_DIR}/app-arm64-v8a-release.apk ${APK_DIR}/pantry-${VERSION}-arm64-v8a.apk
|
||||
mv ${APK_DIR}/app-x86_64-release.apk ${APK_DIR}/pantry-${VERSION}-x86_64.apk
|
||||
mv build/app/outputs/bundle/release/app-release.aab build/app/outputs/bundle/release/pantry-${VERSION}.aab
|
||||
|
||||
- name: Upload APK to release
|
||||
- name: Upload APKs to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ needs.release-please.outputs.tag_name }}
|
||||
files: |
|
||||
build/app/outputs/flutter-apk/pantry-${{ needs.release-please.outputs.version }}.apk
|
||||
build/app/outputs/flutter-apk/pantry-${{ needs.release-please.outputs.version }}-armeabi-v7a.apk
|
||||
build/app/outputs/flutter-apk/pantry-${{ needs.release-please.outputs.version }}-arm64-v8a.apk
|
||||
build/app/outputs/flutter-apk/pantry-${{ needs.release-please.outputs.version }}-x86_64.apk
|
||||
|
||||
- name: Upload App Bundle to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
@@ -181,7 +191,7 @@ jobs:
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: "3.41.7"
|
||||
cache: true
|
||||
|
||||
- name: Cache pub dependencies
|
||||
|
||||
11
.gitignore
vendored
@@ -47,6 +47,8 @@ app.*.map.json
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.envrc
|
||||
/.flutter-flags.yml
|
||||
|
||||
# Android signing
|
||||
android/key.properties
|
||||
@@ -54,7 +56,8 @@ android/app/*.jks
|
||||
android/app/*.keystore
|
||||
|
||||
# Fastlane
|
||||
android/fastlane/play-store-key.json
|
||||
ios/fastlane/report.xml
|
||||
android/fastlane/report.xml
|
||||
/.envrc
|
||||
fastlane/play-store-key.json
|
||||
fastlane/.image_hashes.json
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/metadata/ios/en-US/release_notes.txt
|
||||
|
||||
110
CHANGELOG.md
@@ -1,5 +1,115 @@
|
||||
# Changelog
|
||||
|
||||
## [0.9.3](https://github.com/chenasraf/pantry-flutter/compare/v0.9.2...v0.9.3) (2026-04-19)
|
||||
|
||||
|
||||
### Build System
|
||||
|
||||
* upgrade flutter version ([3e4051a](https://github.com/chenasraf/pantry-flutter/commit/3e4051a8462271543381496a9d60a22239b8d8da))
|
||||
|
||||
## [0.9.2](https://github.com/chenasraf/pantry-flutter/compare/v0.9.1...v0.9.2) (2026-04-19)
|
||||
|
||||
|
||||
### Build System
|
||||
|
||||
* reproducible build ([9d4c832](https://github.com/chenasraf/pantry-flutter/commit/9d4c8327b035eb0433d6d0a571af406ffca84f83))
|
||||
|
||||
## [0.9.1](https://github.com/chenasraf/pantry-flutter/compare/v0.9.0...v0.9.1) (2026-04-18)
|
||||
|
||||
|
||||
### Build System
|
||||
|
||||
* add abi split ([7d0c793](https://github.com/chenasraf/pantry-flutter/commit/7d0c7932ea9bf18d5ff391351f0058889abba5d8))
|
||||
|
||||
## [0.9.0](https://github.com/chenasraf/pantry-flutter/compare/v0.8.0...v0.9.0) (2026-04-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add search in lists ([eb797dd](https://github.com/chenasraf/pantry-flutter/commit/eb797dd0e87f7eb14576a3bdf7e77f9fe1c0cb09))
|
||||
* allow uploading list item image ([7243e43](https://github.com/chenasraf/pantry-flutter/commit/7243e43bbbfe8072327fc921ed2a4ffba228bd3f))
|
||||
|
||||
## [0.8.0](https://github.com/chenasraf/pantry-flutter/compare/v0.7.1...v0.8.0) (2026-04-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add more icons to categories ([179c6d7](https://github.com/chenasraf/pantry-flutter/commit/179c6d781c1342434608b9af88daa807795c9a46))
|
||||
* allow adding one-off list items ([a447fe1](https://github.com/chenasraf/pantry-flutter/commit/a447fe1c8a1d9de655c081015f287afeba75bee1))
|
||||
|
||||
## [0.7.1](https://github.com/chenasraf/pantry-flutter/compare/v0.7.0...v0.7.1) (2026-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* about urls not opening ([64af382](https://github.com/chenasraf/pantry-flutter/commit/64af382f10bd696f05a23d31ee8e04d746fc4b46))
|
||||
|
||||
## [0.7.0](https://github.com/chenasraf/pantry-flutter/compare/v0.6.0...v0.7.0) (2026-04-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add about page ([0cb6c06](https://github.com/chenasraf/pantry-flutter/commit/0cb6c06d9d418b61d5fd1c4852ec244366aa6af8))
|
||||
|
||||
## [0.6.0](https://github.com/chenasraf/pantry-flutter/compare/v0.5.0...v0.6.0) (2026-04-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* show next due date for list items ([e7ff39a](https://github.com/chenasraf/pantry-flutter/commit/e7ff39a2328ecd9967a3b162dc389bac8a645f38))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* appbar icon spacings ([1197254](https://github.com/chenasraf/pantry-flutter/commit/11972542da777a5922aec564684b7f37b3330aa0))
|
||||
* improve i18n recurrence string rules ([1e85d0c](https://github.com/chenasraf/pantry-flutter/commit/1e85d0c2a6d46d7561105f02683bbed97c907792))
|
||||
|
||||
## [0.5.0](https://github.com/chenasraf/pantry-flutter/compare/v0.4.0...v0.5.0) (2026-04-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add de, es, fr locales ([7ec9526](https://github.com/chenasraf/pantry-flutter/commit/7ec952620db2d957278d58c3798e5b03ab8c59fc))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow arbitrary text in quantity ([32326be](https://github.com/chenasraf/pantry-flutter/commit/32326beb8d39d4713c9f65d01dfb243c44a5dbda))
|
||||
* improve rtl layout spacings ([9d474a6](https://github.com/chenasraf/pantry-flutter/commit/9d474a62fe6ae19f3c08cdb634eac725ffb403c4))
|
||||
* rtl layout + switching ([b0fcd93](https://github.com/chenasraf/pantry-flutter/commit/b0fcd937922badb59467f1bf164e3668c658e531))
|
||||
|
||||
## [0.4.0](https://github.com/chenasraf/pantry-flutter/compare/v0.3.0...v0.4.0) (2026-04-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add hebrew language translation ([7c572a6](https://github.com/chenasraf/pantry-flutter/commit/7c572a6e64eafcf3433a2e6599b698312ffa9cbe))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* description field in items saving+displaying ([4d99694](https://github.com/chenasraf/pantry-flutter/commit/4d9969410935d0b8d64fcfbc3e11d317a17979a6))
|
||||
|
||||
## [0.3.0](https://github.com/chenasraf/pantry-flutter/compare/v0.2.1...v0.3.0) (2026-04-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve main page navigations ([ea8ff9a](https://github.com/chenasraf/pantry-flutter/commit/ea8ff9aabd0924f8273927c907b800576c7cd697))
|
||||
* move items between lists ([c5595c0](https://github.com/chenasraf/pantry-flutter/commit/c5595c0d1ae07c3c2dbf35fba5a70a957fc9af17))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* support back button when in photos foldeer ([e6284b9](https://github.com/chenasraf/pantry-flutter/commit/e6284b95774a5bd967af95626acb6ec3562ae9a5))
|
||||
|
||||
## [0.2.1](https://github.com/chenasraf/pantry-flutter/compare/v0.2.0...v0.2.1) (2026-04-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sorting prefs persistence & error wrapping ([a5c8e5b](https://github.com/chenasraf/pantry-flutter/commit/a5c8e5b479e92f87ea910b5af19ca24711ce7b16))
|
||||
|
||||
## [0.2.0](https://github.com/chenasraf/pantry-flutter/compare/v0.1.0...v0.2.0) (2026-04-11)
|
||||
|
||||
|
||||
|
||||
96
Makefile
@@ -1,9 +1,6 @@
|
||||
# Version from pubspec.yaml (without build number)
|
||||
VERSION := $(shell grep '^version:' pubspec.yaml | sed 's/version: *//;s/+.*//')
|
||||
|
||||
# Get staged Dart files
|
||||
STAGED_DART_FILES := $(shell git diff --cached --name-only --diff-filter=ACM | grep '\.dart$$' 2>/dev/null)
|
||||
|
||||
# Default target
|
||||
.PHONY: help
|
||||
help:
|
||||
@@ -12,7 +9,7 @@ help:
|
||||
@echo " Setup:"
|
||||
@echo " get Install dependencies"
|
||||
@echo " clean Clean build artifacts"
|
||||
@echo " install-precommit Install git pre-commit hook"
|
||||
@echo " install-hooks Install git hooks via lefthook"
|
||||
@echo " pods Update CocoaPods repo and install pods"
|
||||
@echo ""
|
||||
@echo " i18n:"
|
||||
@@ -22,13 +19,9 @@ help:
|
||||
@echo " Development:"
|
||||
@echo " run Run the app in debug mode"
|
||||
@echo " webapp-run Run the web app in default browser"
|
||||
@echo " format Format staged Dart files"
|
||||
@echo " analyze Analyze staged Dart files"
|
||||
@echo " check Check staged files (format + analyze, no changes)"
|
||||
@echo " precommit Run pre-commit checks on staged files"
|
||||
@echo " format-all Format all Dart files"
|
||||
@echo " analyze-all Analyze all Dart files"
|
||||
@echo " check-all Check all files (format + analyze, no changes)"
|
||||
@echo " format Format all Dart files"
|
||||
@echo " analyze Analyze all Dart files"
|
||||
@echo " check Check all files (format + analyze, no changes)"
|
||||
@echo ""
|
||||
@echo " Testing:"
|
||||
@echo " test Run all tests"
|
||||
@@ -44,6 +37,7 @@ help:
|
||||
@echo " Building:"
|
||||
@echo " android-install Build APK and install on connected device"
|
||||
@echo " android-build-apk Build Android APK"
|
||||
@echo " android-build-apk-split Build Android split-per-ABI APKs"
|
||||
@echo " android-build-aab Build Android App Bundle"
|
||||
@echo " android-push Build APK and push to device via adb"
|
||||
@echo " ios-build Build iOS (no codesign)"
|
||||
@@ -79,6 +73,7 @@ build-clean:
|
||||
# i18n
|
||||
.PHONY: i18n
|
||||
i18n:
|
||||
dart run tool/fix_i18n_escapes.dart
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
|
||||
.PHONY: i18n-watch
|
||||
@@ -96,50 +91,14 @@ webapp-run:
|
||||
|
||||
.PHONY: format
|
||||
format:
|
||||
@if [ -n "$(STAGED_DART_FILES)" ]; then \
|
||||
echo "Formatting staged files..."; \
|
||||
dart format $(STAGED_DART_FILES); \
|
||||
else \
|
||||
echo "No staged Dart files to format."; \
|
||||
fi
|
||||
dart format .
|
||||
|
||||
.PHONY: analyze
|
||||
analyze:
|
||||
@if [ -n "$(STAGED_DART_FILES)" ]; then \
|
||||
echo "Analyzing staged files..."; \
|
||||
dart analyze $(STAGED_DART_FILES); \
|
||||
else \
|
||||
echo "No staged Dart files to analyze."; \
|
||||
fi
|
||||
flutter analyze --no-fatal-infos
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
@if [ -n "$(STAGED_DART_FILES)" ]; then \
|
||||
echo "Checking staged files..."; \
|
||||
dart format --output=none --set-exit-if-changed $(STAGED_DART_FILES); \
|
||||
dart analyze $(STAGED_DART_FILES); \
|
||||
else \
|
||||
echo "No staged Dart files to check."; \
|
||||
fi
|
||||
|
||||
.PHONY: precommit
|
||||
precommit: format analyze
|
||||
@if [ -n "$(STAGED_DART_FILES)" ]; then \
|
||||
echo "Re-staging formatted files..."; \
|
||||
git add $(STAGED_DART_FILES); \
|
||||
fi
|
||||
|
||||
# Full project commands
|
||||
.PHONY: format-all
|
||||
format-all:
|
||||
dart format .
|
||||
|
||||
.PHONY: analyze-all
|
||||
analyze-all:
|
||||
flutter analyze --no-fatal-infos
|
||||
|
||||
.PHONY: check-all
|
||||
check-all:
|
||||
dart format --output=none --set-exit-if-changed .
|
||||
flutter analyze --no-fatal-infos
|
||||
|
||||
@@ -162,6 +121,10 @@ test-coverage:
|
||||
android-build-apk:
|
||||
flutter build apk --release --obfuscate --split-debug-info=build/debug-info-apk --dart-define-from-file=.env
|
||||
|
||||
.PHONY: android-build-apk-split
|
||||
android-build-apk-split:
|
||||
flutter build apk --release --split-per-abi --obfuscate --split-debug-info=build/debug-info-apk --dart-define-from-file=.env
|
||||
|
||||
.PHONY: android-install
|
||||
android-install: android-build-apk
|
||||
flutter install
|
||||
@@ -177,6 +140,10 @@ android-build-aab:
|
||||
|
||||
.PHONY: ios-build
|
||||
ios-build:
|
||||
flutter build ios --release --no-codesign --obfuscate --split-debug-info=build/debug-info-ios --dart-define-from-file=.env
|
||||
|
||||
.PHONY: ios-build-ipa
|
||||
ios-build-ipa:
|
||||
flutter build ipa --release --obfuscate --split-debug-info=build/debug-info-ios --dart-define-from-file=.env --export-options-plist=ios/ExportOptions.plist
|
||||
|
||||
.PHONY: web-build
|
||||
@@ -210,7 +177,7 @@ android-upload:
|
||||
@echo "$(or $(TRACK),beta)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TRACK '$(TRACK)'. Must be: internal, alpha, beta, production"; exit 1)
|
||||
@echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1)
|
||||
@echo "Track: $(or $(TRACK),internal) | Status: $(or $(STATUS),draft)"
|
||||
cd android && bundle exec fastlane deploy track:$(or $(TRACK),internal) status:$(or $(STATUS),draft)
|
||||
bundle exec fastlane deploy track:$(or $(TRACK),internal) status:$(or $(STATUS),draft)
|
||||
|
||||
.PHONY: android-deploy
|
||||
android-deploy: android-build-aab android-upload
|
||||
@@ -221,20 +188,20 @@ android-promote:
|
||||
@echo "$(or $(TO),production)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TO '$(TO)'. Must be: internal, alpha, beta, production"; exit 1)
|
||||
@echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1)
|
||||
@echo "Promote: $(or $(FROM),internal) -> $(or $(TO),production) | Status: $(or $(STATUS),draft)"
|
||||
cd android && bundle exec fastlane promote from:$(or $(FROM),internal) to:$(or $(TO),production) status:$(or $(STATUS),draft)
|
||||
bundle exec fastlane promote from:$(or $(FROM),internal) to:$(or $(TO),production) status:$(or $(STATUS),draft)
|
||||
|
||||
.PHONY: ios-upload
|
||||
ios-upload:
|
||||
@echo "$(or $(DEST),testflight)" | grep -qE '^(testflight|appstore)$$' || (echo "Error: Invalid DEST '$(DEST)'. Must be: testflight, appstore"; exit 1)
|
||||
@echo "Destination: $(or $(DEST),testflight)"
|
||||
@if [ "$(or $(DEST),testflight)" = "appstore" ]; then \
|
||||
cd ios && bundle exec fastlane release; \
|
||||
bundle exec fastlane ios release; \
|
||||
else \
|
||||
cd ios && bundle exec fastlane beta; \
|
||||
bundle exec fastlane ios beta; \
|
||||
fi
|
||||
|
||||
.PHONY: ios-deploy
|
||||
ios-deploy: ios-build ios-upload
|
||||
ios-deploy: ios-build-ipa ios-upload
|
||||
|
||||
.PHONY: web-release
|
||||
web-release: web-build
|
||||
@@ -252,17 +219,9 @@ pods:
|
||||
cd macos && pod install --repo-update
|
||||
|
||||
# Git hooks
|
||||
.PHONY: install-precommit
|
||||
install-precommit:
|
||||
@if [ ! -f .git/hooks/pre-commit ]; then \
|
||||
echo "Installing pre-commit hook..."; \
|
||||
echo '#!/bin/sh' > .git/hooks/pre-commit; \
|
||||
echo 'make precommit' >> .git/hooks/pre-commit; \
|
||||
chmod +x .git/hooks/pre-commit; \
|
||||
echo "Pre-commit hook installed."; \
|
||||
else \
|
||||
echo "Pre-commit hook already exists, skipping."; \
|
||||
fi
|
||||
.PHONY: install-hooks
|
||||
install-hooks:
|
||||
lefthook install
|
||||
|
||||
# API
|
||||
.PHONY: fetch-openapi
|
||||
@@ -287,11 +246,14 @@ endif
|
||||
.PHONY: icons
|
||||
icons:
|
||||
mkdir -p assets/icon
|
||||
rsvg-convert -h 1024 assets/logo_icon.svg > assets/icon/icon.png
|
||||
rsvg-convert -w 1024 -h 1024 assets/logo_icon_squircle.svg > assets/icon/icon.png
|
||||
rsvg-convert -w 1024 -h 1024 assets/logo_icon_square.svg > assets/icon/icon_ios.png
|
||||
rsvg-convert -w 1024 -h 1024 assets/logo_icon_foreground.svg > assets/icon/icon_foreground.png
|
||||
dart run flutter_launcher_icons
|
||||
rsvg-convert -w 512 -h 512 assets/logo_icon_squircle.svg > fastlane/metadata/android/en-US/images/icon.png
|
||||
|
||||
.PHONY: splash
|
||||
splash:
|
||||
mkdir -p assets/icon
|
||||
rsvg-convert -h 512 --page-width 1024 --page-height 1024 --top 256 --left 256 assets/logo_icon.svg > assets/icon/splash.png
|
||||
rsvg-convert -h 1152 --page-width 1920 --page-height 1920 --top 384 --left 384 assets/logo_icon.svg > assets/icon/splash.png
|
||||
dart run flutter_native_splash:create
|
||||
|
||||
@@ -5,6 +5,7 @@ plugins {
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
import com.android.build.gradle.internal.api.ApkVariantOutputImpl
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
|
||||
@@ -49,6 +50,10 @@ android {
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-dev"
|
||||
}
|
||||
release {
|
||||
signingConfig = if (signingConfigs.names.contains("release"))
|
||||
signingConfigs.getByName("release")
|
||||
@@ -58,6 +63,17 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
val abiCodes = mapOf("armeabi-v7a" to 1, "arm64-v8a" to 2, "x86_64" to 3)
|
||||
android.applicationVariants.configureEach {
|
||||
val variant = this
|
||||
variant.outputs.forEach { output ->
|
||||
val abiVersionCode = abiCodes[output.filters.find { it.filterType == "ABI" }?.identifier]
|
||||
if (abiVersionCode != null) {
|
||||
(output as ApkVariantOutputImpl).versionCodeOverride = variant.versionCode * 10 + abiVersionCode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<application android:label="Pantry Dev" tools:replace="android:label" />
|
||||
</manifest>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.8 KiB |
@@ -1,2 +0,0 @@
|
||||
json_key_file(ENV["GOOGLE_PLAY_KEY_FILE"])
|
||||
package_name("dev.casraf.pantry")
|
||||
@@ -1,82 +0,0 @@
|
||||
default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
def version_info
|
||||
pubspec = File.read(File.expand_path("../../pubspec.yaml", __dir__))
|
||||
version = pubspec.match(/^version:\s*(.+)$/)[1].strip
|
||||
name, build = version.split("+")
|
||||
{ name: name, build: build }
|
||||
end
|
||||
|
||||
def version_name
|
||||
v = version_info
|
||||
"#{v[:build]} (#{v[:name]})"
|
||||
end
|
||||
|
||||
def changelog_notes
|
||||
version = version_info[:name]
|
||||
changelog_path = File.expand_path("../../CHANGELOG.md", __dir__)
|
||||
return "Release #{version}" unless File.exist?(changelog_path)
|
||||
|
||||
changelog = File.read(changelog_path)
|
||||
pattern = /^## \[#{Regexp.escape(version)}\].*?\n(.*?)(?=^## \[|\z)/m
|
||||
match = changelog.match(pattern)
|
||||
return "Release #{version}" unless match
|
||||
|
||||
match[1].strip
|
||||
.gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "")
|
||||
.gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ")
|
||||
.gsub(/^\*\s+/, "- ")
|
||||
.gsub(/^### /, "")
|
||||
.gsub(/\n{3,}/, "\n\n")
|
||||
.strip
|
||||
.then { |n| n.empty? ? "Release #{version}" : n }
|
||||
end
|
||||
|
||||
desc "Upload AAB to Google Play"
|
||||
lane :deploy do |options|
|
||||
# Write release notes to the metadata tree so `supply` picks it up
|
||||
# keyed by the current versionCode.
|
||||
version_code = version_info[:build]
|
||||
changelog_dir = File.expand_path("metadata/android/en-US/changelogs", __dir__)
|
||||
FileUtils.mkdir_p(changelog_dir)
|
||||
File.write(File.join(changelog_dir, "#{version_code}.txt"), changelog_notes)
|
||||
|
||||
upload_to_play_store(
|
||||
aab: File.expand_path("../../build/app/outputs/bundle/release/app-release.aab", __dir__),
|
||||
track: options[:track] || "internal",
|
||||
release_status: options[:status] || "draft",
|
||||
version_name: version_name,
|
||||
metadata_path: File.expand_path("metadata/android", __dir__),
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sync metadata and screenshots only (no AAB upload)"
|
||||
lane :metadata do
|
||||
upload_to_play_store(
|
||||
skip_upload_aab: true,
|
||||
skip_upload_apk: true,
|
||||
metadata_path: File.expand_path("metadata/android", __dir__),
|
||||
)
|
||||
end
|
||||
|
||||
desc "Promote a release from one track to another"
|
||||
lane :promote do |options|
|
||||
from = options[:from] || "internal"
|
||||
to = options[:to] || "production"
|
||||
status = options[:status] || "draft"
|
||||
|
||||
upload_to_play_store(
|
||||
track: from,
|
||||
track_promote_to: to,
|
||||
release_status: status,
|
||||
version_name: version_name,
|
||||
skip_upload_aab: true,
|
||||
skip_upload_apk: true,
|
||||
skip_upload_metadata: true,
|
||||
skip_upload_changelogs: true,
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1 +0,0 @@
|
||||
Manage your household with your Nextcloud — lists, photos & notes.
|
||||
@@ -1 +0,0 @@
|
||||
Nextcloud Pantry
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 29 KiB |
BIN
assets/icon/icon_foreground.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/icon/icon_ios.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 53 KiB |
5
assets/logo_icon_foreground.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 108 108">
|
||||
<g transform="translate(22, 22) scale(2.667)">
|
||||
<path fill="#FFFFFF" d="M12,3L2,12H5V20H19V12H22L12,3M12,8.75A2.25,2.25 0 0,1 14.25,11A2.25,2.25 0 0,1 12,13.25A2.25,2.25 0 0,1 9.75,11A2.25,2.25 0 0,1 12,8.75M12,15C13.5,15 16.5,15.75 16.5,17.25V18H7.5V17.25C7.5,15.75 10.5,15 12,15Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 367 B |
6
assets/logo_icon_square.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" fill="#0082C9"/>
|
||||
<g transform="translate(106, 106) scale(12.5)">
|
||||
<path fill="#FFFFFF" d="M12,3L2,12H5V20H19V12H22L12,3M12,8.75A2.25,2.25 0 0,1 14.25,11A2.25,2.25 0 0,1 12,13.25A2.25,2.25 0 0,1 9.75,11A2.25,2.25 0 0,1 12,8.75M12,15C13.5,15 16.5,15.75 16.5,17.25V18H7.5V17.25C7.5,15.75 10.5,15 12,15Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 418 B |
25
assets/logo_icon_squircle.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<defs>
|
||||
<clipPath id="squircle">
|
||||
<path d="
|
||||
M256,0
|
||||
C353,0 406,0 443,18
|
||||
C468,30 482,44 494,69
|
||||
C512,106 512,159 512,256
|
||||
C512,353 512,406 494,443
|
||||
C482,468 468,482 443,494
|
||||
C406,512 353,512 256,512
|
||||
C159,512 106,512 69,494
|
||||
C44,482 30,468 18,443
|
||||
C0,406 0,353 0,256
|
||||
C0,159 0,106 18,69
|
||||
C30,44 44,30 69,18
|
||||
C106,0 159,0 256,0
|
||||
Z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<rect width="512" height="512" fill="#0082C9" clip-path="url(#squircle)"/>
|
||||
<g transform="translate(106, 106) scale(12.5)">
|
||||
<path fill="#FFFFFF" d="M12,3L2,12H5V20H19V12H22L12,3M12,8.75A2.25,2.25 0 0,1 14.25,11A2.25,2.25 0 0,1 12,13.25A2.25,2.25 0 0,1 9.75,11A2.25,2.25 0 0,1 12,8.75M12,15C13.5,15 16.5,15.75 16.5,17.25V18H7.5V17.25C7.5,15.75 10.5,15 12,15Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 913 B |
@@ -1,5 +1,9 @@
|
||||
# Android
|
||||
json_key_file(ENV["GOOGLE_PLAY_KEY_FILE"])
|
||||
package_name("dev.casraf.pantry")
|
||||
|
||||
# iOS
|
||||
app_identifier("dev.casraf.pantry")
|
||||
apple_id(ENV["APPLE_ID"])
|
||||
|
||||
itc_team_id(ENV["ITC_TEAM_ID"])
|
||||
team_id(ENV["APPLE_TEAM_ID"])
|
||||
2
fastlane/Deliverfile
Normal file
@@ -0,0 +1,2 @@
|
||||
metadata_path("./fastlane/metadata/ios")
|
||||
screenshots_path("./fastlane/metadata/ios/screenshots")
|
||||
220
fastlane/Fastfile
Normal file
@@ -0,0 +1,220 @@
|
||||
require "digest"
|
||||
require "json"
|
||||
|
||||
# -- Shared helpers --
|
||||
|
||||
def version_info
|
||||
pubspec = File.read(File.expand_path("../pubspec.yaml", __dir__))
|
||||
version = pubspec.match(/^version:\s*(.+)$/)[1].strip
|
||||
name, build = version.split("+")
|
||||
{ name: name, build: build }
|
||||
end
|
||||
|
||||
def version_name
|
||||
v = version_info
|
||||
"#{v[:build]} (#{v[:name]})"
|
||||
end
|
||||
|
||||
def changelog_notes
|
||||
version = version_info[:name]
|
||||
changelog_path = File.expand_path("../CHANGELOG.md", __dir__)
|
||||
return "Release #{version}" unless File.exist?(changelog_path)
|
||||
|
||||
changelog = File.read(changelog_path)
|
||||
escaped = Regexp.escape(version)
|
||||
pattern = /^## (?:\[#{escaped}\]|#{escaped}[\s(]).*?\n(.*?)(?=^## |\z)/m
|
||||
match = changelog.match(pattern)
|
||||
return "Release #{version}" unless match
|
||||
|
||||
match[1].strip
|
||||
.gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "")
|
||||
.gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ")
|
||||
.gsub(/^\*\s+/, "- ")
|
||||
.gsub(/^### /, "")
|
||||
.gsub(/\n{3,}/, "\n\n")
|
||||
.strip
|
||||
.then { |n| n.empty? ? "Release #{version}" : n }
|
||||
end
|
||||
|
||||
# -- Android --
|
||||
|
||||
default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
# Google Play enforces a 500-char limit on release notes per language.
|
||||
PLAY_NOTES_MAX = 500
|
||||
PLAY_NOTES_TRAILER = "\n\n… see full notes on GitHub."
|
||||
|
||||
def play_changelog
|
||||
notes = changelog_notes
|
||||
return notes if notes.length <= PLAY_NOTES_MAX
|
||||
|
||||
budget = PLAY_NOTES_MAX - PLAY_NOTES_TRAILER.length
|
||||
truncated = notes[0, budget]
|
||||
last_newline = truncated.rindex("\n")
|
||||
truncated = truncated[0, last_newline] if last_newline && last_newline > budget / 2
|
||||
truncated.rstrip + PLAY_NOTES_TRAILER
|
||||
end
|
||||
|
||||
# -- Image change detection --
|
||||
|
||||
IMAGE_HASH_CACHE = File.expand_path(".image_hashes.json", __dir__)
|
||||
|
||||
def current_image_hashes
|
||||
root = File.expand_path("metadata/android", __dir__)
|
||||
return {} unless Dir.exist?(root)
|
||||
|
||||
files = Dir.glob(File.join(root, "**/images/**/*")).select { |f| File.file?(f) }
|
||||
files.sort.each_with_object({}) do |path, acc|
|
||||
rel = path.sub("#{root}/", "")
|
||||
acc[rel] = Digest::SHA256.file(path).hexdigest
|
||||
end
|
||||
end
|
||||
|
||||
def cached_image_hashes
|
||||
return {} unless File.exist?(IMAGE_HASH_CACHE)
|
||||
JSON.parse(File.read(IMAGE_HASH_CACHE))
|
||||
rescue StandardError
|
||||
{}
|
||||
end
|
||||
|
||||
def images_changed?
|
||||
current_image_hashes != cached_image_hashes
|
||||
end
|
||||
|
||||
def save_image_hashes
|
||||
File.write(IMAGE_HASH_CACHE, JSON.pretty_generate(current_image_hashes))
|
||||
end
|
||||
|
||||
desc "Upload AAB to Google Play"
|
||||
lane :deploy do |options|
|
||||
# Write changelog if not already present (CI generates it during the
|
||||
# release PR, but this covers manual deploys).
|
||||
version_code = version_info[:build]
|
||||
changelog_dir = File.expand_path("metadata/android/en-US/changelogs", __dir__)
|
||||
changelog_file = File.join(changelog_dir, "#{version_code}.txt")
|
||||
unless File.exist?(changelog_file)
|
||||
FileUtils.mkdir_p(changelog_dir)
|
||||
File.write(changelog_file, play_changelog)
|
||||
end
|
||||
|
||||
changed = images_changed?
|
||||
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
|
||||
|
||||
upload_to_play_store(
|
||||
aab: File.expand_path("../build/app/outputs/bundle/release/app-release.aab", __dir__),
|
||||
track: options[:track] || "internal",
|
||||
release_status: options[:status] || "draft",
|
||||
version_name: version_name,
|
||||
metadata_path: File.expand_path("metadata/android", __dir__),
|
||||
skip_upload_images: !changed,
|
||||
skip_upload_screenshots: !changed,
|
||||
)
|
||||
|
||||
save_image_hashes if changed
|
||||
end
|
||||
|
||||
desc "Sync metadata and screenshots only (no AAB upload)"
|
||||
lane :metadata do
|
||||
changed = images_changed?
|
||||
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
|
||||
|
||||
upload_to_play_store(
|
||||
skip_upload_aab: true,
|
||||
skip_upload_apk: true,
|
||||
skip_upload_changelogs: true,
|
||||
metadata_path: File.expand_path("metadata/android", __dir__),
|
||||
skip_upload_images: !changed,
|
||||
skip_upload_screenshots: !changed,
|
||||
)
|
||||
|
||||
save_image_hashes if changed
|
||||
end
|
||||
|
||||
desc "Promote a release from one track to another"
|
||||
lane :promote do |options|
|
||||
from = options[:from] || "internal"
|
||||
to = options[:to] || "production"
|
||||
status = options[:status] || "draft"
|
||||
|
||||
upload_to_play_store(
|
||||
track: from,
|
||||
track_promote_to: to,
|
||||
release_status: status,
|
||||
version_name: version_name,
|
||||
skip_upload_aab: true,
|
||||
skip_upload_apk: true,
|
||||
skip_upload_metadata: true,
|
||||
skip_upload_changelogs: true,
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# -- iOS --
|
||||
|
||||
platform :ios do
|
||||
def api_key
|
||||
key_id = ENV.fetch("APP_STORE_API_KEY")
|
||||
app_store_connect_api_key(
|
||||
key_id: key_id,
|
||||
issuer_id: ENV.fetch("APP_STORE_ISSUER_ID"),
|
||||
key_filepath: File.join(ENV.fetch("APP_STORE_KEY_PATH"), "AuthKey_#{key_id}.p8"),
|
||||
)
|
||||
end
|
||||
|
||||
def find_ipa
|
||||
ipa_path = Dir[File.expand_path("../build/ios/ipa/*.ipa", __dir__)].first
|
||||
UI.user_error!("No IPA found in build/ios/ipa/. Run 'make ios-build' first.") unless ipa_path
|
||||
ipa_path
|
||||
end
|
||||
|
||||
def sync_release_notes
|
||||
version_code = version_info[:build]
|
||||
changelog_file = File.expand_path("metadata/ios/en-US/changelogs/#{version_code}.txt", __dir__)
|
||||
notes = File.exist?(changelog_file) ? File.read(changelog_file).strip : changelog_notes
|
||||
release_notes_path = File.expand_path("metadata/ios/en-US/release_notes.txt", __dir__)
|
||||
File.write(release_notes_path, notes)
|
||||
UI.message("Synced release notes from build #{version_code} (#{notes.length} chars)")
|
||||
notes
|
||||
end
|
||||
|
||||
desc "Upload to TestFlight"
|
||||
lane :beta do
|
||||
notes = sync_release_notes
|
||||
upload_to_testflight(
|
||||
api_key: api_key,
|
||||
ipa: find_ipa,
|
||||
changelog: notes,
|
||||
skip_waiting_for_build_processing: true,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Upload to App Store"
|
||||
lane :release do
|
||||
sync_release_notes
|
||||
deliver(
|
||||
api_key: api_key,
|
||||
ipa: find_ipa,
|
||||
metadata_path: File.expand_path("metadata/ios", __dir__),
|
||||
screenshots_path: File.expand_path("metadata/ios/en-US/screenshots", __dir__),
|
||||
skip_screenshots: true,
|
||||
submit_for_review: true,
|
||||
precheck_include_in_app_purchases: false,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sync iOS metadata only (no IPA upload)"
|
||||
lane :metadata do
|
||||
deliver(
|
||||
api_key: api_key,
|
||||
metadata_path: File.expand_path("metadata/ios", __dir__),
|
||||
screenshots_path: File.expand_path("metadata/ios/en-US/screenshots", __dir__),
|
||||
skip_binary_upload: true,
|
||||
skip_screenshots: true,
|
||||
submit_for_review: false,
|
||||
precheck_include_in_app_purchases: false,
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -41,6 +41,35 @@ Promote a release from one track to another
|
||||
|
||||
----
|
||||
|
||||
|
||||
## iOS
|
||||
|
||||
### ios beta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios beta
|
||||
```
|
||||
|
||||
Upload to TestFlight
|
||||
|
||||
### ios release
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios release
|
||||
```
|
||||
|
||||
Upload to App Store
|
||||
|
||||
### ios metadata
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios metadata
|
||||
```
|
||||
|
||||
Sync iOS metadata only (no IPA upload)
|
||||
|
||||
----
|
||||
|
||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||
|
||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||
2
fastlane/metadata/android/en-US/changelogs/10.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Bug Fixes
|
||||
- about urls not opening
|
||||
3
fastlane/metadata/android/en-US/changelogs/11.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Features
|
||||
- add more icons to categories
|
||||
- allow adding one-off list items
|
||||
3
fastlane/metadata/android/en-US/changelogs/12.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Features
|
||||
- add search in lists
|
||||
- allow uploading list item image
|
||||
2
fastlane/metadata/android/en-US/changelogs/13.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- add abi split
|
||||
2
fastlane/metadata/android/en-US/changelogs/14.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- reproducible build
|
||||
2
fastlane/metadata/android/en-US/changelogs/15.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- upgrade flutter version
|
||||
8
fastlane/metadata/android/en-US/changelogs/3.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Features
|
||||
|
||||
- add sorting by category for checklist
|
||||
- notifications support
|
||||
|
||||
Bug Fixes
|
||||
|
||||
- add bottom padding to accomodate fab
|
||||
3
fastlane/metadata/android/en-US/changelogs/4.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Bug Fixes
|
||||
|
||||
- sorting prefs persistence & error wrapping
|
||||
8
fastlane/metadata/android/en-US/changelogs/5.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Features
|
||||
|
||||
- improve main page navigations
|
||||
- move items between lists
|
||||
|
||||
Bug Fixes
|
||||
|
||||
- support back button when in photos foldeer
|
||||
7
fastlane/metadata/android/en-US/changelogs/6.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Features
|
||||
|
||||
- add hebrew language translation
|
||||
|
||||
Bug Fixes
|
||||
|
||||
- description field in items saving+displaying
|
||||
6
fastlane/metadata/android/en-US/changelogs/7.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Features
|
||||
- add de, es, fr locales
|
||||
Bug Fixes
|
||||
- allow arbitrary text in quantity
|
||||
- improve rtl layout spacings
|
||||
- rtl layout + switching
|
||||
5
fastlane/metadata/android/en-US/changelogs/8.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Features
|
||||
- show next due date for list items
|
||||
Bug Fixes
|
||||
- appbar icon spacings
|
||||
- improve i18n recurrence string rules
|
||||
2
fastlane/metadata/android/en-US/changelogs/9.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Features
|
||||
- add about page
|
||||
@@ -10,7 +10,7 @@ Upload and organize photos into folders. Add captions, drag to reorder, and brow
|
||||
Keep shared notes with your household. Color-code them, write in markdown, and pin the important stuff where everyone can see it.
|
||||
|
||||
* Your data, your server
|
||||
Pantry connects directly to your self-hosted Nextcloud instance. No accounts to create, no cloud services in between. Your data never leaves your server.
|
||||
Pantry connects directly to your Nextcloud instance. No accounts to create, no cloud services in between. Your data never leaves your server.
|
||||
|
||||
* Features
|
||||
- Shared checklists with categories, quantities, and recurrence
|
||||
@@ -20,6 +20,6 @@ Pantry connects directly to your self-hosted Nextcloud instance. No accounts to
|
||||
- Multi-select for bulk actions
|
||||
- Offline caching for fast loading
|
||||
- Material Design 3 with dark mode support
|
||||
- Nextcloud Login Flow v2 authentication
|
||||
- Secure login flow authentication
|
||||
|
||||
* Pantry requires a Nextcloud server with the Pantry app installed. Visit the project page for setup instructions.
|
||||
* Requires a Nextcloud server with the Pantry app installed. Visit the project page for setup instructions.
|
||||
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 517 KiB After Width: | Height: | Size: 517 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 400 KiB After Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 455 KiB After Width: | Height: | Size: 455 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Manage your household — shared lists, photos & notes on your own server.
|
||||
1
fastlane/metadata/android/en-US/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
Pantry for Nextcloud
|
||||
1
fastlane/metadata/ios/copyright.txt
Normal file
@@ -0,0 +1 @@
|
||||
2026 Chen Asraf
|
||||
1
fastlane/metadata/ios/en-US/apple_tv_privacy_policy.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
fastlane/metadata/ios/en-US/changelogs/10.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Bug Fixes
|
||||
- about urls not opening
|
||||
3
fastlane/metadata/ios/en-US/changelogs/11.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Features
|
||||
- add more icons to categories
|
||||
- allow adding one-off list items
|
||||
3
fastlane/metadata/ios/en-US/changelogs/12.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Features
|
||||
- add search in lists
|
||||
- allow uploading list item image
|
||||
2
fastlane/metadata/ios/en-US/changelogs/13.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- add abi split
|
||||
2
fastlane/metadata/ios/en-US/changelogs/14.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- reproducible build
|
||||
2
fastlane/metadata/ios/en-US/changelogs/15.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Build System
|
||||
- upgrade flutter version
|
||||
25
fastlane/metadata/ios/en-US/description.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
Pantry is a companion app for the Nextcloud Pantry server app. It lets you and your household members collaborate on shared checklists, a photo board, and a notes wall — all stored on your own Nextcloud server.
|
||||
|
||||
* Checklists
|
||||
Create shopping lists and to-do lists with categories, quantities, recurring items, and images. Drag to reorder, sort by name or date, and check items off as you go.
|
||||
|
||||
* Photo Board
|
||||
Upload and organize photos into folders. Add captions, drag to reorder, and browse everything in a clean grid view.
|
||||
|
||||
* Notes Wall
|
||||
Keep shared notes with your household. Color-code them, write in markdown, and pin the important stuff where everyone can see it.
|
||||
|
||||
* Your data, your server
|
||||
Pantry connects directly to your Nextcloud instance. No accounts to create, no cloud services in between. Your data never leaves your server.
|
||||
|
||||
* Features
|
||||
- Shared checklists with categories, quantities, and recurrence
|
||||
- Photo board with folders, captions, and multi-upload
|
||||
- Color-coded notes wall
|
||||
- Drag-and-drop reordering everywhere
|
||||
- Multi-select for bulk actions
|
||||
- Offline caching for fast loading
|
||||
- Material Design 3 with dark mode support
|
||||
- Secure login flow authentication
|
||||
|
||||
* Requires a Nextcloud server with the Pantry app installed. Visit the project page for setup instructions.
|
||||
1
fastlane/metadata/ios/en-US/keywords.txt
Normal file
@@ -0,0 +1 @@
|
||||
nextcloud, checklist, todo, shopping list, notes, self-hosted, household
|
||||
1
fastlane/metadata/ios/en-US/marketing_url.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/chenasraf/pantry-flutter
|
||||
1
fastlane/metadata/ios/en-US/name.txt
Normal file
@@ -0,0 +1 @@
|
||||
Pantry for Nextcloud
|
||||
1
fastlane/metadata/ios/en-US/privacy_url.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://casraf.dev/pantry-privacy-policy
|
||||
1
fastlane/metadata/ios/en-US/promotional_text.txt
Normal file
@@ -0,0 +1 @@
|
||||
Manage your household on your Nextcloud — shared lists, photos & notes.
|
||||
|
After Width: | Height: | Size: 171 KiB |
BIN
fastlane/metadata/ios/en-US/screenshots/0_APP_IPHONE_67_0.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 685 KiB |
BIN
fastlane/metadata/ios/en-US/screenshots/1_APP_IPHONE_67_1.png
Normal file
|
After Width: | Height: | Size: 882 KiB |
|
After Width: | Height: | Size: 210 KiB |
BIN
fastlane/metadata/ios/en-US/screenshots/2_APP_IPHONE_67_2.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
1
fastlane/metadata/ios/en-US/subtitle.txt
Normal file
@@ -0,0 +1 @@
|
||||
Home lists, photos & notes
|
||||