diff --git a/.github/workflows/cd_dev.yml b/.github/workflows/cd_dev.yml index 6e0192e..66695b1 100644 --- a/.github/workflows/cd_dev.yml +++ b/.github/workflows/cd_dev.yml @@ -68,6 +68,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: "stable" + flutter-version: '3.10.0' - name: Prepare flutter project run: | diff --git a/.github/workflows/cd_prod.yml b/.github/workflows/cd_prod.yml index 4030fd5..832dcd4 100644 --- a/.github/workflows/cd_prod.yml +++ b/.github/workflows/cd_prod.yml @@ -70,6 +70,7 @@ jobs: uses: subosito/flutter-action@v2 with: channel: "stable" + flutter-version: '3.10.0' - name: Prepare flutter project run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 346e967..9022170 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,15 +12,12 @@ on: branches: ["main"] jobs: - build: + analyze_and_test: + name: Analyze & test runs-on: macos-11 timeout-minutes: 10 steps: - - uses: webfactory/ssh-agent@v0.8.0 - with: - ssh-private-key: ${{ secrets.M3_LIGHTMETER_IAP_KEY }} - - uses: actions/checkout@v3 with: submodules: recursive @@ -28,23 +25,13 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: "stable" + flutter-version: '3.10.0' - - name: Check flutter version - run: flutter --version - - - name: Install dependencies - run: flutter pub get - - - name: Generate intl - run: flutter pub run intl_utils:generate - - - name: Restore firebase_options.dart - env: - FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }} + - name: Prepare flutter project run: | - FIREBASE_OPTIONS_PATH=$RUNNER_TEMP/firebase_options.dart - echo -n "$FIREBASE_OPTIONS" | base64 --decode --output $FIREBASE_OPTIONS_PATH - cp $FIREBASE_OPTIONS_PATH ./lib + flutter --version + flutter pub get + flutter pub run intl_utils:generate - name: Analyze project source run: flutter analyze lib --fatal-infos diff --git a/README.md b/README.md index 3a6be61..b7434bf 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - [Table of contents](#table-of-contents) - [Backstory](#backstory) - [Screenshots](#screenshots) -- [Build](#build) +- [Development](#development) - [Contribution](#contribution) - [iOS Limitations](#ios-limitations) @@ -27,7 +27,7 @@ Without further delay behold my new Lightmeter app inspired by Material You (a.k
-# Build +# Development ## Available flavors Building with prod flavor requires `DefaultFirebaseOptions` to be present in the _lib/firebase_options.dart_ If you don't want to create your own firebase app, you end up with only dev flavor. @@ -49,12 +49,35 @@ m3_lightmeter_iap: After that run `flutter pub get` as usual. For the first run it will be necessary to open _iap/_ folder and run `flutter pub get` from there. +### 1. Install Flutter + +To build this app you need to install Flutter 3.10.0 stable. [How to install](https://docs.flutter.dev/get-started/install). + +### 2. (Optional) Install Firebase + +Out of the box Firebase Crashlytics won't work. If you want to add Crashlytics to your local build please follow [this guide](https://firebase.google.com/docs/flutter/setup). + +### 3. Get packages + +Fetch all the neccessary dependencies and generate translation files by running the following commands: +```console +flutter pub get +flutter pub run intl_utils:generate +``` + +### 4. Build + +You can build an apk by running the following command from the root of the repository: +```console +flutter build apk --release --flavor $FLAVOR --dart-define cameraPreviewAspectRatio=2/3 -t lib/main_$FLAVOR.dart +``` +Just replace `$FLAVOR` with `dev` or `prod`. # Contribution To report a bug or suggest a new feature open a new [issue](https://github.com/vodemn/m3_lightmeter/issues). -In case you want to help develop this project you need to follow this [style guide](doc/style_guide.md). +In case you want to help develop this project feel free to open a Pull Request, but you need to follow this [style guide](doc/style_guide.md). # iOS Limitations diff --git a/lib/data/models/supported_locale.dart b/lib/data/models/supported_locale.dart index e5f6dcb..0d93a50 100644 --- a/lib/data/models/supported_locale.dart +++ b/lib/data/models/supported_locale.dart @@ -1,4 +1,4 @@ -enum SupportedLocale { en, fr, ru } +enum SupportedLocale { en, fr, ru, zh } extension SupportedLocaleExtension on SupportedLocale { String get intlName => toString().replaceAll("SupportedLocale.", ""); @@ -11,6 +11,8 @@ extension SupportedLocaleExtension on SupportedLocale { return 'Français'; case SupportedLocale.ru: return 'Русский'; + case SupportedLocale.zh: + return '简体中文'; } } } diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 0000000..a8a32c7 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,68 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: '', + storageBucket: '', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: '', + storageBucket: '', + iosClientId: '', + iosBundleId: '', + ); +} diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb new file mode 100644 index 0000000..b931906 --- /dev/null +++ b/lib/l10n/intl_zh.arb @@ -0,0 +1,88 @@ +{ + "@@locale": "zh", + "fastestExposurePair": "最快曝光组合", + "slowestExposurePair": "最慢曝光组合", + "ev": "EV", + "evValue": "{value} EV", + "@evValue": { + "placeholders": { + "value": { + "type": "String" + } + } + }, + "iso": "ISO", + "filmSpeed": "胶片感光度", + "nd": "ND", + "ndFilterFactor": "ND 滤镜系数", + "noExposurePairs": "所选设置没有曝光配对", + "noCamerasDetected": "您的设备似乎没有连接到任何摄像头", + "noCameraPermission": "未获得摄像头权限", + "otherCameraError": "连接摄像头时发生错误", + "none": "无", + "cancel": "取消", + "select": "选择", + "save": "保存", + "settings": "设置", + "metering": "测量", + "fractionalStops": "EV 步进值", + "showFractionalStops": "显示 EV 步进值", + "halfStops": "1/2", + "thirdStops": "1/3", + "calibration": "校准", + "calibrationMessage": "此应用测量读数的准确性完全取决于设备的硬件。因此,请考虑测试此应用并手动设置 EV 校准,以获得准确的测量结果。", + "calibrationMessageCameraOnly": "此应用程序测量读数的准确性完全取决于设备的后置摄像头。因此,请考虑测试此应用并手动设置 EV 校准,以获得准确的测量结果。", + "camera": "摄像头", + "lightSensor": "光传感器", + "meteringScreenLayout": "布局", + "meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间", + "meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合", + "meteringScreenFeatureFilmPicker": "胶片选择", + "film": "胶片", + "equipment": "设备", + "equipmentProfileName": "设备配置名称", + "equipmentProfileNameHint": "Praktica MTL5B", + "equipmentProfileAllValues": "全部", + "apertureValues": "光圈值", + "apertureValuesFilterDescription": "选择要显示的光圈值范围。这通常由您使用的镜头决定。", + "ndFilters": "ND 滤镜", + "ndFiltersFilterDescription": "选择要显示的 ND 滤镜系数。这些可能是您最常用的 ND 滤镜,也可能是适合您镜头的滤光镜。", + "shutterSpeedValues": "快门速度", + "shutterSpeedValuesFilterDescription": "选择要显示的快门速度范围。这通常由您使用的相机机身决定。", + "isoValues": "ISO", + "isoValuesFilterDescription": "选择要显示的 ISO。这些值可能是您最常用的值,也可能是相机支持的值。", + "equipmentProfile": "设备配置", + "equipmentProfiles": "设备配置", + "general": "通用", + "keepScreenOn": "保持屏幕常亮", + "haptics": "震动", + "volumeKeysAction": "音量键快门", + "language": "语言", + "chooseLanguage": "选择语言", + "theme": "主题", + "chooseTheme": "选择主题", + "themeLight": "亮色", + "themeDark": "暗色", + "themeSystemDefault": "跟随系统", + "dynamicColor": "动态颜色", + "primaryColor": "主题颜色", + "choosePrimaryColor": "选择主题颜色", + "about": "关于", + "sourceCode": "源代码", + "reportIssue": "报告问题", + "writeEmail": "Email", + "youDontHaveMailApp": "您没有安装任何邮件App。", + "copyEmail": "复制电子邮件", + "version": "Version", + "versionNumber": "{version} ({buildNumber})", + "@versionNumber": { + "placeholders": { + "version": { + "type": "String" + }, + "buildNumber": { + "type": "String" + } + } + } +} diff --git a/lib/main_prod.dart b/lib/main_prod.dart index a47d421..fc1700a 100644 --- a/lib/main_prod.dart +++ b/lib/main_prod.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:lightmeter/application.dart'; import 'package:lightmeter/environment.dart'; @@ -5,6 +7,10 @@ import 'package:lightmeter/firebase.dart'; Future