mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-07-05 05:30:42 +00:00
Compare commits
No commits in common. "c6c52981ee443aa438c04aaa5634d9efbcaa48c8" and "5e8f66d75ccc85969a8ccabeccf9b8e596d56016" have entirely different histories.
c6c52981ee
...
5e8f66d75c
13 changed files with 164 additions and 72 deletions
4
.github/workflows/build_apk.yml
vendored
4
.github/workflows/build_apk.yml
vendored
|
@ -115,7 +115,7 @@ jobs:
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
path: ${{ env.RELEASE_NOTES_PATH }}
|
path: ${{ env.RELEASE_NOTES_PATH }}
|
||||||
|
@ -136,7 +136,7 @@ jobs:
|
||||||
run: flutter build ${{ inputs.binary-type }} $BUILD_ARGS
|
run: flutter build ${{ inputs.binary-type }} $BUILD_ARGS
|
||||||
|
|
||||||
- name: Upload ${{ inputs.binary-type }} to artifacts
|
- name: Upload ${{ inputs.binary-type }} to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: m3_lightmeter_${{ inputs.binary-type }}
|
name: m3_lightmeter_${{ inputs.binary-type }}
|
||||||
path: ${{ inputs.binary-type == 'apk' && env.BUILD_APK_PATH || env.BUILD_AAB_PATH }}
|
path: ${{ inputs.binary-type == 'apk' && env.BUILD_APK_PATH || env.BUILD_AAB_PATH }}
|
||||||
|
|
4
.github/workflows/build_ipa.yml
vendored
4
.github/workflows/build_ipa.yml
vendored
|
@ -108,7 +108,7 @@ jobs:
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
path: ${{ env.RELEASE_NOTES_PATH }}
|
path: ${{ env.RELEASE_NOTES_PATH }}
|
||||||
|
@ -135,7 +135,7 @@ jobs:
|
||||||
--export-options-plist=ios/Runner/ExportOptions.plist
|
--export-options-plist=ios/Runner/ExportOptions.plist
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: m3_lightmeter_ipa
|
name: m3_lightmeter_ipa
|
||||||
path: build/ios/ipa/lightmeter.ipa
|
path: build/ios/ipa/lightmeter.ipa
|
||||||
|
|
20
.github/workflows/create_release.yml
vendored
20
.github/workflows/create_release.yml
vendored
|
@ -69,7 +69,7 @@ jobs:
|
||||||
echo ${{ inputs.release-notes }} > ${{ env.RELEASE_NOTES_FILE }}
|
echo ${{ inputs.release-notes }} > ${{ env.RELEASE_NOTES_FILE }}
|
||||||
perl -i -pe 's/\s{1}(-{1})/\n$1/g' ${{ env.RELEASE_NOTES_FILE }}
|
perl -i -pe 's/\s{1}(-{1})/\n$1/g' ${{ env.RELEASE_NOTES_FILE }}
|
||||||
- name: Upload merged_native_libs.zip to artifacts
|
- name: Upload merged_native_libs.zip to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
path: ${{ env.RELEASE_NOTES_FILE }}
|
path: ${{ env.RELEASE_NOTES_FILE }}
|
||||||
|
@ -112,24 +112,24 @@ jobs:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Download apk
|
- name: Download apk
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: m3_lightmeter_apk
|
name: m3_lightmeter_apk
|
||||||
|
|
||||||
|
- name: Increment build number & replace version number
|
||||||
|
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
path: ${{ env.RELEASE_NOTES_PATH }}
|
path: ${{ env.RELEASE_NOTES_PATH }}
|
||||||
|
|
||||||
- name: Increment build number & replace version number
|
|
||||||
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
|
||||||
|
|
||||||
- name: Commit changes
|
- name: Commit changes
|
||||||
run: |
|
run: |
|
||||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config --local user.name "github-actions[bot]"
|
git config --local user.name "github-actions[bot]"
|
||||||
git add --all -- ":!app-prod-release.apk"
|
git add -A
|
||||||
git commit -m "Release v${{ inputs.version }}"
|
git commit -m "Release v${{ inputs.version }}"
|
||||||
|
|
||||||
- name: Push to main
|
- name: Push to main
|
||||||
|
@ -161,7 +161,7 @@ jobs:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Download app bundle
|
- name: Download app bundle
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: m3_lightmeter_appbundle
|
name: m3_lightmeter_appbundle
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ jobs:
|
||||||
(cd base/lib && zip -r "$OLDPWD/merged_native_libs.zip" .)
|
(cd base/lib && zip -r "$OLDPWD/merged_native_libs.zip" .)
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ jobs:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Download ipa
|
- name: Download ipa
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: m3_lightmeter_ipa
|
name: m3_lightmeter_ipa
|
||||||
|
|
||||||
|
|
6
.github/workflows/pr_check.yml
vendored
6
.github/workflows/pr_check.yml
vendored
|
@ -36,10 +36,8 @@ jobs:
|
||||||
if: steps.fetch-iap.conclusion != 'success'
|
if: steps.fetch-iap.conclusion != 'success'
|
||||||
run: bash ./.github/scripts/stub_iap.sh
|
run: bash ./.github/scripts/stub_iap.sh
|
||||||
|
|
||||||
- name: Restore secrets
|
- name: Restore constants.dart
|
||||||
run: |
|
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
|
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
|
|
||||||
|
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
|
|
3
.github/workflows/run_integration_tests.yml
vendored
3
.github/workflows/run_integration_tests.yml
vendored
|
@ -27,9 +27,8 @@ jobs:
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
|
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
|
||||||
|
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -58,8 +58,8 @@ keystore.properties
|
||||||
android/app/google-services.json
|
android/app/google-services.json
|
||||||
ios/firebase_app_id_file.json
|
ios/firebase_app_id_file.json
|
||||||
ios/Runner/GoogleService-Info.plist
|
ios/Runner/GoogleService-Info.plist
|
||||||
lib/firebase_options.dart
|
/lib/firebase_options.dart
|
||||||
lib/constants.dart
|
/lib/constants.dart
|
||||||
|
|
||||||
coverage/
|
coverage/
|
||||||
test/coverage_helper_test.dart
|
test/coverage_helper_test.dart
|
||||||
|
|
BIN
app-prod-release.apk
Normal file
BIN
app-prod-release.apk
Normal file
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
- Cleaned up camera preview implementation.
|
|
67
lib/firebase_options.dart
Normal file
67
lib/firebase_options.dart
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// 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: '',
|
||||||
|
messagingSenderId: '',
|
||||||
|
projectId: '',
|
||||||
|
storageBucket: '',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions ios = FirebaseOptions(
|
||||||
|
apiKey: '',
|
||||||
|
appId: '',
|
||||||
|
messagingSenderId: '',
|
||||||
|
projectId: '',
|
||||||
|
storageBucket: '',
|
||||||
|
iosClientId: '',
|
||||||
|
iosBundleId: '',
|
||||||
|
);
|
||||||
|
}
|
|
@ -132,7 +132,6 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
||||||
|
|
||||||
await _cameraController!.initialize();
|
await _cameraController!.initialize();
|
||||||
await _cameraController!.setFlashMode(FlashMode.off);
|
await _cameraController!.setFlashMode(FlashMode.off);
|
||||||
await _cameraController!.lockCaptureOrientation(DeviceOrientation.portraitUp);
|
|
||||||
|
|
||||||
_zoomRange = await Future.wait<double>([
|
_zoomRange = await Future.wait<double>([
|
||||||
_cameraController!.getMinZoomLevel(),
|
_cameraController!.getMinZoomLevel(),
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import 'package:camera/camera.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class CameraView extends StatelessWidget {
|
||||||
|
final CameraController controller;
|
||||||
|
|
||||||
|
const CameraView({required this.controller, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final value = controller.value;
|
||||||
|
return ValueListenableBuilder<CameraValue>(
|
||||||
|
valueListenable: controller,
|
||||||
|
builder: (_, __, Widget? child) => AspectRatio(
|
||||||
|
aspectRatio: _isLandscape(value) ? value.aspectRatio : (1 / value.aspectRatio),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
RotatedBox(
|
||||||
|
quarterTurns: _getQuarterTurns(value),
|
||||||
|
child: controller.buildPreview(),
|
||||||
|
),
|
||||||
|
child ?? const SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isLandscape(CameraValue value) {
|
||||||
|
return <DeviceOrientation>[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]
|
||||||
|
.contains(_getApplicableOrientation(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getQuarterTurns(CameraValue value) {
|
||||||
|
final Map<DeviceOrientation, int> turns = <DeviceOrientation, int>{
|
||||||
|
DeviceOrientation.portraitUp: 0,
|
||||||
|
DeviceOrientation.landscapeRight: 1,
|
||||||
|
DeviceOrientation.portraitDown: 2,
|
||||||
|
DeviceOrientation.landscapeLeft: 3,
|
||||||
|
};
|
||||||
|
return turns[_getApplicableOrientation(value)]!;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceOrientation _getApplicableOrientation(CameraValue value) {
|
||||||
|
return value.isRecordingVideo
|
||||||
|
? value.recordingOrientation!
|
||||||
|
: (value.previewPauseOrientation ?? value.lockedCaptureOrientation ?? value.deviceOrientation);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,18 @@
|
||||||
import 'package:camera/camera.dart' as camera;
|
import 'package:camera/camera.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/data/models/camera_feature.dart';
|
import 'package:lightmeter/data/models/camera_feature.dart';
|
||||||
import 'package:lightmeter/platform_config.dart';
|
import 'package:lightmeter/platform_config.dart';
|
||||||
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_spot_detector/widget_camera_spot_detector.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_spot_detector/widget_camera_spot_detector.dart';
|
||||||
|
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view/widget_camera_view.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view_placeholder/widget_placeholder_camera_view.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view_placeholder/widget_placeholder_camera_view.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/histogram/widget_histogram.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/histogram/widget_histogram.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
import 'package:lightmeter/utils/context_utils.dart';
|
||||||
|
|
||||||
class CameraPreview extends StatefulWidget {
|
class CameraPreview extends StatefulWidget {
|
||||||
final camera.CameraController? controller;
|
final CameraController? controller;
|
||||||
final CameraErrorType? error;
|
final CameraErrorType? error;
|
||||||
final ValueChanged<Offset?> onSpotTap;
|
final ValueChanged<Offset?> onSpotTap;
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ class _CameraPreviewState extends State<CameraPreview> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CameraPreviewBuilder extends StatefulWidget {
|
class _CameraPreviewBuilder extends StatefulWidget {
|
||||||
final camera.CameraController controller;
|
final CameraController controller;
|
||||||
final ValueChanged<Offset?> onSpotTap;
|
final ValueChanged<Offset?> onSpotTap;
|
||||||
|
|
||||||
const _CameraPreviewBuilder({
|
const _CameraPreviewBuilder({
|
||||||
|
@ -96,15 +97,29 @@ class _CameraPreviewBuilderState extends State<_CameraPreviewBuilder> {
|
||||||
}
|
}
|
||||||
return ValueListenableBuilder<bool>(
|
return ValueListenableBuilder<bool>(
|
||||||
valueListenable: _initializedNotifier,
|
valueListenable: _initializedNotifier,
|
||||||
builder: (context, value, _) => value
|
builder: (context, value, child) => value
|
||||||
? camera.CameraPreview(
|
? Stack(
|
||||||
widget.controller,
|
alignment: Alignment.bottomCenter,
|
||||||
child: context.isPro
|
children: [
|
||||||
? _ProFeaturesOverlay(
|
CameraView(controller: widget.controller),
|
||||||
controller: widget.controller,
|
if (context.isPro) ...[
|
||||||
onSpotTap: widget.onSpotTap,
|
if (UserPreferencesProvider.cameraFeatureOf(
|
||||||
)
|
context,
|
||||||
: const SizedBox.shrink(),
|
CameraFeature.histogram,
|
||||||
|
))
|
||||||
|
Positioned(
|
||||||
|
left: Dimens.grid8,
|
||||||
|
right: Dimens.grid8,
|
||||||
|
bottom: Dimens.grid16,
|
||||||
|
child: CameraHistogram(controller: widget.controller),
|
||||||
|
),
|
||||||
|
if (UserPreferencesProvider.cameraFeatureOf(
|
||||||
|
context,
|
||||||
|
CameraFeature.spotMetering,
|
||||||
|
))
|
||||||
|
CameraSpotDetector(onSpotTap: widget.onSpotTap),
|
||||||
|
],
|
||||||
|
],
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
|
@ -114,38 +129,3 @@ class _CameraPreviewBuilderState extends State<_CameraPreviewBuilder> {
|
||||||
_initializedNotifier.value = widget.controller.value.isInitialized;
|
_initializedNotifier.value = widget.controller.value.isInitialized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ProFeaturesOverlay extends StatelessWidget {
|
|
||||||
final camera.CameraController controller;
|
|
||||||
final ValueChanged<Offset?> onSpotTap;
|
|
||||||
|
|
||||||
const _ProFeaturesOverlay({
|
|
||||||
required this.controller,
|
|
||||||
required this.onSpotTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final bool hasHistogram = UserPreferencesProvider.cameraFeatureOf(
|
|
||||||
context,
|
|
||||||
CameraFeature.histogram,
|
|
||||||
);
|
|
||||||
final bool hasSpotMetering = UserPreferencesProvider.cameraFeatureOf(
|
|
||||||
context,
|
|
||||||
CameraFeature.histogram,
|
|
||||||
);
|
|
||||||
return Stack(
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
children: [
|
|
||||||
if (hasHistogram)
|
|
||||||
Positioned(
|
|
||||||
left: Dimens.grid8,
|
|
||||||
right: Dimens.grid8,
|
|
||||||
bottom: Dimens.grid16,
|
|
||||||
child: CameraHistogram(controller: controller),
|
|
||||||
),
|
|
||||||
if (hasSpotMetering) CameraSpotDetector(onSpotTap: onSpotTap),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: lightmeter
|
name: lightmeter
|
||||||
description: Lightmeter app inspired by Material 3 design system.
|
description: Lightmeter app inspired by Material 3 design system.
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 1.0.2+57
|
version: 1.0.1+56
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
Loading…
Reference in a new issue