mirror of
https://github.com/chenasraf/pantry-flutter.git
synced 2026-05-17 17:28:03 +00:00
chore(macos): app store preparations, ui adjustments
This commit is contained in:
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -95,7 +95,9 @@ jobs:
|
||||
release-type: dart
|
||||
scopes: |
|
||||
ios: fastlane/metadata/ios/en-US/changelogs
|
||||
apple: fastlane/metadata/ios/en-US/changelogs
|
||||
apple: |
|
||||
fastlane/metadata/ios/en-US/changelogs
|
||||
fastlane/metadata/macos/en-US/changelogs
|
||||
android: fastlane/metadata/android/en-US/changelogs
|
||||
|
||||
build-android:
|
||||
@@ -112,9 +114,9 @@ jobs:
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
cache: "gradle"
|
||||
|
||||
- name: Setup Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
|
||||
48
Makefile
48
Makefile
@@ -40,12 +40,15 @@ help:
|
||||
@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)"
|
||||
@echo " macos-build Build macOS app (.app bundle, no codesign)"
|
||||
@echo " macos-build-pkg Build signed macOS .pkg for App Store"
|
||||
@echo " build-all Build all platforms"
|
||||
@echo ""
|
||||
@echo " Release:"
|
||||
@echo " android-release-apk Build APK and copy to build/release/"
|
||||
@echo " android-release-aab Build AAB and copy to build/release/"
|
||||
@echo " ios-release Build IPA and copy to build/release/"
|
||||
@echo " macos-release Build PKG and copy to build/release/"
|
||||
@echo " release-all Build and release all platforms"
|
||||
@echo ""
|
||||
@echo " Deploying:"
|
||||
@@ -53,6 +56,8 @@ help:
|
||||
@echo " android-promote Promote release between tracks (FROM=internal, TO=production, STATUS=draft|completed)"
|
||||
@echo " ios-deploy Build IPA and upload (DEST=testflight|appstore, default: testflight)"
|
||||
@echo " ios-submit Submit the existing App Store build for review (no upload)"
|
||||
@echo " macos-deploy Build PKG and upload (DEST=testflight|appstore, default: testflight)"
|
||||
@echo " macos-submit Submit the existing Mac App Store build for review (no upload)"
|
||||
@echo " deploy-production Build and deploy to production (Google Play + App Store)"
|
||||
@echo " deploy-beta Build and deploy to beta (Google Play beta + TestFlight)"
|
||||
|
||||
@@ -137,6 +142,26 @@ ios-build:
|
||||
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: macos-build
|
||||
macos-build:
|
||||
flutter build macos --release --obfuscate --split-debug-info=build/debug-info-macos
|
||||
|
||||
.PHONY: macos-build-pkg
|
||||
macos-build-pkg:
|
||||
flutter build macos --config-only --obfuscate --split-debug-info=build/debug-info-macos
|
||||
rm -rf build/macos/Runner.xcarchive build/macos/pkg
|
||||
xcodebuild -workspace macos/Runner.xcworkspace \
|
||||
-scheme Runner \
|
||||
-configuration Release \
|
||||
-archivePath build/macos/Runner.xcarchive \
|
||||
-allowProvisioningUpdates \
|
||||
archive
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath build/macos/Runner.xcarchive \
|
||||
-exportPath build/macos/pkg \
|
||||
-exportOptionsPlist macos/ExportOptions.plist \
|
||||
-allowProvisioningUpdates
|
||||
|
||||
.PHONY: build-all
|
||||
build-all: android-build-apk android-build-aab
|
||||
|
||||
@@ -159,6 +184,12 @@ ios-release: ios-build-ipa
|
||||
cp build/ios/ipa/*.ipa build/release/pantry-$(VERSION).ipa
|
||||
@echo "-> build/release/pantry-$(VERSION).ipa"
|
||||
|
||||
.PHONY: macos-release
|
||||
macos-release: macos-build-pkg
|
||||
mkdir -p build/release
|
||||
cp build/macos/pkg/*.pkg build/release/pantry-$(VERSION).pkg
|
||||
@echo "-> build/release/pantry-$(VERSION).pkg"
|
||||
|
||||
.PHONY: android-upload
|
||||
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)
|
||||
@@ -194,6 +225,23 @@ ios-deploy: ios-build-ipa ios-upload
|
||||
ios-submit:
|
||||
bundle exec fastlane ios submit
|
||||
|
||||
.PHONY: macos-upload
|
||||
macos-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 \
|
||||
bundle exec fastlane mac release; \
|
||||
else \
|
||||
bundle exec fastlane mac beta; \
|
||||
fi
|
||||
|
||||
.PHONY: macos-deploy
|
||||
macos-deploy: macos-build-pkg macos-upload
|
||||
|
||||
.PHONY: macos-submit
|
||||
macos-submit:
|
||||
bundle exec fastlane mac submit
|
||||
|
||||
.PHONY: release-all
|
||||
release-all: android-release-apk android-release-aab
|
||||
|
||||
|
||||
@@ -234,3 +234,90 @@ platform :ios do
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# -- macOS --
|
||||
|
||||
platform :mac 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_pkg
|
||||
pkg_path = Dir[File.expand_path("../build/macos/pkg/*.pkg", __dir__)].first
|
||||
UI.user_error!("No PKG found in build/macos/pkg/. Run 'make macos-build-pkg' first.") unless pkg_path
|
||||
pkg_path
|
||||
end
|
||||
|
||||
def sync_release_notes
|
||||
version_code = version_info[:build]
|
||||
changelog_file = File.expand_path("metadata/macos/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/macos/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 (macOS)"
|
||||
lane :beta do
|
||||
notes = sync_release_notes
|
||||
upload_to_testflight(
|
||||
api_key: api_key,
|
||||
pkg: find_pkg,
|
||||
app_platform: "osx",
|
||||
changelog: notes,
|
||||
skip_waiting_for_build_processing: true,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Upload to Mac App Store"
|
||||
lane :release do
|
||||
sync_release_notes
|
||||
deliver(
|
||||
api_key: api_key,
|
||||
pkg: find_pkg,
|
||||
platform: "osx",
|
||||
metadata_path: File.expand_path("metadata/macos", __dir__),
|
||||
screenshots_path: File.expand_path("metadata/macos/en-US/screenshots", __dir__),
|
||||
skip_screenshots: true,
|
||||
submit_for_review: true,
|
||||
precheck_include_in_app_purchases: false,
|
||||
force: true,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sync macOS metadata only (no PKG upload)"
|
||||
lane :metadata do
|
||||
deliver(
|
||||
api_key: api_key,
|
||||
platform: "osx",
|
||||
metadata_path: File.expand_path("metadata/macos", __dir__),
|
||||
screenshots_path: File.expand_path("metadata/macos/en-US/screenshots", __dir__),
|
||||
skip_binary_upload: true,
|
||||
skip_screenshots: true,
|
||||
submit_for_review: false,
|
||||
precheck_include_in_app_purchases: false,
|
||||
force: true,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Submit existing Mac App Store build for review (no PKG upload)"
|
||||
lane :submit do
|
||||
deliver(
|
||||
api_key: api_key,
|
||||
platform: "osx",
|
||||
metadata_path: File.expand_path("metadata/macos", __dir__),
|
||||
screenshots_path: File.expand_path("metadata/macos/en-US/screenshots", __dir__),
|
||||
skip_binary_upload: true,
|
||||
skip_screenshots: true,
|
||||
submit_for_review: true,
|
||||
precheck_include_in_app_purchases: false,
|
||||
force: true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -78,6 +78,43 @@ Submit existing App Store build for review (no IPA upload)
|
||||
|
||||
----
|
||||
|
||||
|
||||
## Mac
|
||||
|
||||
### mac beta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane mac beta
|
||||
```
|
||||
|
||||
Upload to TestFlight (macOS)
|
||||
|
||||
### mac release
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane mac release
|
||||
```
|
||||
|
||||
Upload to Mac App Store
|
||||
|
||||
### mac metadata
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane mac metadata
|
||||
```
|
||||
|
||||
Sync macOS metadata only (no PKG upload)
|
||||
|
||||
### mac submit
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane mac submit
|
||||
```
|
||||
|
||||
Submit existing Mac App Store build for review (no PKG 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).
|
||||
|
||||
1
fastlane/metadata/macos/copyright.txt
Normal file
1
fastlane/metadata/macos/copyright.txt
Normal file
@@ -0,0 +1 @@
|
||||
2026 Chen Asraf
|
||||
5
fastlane/metadata/macos/en-US/changelogs/26.txt
Normal file
5
fastlane/metadata/macos/en-US/changelogs/26.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Features
|
||||
- add setting to show spacing between categories in checklist items
|
||||
- create new lists from the list selector
|
||||
- share photos, links, and text to Pantry from other apps
|
||||
- take photos directly from the photo board
|
||||
25
fastlane/metadata/macos/en-US/description.txt
Normal file
25
fastlane/metadata/macos/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/macos/en-US/keywords.txt
Normal file
1
fastlane/metadata/macos/en-US/keywords.txt
Normal file
@@ -0,0 +1 @@
|
||||
nextcloud, checklist, todo, shopping list, notes, self-hosted, household
|
||||
1
fastlane/metadata/macos/en-US/marketing_url.txt
Normal file
1
fastlane/metadata/macos/en-US/marketing_url.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/chenasraf/pantry-flutter
|
||||
1
fastlane/metadata/macos/en-US/name.txt
Normal file
1
fastlane/metadata/macos/en-US/name.txt
Normal file
@@ -0,0 +1 @@
|
||||
Pantry for Nextcloud
|
||||
1
fastlane/metadata/macos/en-US/privacy_url.txt
Normal file
1
fastlane/metadata/macos/en-US/privacy_url.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://casraf.dev/pantry-privacy-policy
|
||||
1
fastlane/metadata/macos/en-US/promotional_text.txt
Normal file
1
fastlane/metadata/macos/en-US/promotional_text.txt
Normal file
@@ -0,0 +1 @@
|
||||
Manage your household on your Nextcloud — shared lists, photos & notes.
|
||||
5
fastlane/metadata/macos/en-US/release_notes.txt
Normal file
5
fastlane/metadata/macos/en-US/release_notes.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Features
|
||||
- add setting to show spacing between categories in checklist items
|
||||
- create new lists from the list selector
|
||||
- share photos, links, and text to Pantry from other apps
|
||||
- take photos directly from the photo board
|
||||
BIN
fastlane/metadata/macos/en-US/screenshots/0_APP_DESKTOP_0.png
Normal file
BIN
fastlane/metadata/macos/en-US/screenshots/0_APP_DESKTOP_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
fastlane/metadata/macos/en-US/screenshots/1_APP_DESKTOP_1.png
Normal file
BIN
fastlane/metadata/macos/en-US/screenshots/1_APP_DESKTOP_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
BIN
fastlane/metadata/macos/en-US/screenshots/2_APP_DESKTOP_2.png
Normal file
BIN
fastlane/metadata/macos/en-US/screenshots/2_APP_DESKTOP_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
1
fastlane/metadata/macos/en-US/subtitle.txt
Normal file
1
fastlane/metadata/macos/en-US/subtitle.txt
Normal file
@@ -0,0 +1 @@
|
||||
Home lists, photos & notes
|
||||
1
fastlane/metadata/macos/en-US/support_url.txt
Normal file
1
fastlane/metadata/macos/en-US/support_url.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/chenasraf/pantry-flutter
|
||||
1
fastlane/metadata/macos/primary_category.txt
Normal file
1
fastlane/metadata/macos/primary_category.txt
Normal file
@@ -0,0 +1 @@
|
||||
PRODUCTIVITY
|
||||
1
fastlane/metadata/macos/primary_first_sub_category.txt
Normal file
1
fastlane/metadata/macos/primary_first_sub_category.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
fastlane/metadata/macos/primary_second_sub_category.txt
Normal file
1
fastlane/metadata/macos/primary_second_sub_category.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
EQq38!t9uA!@RdAkn6umJHo@nDh3ZZwM
|
||||
1
fastlane/metadata/macos/review_information/demo_user.txt
Normal file
1
fastlane/metadata/macos/review_information/demo_user.txt
Normal file
@@ -0,0 +1 @@
|
||||
store-test
|
||||
@@ -0,0 +1 @@
|
||||
casraf@pm.me
|
||||
@@ -0,0 +1 @@
|
||||
Chen
|
||||
1
fastlane/metadata/macos/review_information/last_name.txt
Normal file
1
fastlane/metadata/macos/review_information/last_name.txt
Normal file
@@ -0,0 +1 @@
|
||||
Asraf
|
||||
3
fastlane/metadata/macos/review_information/notes.txt
Normal file
3
fastlane/metadata/macos/review_information/notes.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
1. In the login screen, for the server, use: spider.casraf.dev and click "Connect"
|
||||
2. Use the given username/password to sign in to the Nextcloud website loaded in the default browser
|
||||
3. Click "Grant Access" to grant access to the app inside the in-app browser
|
||||
@@ -0,0 +1 @@
|
||||
+972549107970
|
||||
1
fastlane/metadata/macos/secondary_category.txt
Normal file
1
fastlane/metadata/macos/secondary_category.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
fastlane/metadata/macos/secondary_first_sub_category.txt
Normal file
1
fastlane/metadata/macos/secondary_first_sub_category.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,4 +1,40 @@
|
||||
PODS:
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- DKImagePickerController/Core (4.3.9):
|
||||
- DKImagePickerController/ImageDataManager
|
||||
- DKImagePickerController/Resource
|
||||
- DKImagePickerController/ImageDataManager (4.3.9)
|
||||
- DKImagePickerController/PhotoGallery (4.3.9):
|
||||
- DKImagePickerController/Core
|
||||
- DKPhotoGallery
|
||||
- DKImagePickerController/Resource (4.3.9)
|
||||
- DKPhotoGallery (0.0.19):
|
||||
- DKPhotoGallery/Core (= 0.0.19)
|
||||
- DKPhotoGallery/Model (= 0.0.19)
|
||||
- DKPhotoGallery/Preview (= 0.0.19)
|
||||
- DKPhotoGallery/Resource (= 0.0.19)
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Core (0.0.19):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Preview
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Model (0.0.19):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Preview (0.0.19):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Resource
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Resource (0.0.19):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- file_picker (0.0.1):
|
||||
- DKImagePickerController/PhotoGallery
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_local_notifications (0.0.1):
|
||||
- Flutter
|
||||
@@ -13,9 +49,13 @@ PODS:
|
||||
- Flutter
|
||||
- receive_sharing_intent (1.8.1):
|
||||
- Flutter
|
||||
- SDWebImage (5.21.7):
|
||||
- SDWebImage/Core (= 5.21.7)
|
||||
- SDWebImage/Core (5.21.7)
|
||||
- sqflite_darwin (0.0.4):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- SwiftyGif (5.4.5)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
@@ -24,6 +64,8 @@ PODS:
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
@@ -36,7 +78,18 @@ DEPENDENCIES:
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
- workmanager_apple (from `.symlinks/plugins/workmanager_apple/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- DKImagePickerController
|
||||
- DKPhotoGallery
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
file_picker:
|
||||
:path: ".symlinks/plugins/file_picker/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_local_notifications:
|
||||
@@ -61,6 +114,10 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/workmanager_apple/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
flutter_local_notifications: 395056b3175ba4f08480a7c5de30cd36d69827e4
|
||||
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
|
||||
@@ -68,7 +125,9 @@ SPEC CHECKSUMS:
|
||||
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||
workmanager_apple: 904529ae31e97fc5be632cf628507652294a0778
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -116,13 +117,15 @@ class PantryAppState extends State<PantryApp> {
|
||||
Widget build(BuildContext context) {
|
||||
final color = ThemingService.instance.effectiveColor;
|
||||
final locale = LocaleService.instance.effectiveLocale;
|
||||
final isMacOS = !kIsWeb && Platform.isMacOS;
|
||||
final appBarTheme = isMacOS ? const AppBarTheme(toolbarHeight: 66) : null;
|
||||
return ChangeNotifierProvider<PrefsService>.value(
|
||||
value: PrefsService.instance,
|
||||
child: Directionality(
|
||||
textDirection: LocaleService.instance.textDirection,
|
||||
child: MaterialApp(
|
||||
key: ValueKey(locale),
|
||||
// debugShowCheckedModeBanner: false,
|
||||
debugShowCheckedModeBanner: false,
|
||||
navigatorKey: rootNavigatorKey,
|
||||
locale: locale,
|
||||
supportedLocales: supportedLocales,
|
||||
@@ -137,6 +140,7 @@ class PantryAppState extends State<PantryApp> {
|
||||
seedColor: color,
|
||||
).copyWith(primary: color),
|
||||
useMaterial3: true,
|
||||
appBarTheme: appBarTheme,
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
@@ -151,6 +155,7 @@ class PantryAppState extends State<PantryApp> {
|
||||
brightness: Brightness.dark,
|
||||
).copyWith(primary: color),
|
||||
useMaterial3: true,
|
||||
appBarTheme: appBarTheme,
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'package:pantry/i18n.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
class AboutView extends StatefulWidget {
|
||||
const AboutView({super.key});
|
||||
@@ -35,7 +36,7 @@ class _AboutViewState extends State<AboutView> {
|
||||
final a = m.about;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(a.title)),
|
||||
appBar: AppBar(leading: appBarBackLeading(context), title: Text(a.title)),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
children: [
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:pantry/i18n.dart';
|
||||
import 'package:pantry/models/category.dart';
|
||||
import 'package:pantry/services/category_service.dart';
|
||||
import 'package:pantry/utils/category_icons.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
import 'package:pantry/widgets/create_category_dialog.dart';
|
||||
|
||||
class CategoriesView extends StatefulWidget {
|
||||
@@ -125,7 +126,10 @@ class _CategoriesViewState extends State<CategoriesView> {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(m.categories.manageTitle)),
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(m.categories.manageTitle),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _create,
|
||||
child: const Icon(Icons.add),
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:pantry/utils/category_icons.dart';
|
||||
import 'package:pantry/utils/date_format.dart';
|
||||
import 'package:pantry/utils/rrule.dart';
|
||||
import 'package:pantry/utils/text_direction.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
import 'checklists_controller.dart';
|
||||
import 'item_form_view.dart';
|
||||
|
||||
@@ -53,6 +54,8 @@ class ItemDetailView extends StatelessWidget {
|
||||
SliverAppBar(
|
||||
expandedHeight: hasImage ? 280 : 0,
|
||||
pinned: true,
|
||||
toolbarHeight: theme.appBarTheme.toolbarHeight ?? kToolbarHeight,
|
||||
leading: appBarBackLeading(context),
|
||||
title: Directionality(
|
||||
textDirection: nameDir,
|
||||
child: Text(item.name),
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:pantry/models/checklist.dart';
|
||||
import 'package:pantry/services/auth_service.dart';
|
||||
import 'package:pantry/services/checklist_service.dart';
|
||||
import 'package:pantry/utils/text_direction.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
import 'package:pantry/widgets/category_picker.dart';
|
||||
import 'package:pantry/widgets/recurrence_dialog.dart';
|
||||
import 'package:pantry/widgets/repeat_button.dart';
|
||||
@@ -151,7 +152,10 @@ class _ItemFormViewState extends State<ItemFormView> {
|
||||
final f = m.checklists.itemForm;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(_isEditing ? f.editTitle : f.addTitle)),
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(_isEditing ? f.editTitle : f.addTitle),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _saving ? null : _save,
|
||||
child: _saving
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:pantry/models/note.dart';
|
||||
import 'package:pantry/utils/text_direction.dart';
|
||||
import 'package:pantry/views/notes/note_form_view.dart';
|
||||
import 'package:pantry/views/notes/notes_controller.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
class NoteDetailView extends StatelessWidget {
|
||||
final Note note;
|
||||
@@ -32,15 +33,8 @@ class NoteDetailView extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
backgroundColor: bgColor,
|
||||
foregroundColor: textColor,
|
||||
title: Align(
|
||||
alignment: titleDir == TextDirection.rtl
|
||||
? Alignment.centerRight
|
||||
: Alignment.centerLeft,
|
||||
child: Directionality(
|
||||
textDirection: titleDir,
|
||||
child: Text(note.title),
|
||||
),
|
||||
),
|
||||
leading: appBarBackLeading(context),
|
||||
title: Directionality(textDirection: titleDir, child: Text(note.title)),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
heroTag: null,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:pantry/i18n.dart';
|
||||
import 'package:pantry/models/note.dart';
|
||||
import 'package:pantry/utils/text_direction.dart';
|
||||
import 'package:pantry/views/notes/notes_controller.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
const _colorOptions = <String?>[
|
||||
null, // default / no color
|
||||
@@ -134,6 +135,7 @@ class _NoteFormViewState extends State<NoteFormView> {
|
||||
appBar: AppBar(
|
||||
backgroundColor: bgColor,
|
||||
foregroundColor: textColor,
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(_isEditing ? m.notesWall.editNote : m.notesWall.newNote),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:pantry/i18n.dart';
|
||||
import 'package:pantry/models/notification.dart';
|
||||
import 'package:pantry/services/deep_link_service.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
import 'notifications_controller.dart';
|
||||
|
||||
class NotificationsView extends StatefulWidget {
|
||||
@@ -53,6 +54,7 @@ class _NotificationsBody extends StatelessWidget {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(m.notifications.title),
|
||||
actions: [
|
||||
if (controller.notifications.isNotEmpty)
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pantry/models/photo.dart';
|
||||
import 'package:pantry/views/photos/photo_board_controller.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
class PhotoDetailView extends StatelessWidget {
|
||||
final Photo photo;
|
||||
@@ -21,7 +22,10 @@ class PhotoDetailView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(photo.caption ?? '')),
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(photo.caption ?? ''),
|
||||
),
|
||||
body: InteractiveViewer(
|
||||
child: Center(
|
||||
child: CachedNetworkImage(
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:pantry/services/local_notifications_service.dart';
|
||||
import 'package:pantry/services/locale_service.dart';
|
||||
import 'package:pantry/services/prefs_service.dart';
|
||||
import 'package:pantry/services/theming_service.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
class SettingsView extends StatefulWidget {
|
||||
const SettingsView({super.key});
|
||||
@@ -132,7 +133,10 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
final categorySpacing = prefs.checklistCategorySpacing;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(m.settings.title)),
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(m.settings.title),
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
// -- General --
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:pantry/services/pending_note_share_service.dart';
|
||||
import 'package:pantry/services/pending_photo_share_service.dart';
|
||||
import 'package:pantry/services/photo_service.dart';
|
||||
import 'package:pantry/services/prefs_service.dart';
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
/// Entry screen for an incoming OS share intent. Classifies the payload,
|
||||
/// optionally asks the user to pick a house, and then routes:
|
||||
@@ -174,7 +175,10 @@ class _ShareRouterViewState extends State<ShareRouterView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(m.share.title)),
|
||||
appBar: AppBar(
|
||||
leading: appBarBackLeading(context),
|
||||
title: Text(m.share.title),
|
||||
),
|
||||
body: Center(
|
||||
child: _busy
|
||||
? const CircularProgressIndicator()
|
||||
|
||||
14
lib/widgets/app_bar_back_leading.dart
Normal file
14
lib/widgets/app_bar_back_leading.dart
Normal file
@@ -0,0 +1,14 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget? appBarBackLeading(BuildContext context) {
|
||||
if (kIsWeb || !Platform.isMacOS) return null;
|
||||
final route = ModalRoute.of(context);
|
||||
if (route?.canPop != true) return null;
|
||||
return const Align(
|
||||
alignment: AlignmentDirectional.bottomCenter,
|
||||
child: BackButton(),
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pantry/widgets/app_bar_back_leading.dart';
|
||||
|
||||
class ImagePreview extends StatelessWidget {
|
||||
final String imageUrl;
|
||||
final Map<String, String> headers;
|
||||
@@ -45,6 +47,7 @@ class ImagePreview extends StatelessWidget {
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
leading: appBarBackLeading(context),
|
||||
),
|
||||
body: InteractiveViewer(
|
||||
minScale: 0.5,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:io' show Platform;
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
@@ -21,6 +22,7 @@ class _PhotoAddButtonState extends State<PhotoAddButton>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _animController;
|
||||
bool _open = false;
|
||||
bool _cameraSupported = !Platform.isMacOS;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -29,6 +31,12 @@ class _PhotoAddButtonState extends State<PhotoAddButton>
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 380),
|
||||
);
|
||||
if (_cameraSupported) {
|
||||
isiOSAppOnMac().then((onMac) {
|
||||
if (!mounted || !onMac) return;
|
||||
setState(() => _cameraSupported = false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -54,7 +62,7 @@ class _PhotoAddButtonState extends State<PhotoAddButton>
|
||||
|
||||
Future<void> _pickPhotos() async {
|
||||
_close();
|
||||
final useFilePicker = await isiOSAppOnMac();
|
||||
final useFilePicker = Platform.isMacOS || await isiOSAppOnMac();
|
||||
if (useFilePicker) {
|
||||
final result = await FilePicker.pickFiles(
|
||||
allowMultiple: true,
|
||||
@@ -135,6 +143,7 @@ class _PhotoAddButtonState extends State<PhotoAddButton>
|
||||
label: m.photoBoard.addMenu.upload,
|
||||
onTap: _pickPhotos,
|
||||
),
|
||||
if (_cameraSupported)
|
||||
_FabAction(
|
||||
icon: Icons.camera_alt,
|
||||
label: m.photoBoard.addMenu.camera,
|
||||
|
||||
18
macos/ExportOptions.plist
Normal file
18
macos/ExportOptions.plist
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store-connect</string>
|
||||
<key>destination</key>
|
||||
<string>export</string>
|
||||
<key>signingStyle</key>
|
||||
<string>automatic</string>
|
||||
<key>stripSwiftSymbols</key>
|
||||
<true/>
|
||||
<key>uploadSymbols</key>
|
||||
<true/>
|
||||
<key>teamID</key>
|
||||
<string>Y893L6NQP2</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,4 +1,8 @@
|
||||
PODS:
|
||||
- device_info_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- file_picker (0.0.1):
|
||||
- FlutterMacOS
|
||||
- file_selector_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- flutter_local_notifications (0.0.1):
|
||||
@@ -18,6 +22,8 @@ PODS:
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
||||
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
|
||||
- file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
|
||||
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
|
||||
- flutter_secure_storage_darwin (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_darwin/darwin`)
|
||||
@@ -28,6 +34,10 @@ DEPENDENCIES:
|
||||
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
||||
file_picker:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos
|
||||
file_selector_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos
|
||||
flutter_local_notifications:
|
||||
@@ -46,6 +56,8 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
||||
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
|
||||
file_selector_macos: 9e9e068e90ebee155097d00e89ae91edb2374db7
|
||||
flutter_local_notifications: 13862b132e32eb858dea558a86d45d08daeacfe7
|
||||
flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)dev.casraf.pantry</string>
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.productivity</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)dev.casraf.pantry</string>
|
||||
|
||||
Reference in New Issue
Block a user