Compare commits

...

3 commits

Author SHA1 Message Date
vodemn
dd5f551fd2 Version bump 2023-07-24 07:54:38 +00:00
ScaredCube
bb9b023fa7
Add Chinese language support (#91)
* Add Chinese language support

* Update intl_cn.arb

* Fixed some bugs

* Add Chinese language support

* renamed `cn` to `zh`

---------

Co-authored-by: Vadim <44135514+vodemn@users.noreply.github.com>
Co-authored-by: Vadim <vadim.turko@gmail.com>
2023-07-24 09:35:30 +02:00
Vadim
dbf1f09eb6 Renamed EquipmentProfileData -> EquipmentProfile 2023-07-24 09:08:37 +02:00
12 changed files with 114 additions and 26 deletions

View file

@ -1,4 +1,4 @@
enum SupportedLocale { en, fr, ru } enum SupportedLocale { en, fr, ru, zh }
extension SupportedLocaleExtension on SupportedLocale { extension SupportedLocaleExtension on SupportedLocale {
String get intlName => toString().replaceAll("SupportedLocale.", ""); String get intlName => toString().replaceAll("SupportedLocale.", "");
@ -11,6 +11,8 @@ extension SupportedLocaleExtension on SupportedLocale {
return 'Français'; return 'Français';
case SupportedLocale.ru: case SupportedLocale.ru:
return 'Русский'; return 'Русский';
case SupportedLocale.zh:
return '简体中文';
} }
} }
} }

View file

@ -150,6 +150,6 @@ class UserPreferencesService {
String get selectedEquipmentProfileId => ''; // coverage:ignore-line String get selectedEquipmentProfileId => ''; // coverage:ignore-line
set selectedEquipmentProfileId(String id) {} // coverage:ignore-line set selectedEquipmentProfileId(String id) {} // coverage:ignore-line
List<EquipmentProfileData> get equipmentProfiles => []; // coverage:ignore-line List<EquipmentProfile> get equipmentProfiles => []; // coverage:ignore-line
set equipmentProfiles(List<EquipmentProfileData> profiles) {} // coverage:ignore-line set equipmentProfiles(List<EquipmentProfile> profiles) {} // coverage:ignore-line
} }

88
lib/l10n/intl_zh.arb Normal file
View file

@ -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": "分数位",
"showFractionalStops": "显示分数位",
"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"
}
}
}
}

View file

@ -4,8 +4,7 @@ import 'package:lightmeter/utils/inherited_generics.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
typedef EquipmentProfiles = List<EquipmentProfileData>; typedef EquipmentProfiles = List<EquipmentProfile>;
typedef EquipmentProfile = EquipmentProfileData;
class EquipmentProfileProvider extends StatefulWidget { class EquipmentProfileProvider extends StatefulWidget {
final Widget child; final Widget child;
@ -21,7 +20,7 @@ class EquipmentProfileProvider extends StatefulWidget {
} }
class EquipmentProfileProviderState extends State<EquipmentProfileProvider> { class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
static const EquipmentProfileData _defaultProfile = EquipmentProfileData( static const EquipmentProfile _defaultProfile = EquipmentProfile(
id: '', id: '',
name: '', name: '',
apertureValues: ApertureValue.values, apertureValues: ApertureValue.values,
@ -30,10 +29,10 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
isoValues: IsoValue.values, isoValues: IsoValue.values,
); );
List<EquipmentProfileData> _customProfiles = []; List<EquipmentProfile> _customProfiles = [];
String _selectedId = ''; String _selectedId = '';
EquipmentProfileData get _selectedProfile => _customProfiles.firstWhere( EquipmentProfile get _selectedProfile => _customProfiles.firstWhere(
(e) => e.id == _selectedId, (e) => e.id == _selectedId,
orElse: () { orElse: () {
context.get<UserPreferencesService>().selectedEquipmentProfileId = _defaultProfile.id; context.get<UserPreferencesService>().selectedEquipmentProfileId = _defaultProfile.id;
@ -50,16 +49,16 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InheritedWidgetBase<List<EquipmentProfileData>>( return InheritedWidgetBase<List<EquipmentProfile>>(
data: [_defaultProfile] + _customProfiles, data: [_defaultProfile] + _customProfiles,
child: InheritedWidgetBase<EquipmentProfileData>( child: InheritedWidgetBase<EquipmentProfile>(
data: _selectedProfile, data: _selectedProfile,
child: widget.child, child: widget.child,
), ),
); );
} }
void setProfile(EquipmentProfileData data) { void setProfile(EquipmentProfile data) {
setState(() { setState(() {
_selectedId = data.id; _selectedId = data.id;
}); });
@ -69,7 +68,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
/// Creates a default equipment profile /// Creates a default equipment profile
void addProfile(String name) { void addProfile(String name) {
_customProfiles.add( _customProfiles.add(
EquipmentProfileData( EquipmentProfile(
id: const Uuid().v1(), id: const Uuid().v1(),
name: name, name: name,
apertureValues: ApertureValue.values, apertureValues: ApertureValue.values,
@ -81,7 +80,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
_refreshSavedProfiles(); _refreshSavedProfiles();
} }
void updateProdile(EquipmentProfileData data) { void updateProdile(EquipmentProfile data) {
final indexToUpdate = _customProfiles.indexWhere((element) => element.id == data.id); final indexToUpdate = _customProfiles.indexWhere((element) => element.id == data.id);
if (indexToUpdate >= 0) { if (indexToUpdate >= 0) {
_customProfiles[indexToUpdate] = data; _customProfiles[indexToUpdate] = data;
@ -89,7 +88,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
} }
} }
void deleteProfile(EquipmentProfileData data) { void deleteProfile(EquipmentProfile data) {
_customProfiles.remove(data); _customProfiles.remove(data);
_refreshSavedProfiles(); _refreshSavedProfiles();
} }

View file

@ -105,7 +105,7 @@ class _EquipmentProfilePicker extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AnimatedDialogPicker<EquipmentProfileData>( return AnimatedDialogPicker<EquipmentProfile>(
icon: Icons.camera, icon: Icons.camera,
title: S.of(context).equipmentProfile, title: S.of(context).equipmentProfile,
selectedValue: context.listen<EquipmentProfile>(), selectedValue: context.listen<EquipmentProfile>(),

View file

@ -6,7 +6,7 @@ sealed class MeteringEvent {
} }
class EquipmentProfileChangedEvent extends MeteringEvent { class EquipmentProfileChangedEvent extends MeteringEvent {
final EquipmentProfileData equipmentProfileData; final EquipmentProfile equipmentProfileData;
const EquipmentProfileChangedEvent(this.equipmentProfileData); const EquipmentProfileChangedEvent(this.equipmentProfileData);
} }

View file

@ -7,7 +7,6 @@ import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/environment.dart'; import 'package:lightmeter/environment.dart';
import 'package:lightmeter/providers/equipment_profile_provider.dart';
import 'package:lightmeter/providers/ev_source_type_provider.dart'; import 'package:lightmeter/providers/ev_source_type_provider.dart';
import 'package:lightmeter/screens/metering/bloc_metering.dart'; import 'package:lightmeter/screens/metering/bloc_metering.dart';
import 'package:lightmeter/screens/metering/components/bottom_controls/provider_bottom_controls.dart'; import 'package:lightmeter/screens/metering/components/bottom_controls/provider_bottom_controls.dart';

View file

@ -8,8 +8,8 @@ import 'package:lightmeter/screens/settings/components/metering/components/equip
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class EquipmentProfileContainer extends StatefulWidget { class EquipmentProfileContainer extends StatefulWidget {
final EquipmentProfileData data; final EquipmentProfile data;
final ValueChanged<EquipmentProfileData> onUpdate; final ValueChanged<EquipmentProfile> onUpdate;
final VoidCallback onDelete; final VoidCallback onDelete;
final VoidCallback onExpand; final VoidCallback onExpand;
@ -27,7 +27,7 @@ class EquipmentProfileContainer extends StatefulWidget {
class EquipmentProfileContainerState extends State<EquipmentProfileContainer> class EquipmentProfileContainerState extends State<EquipmentProfileContainer>
with TickerProviderStateMixin { with TickerProviderStateMixin {
late EquipmentProfileData _equipmentData = EquipmentProfileData( late EquipmentProfile _equipmentData = EquipmentProfile(
id: widget.data.id, id: widget.data.id,
name: widget.data.name, name: widget.data.name,
apertureValues: widget.data.apertureValues, apertureValues: widget.data.apertureValues,
@ -45,7 +45,7 @@ class EquipmentProfileContainerState extends State<EquipmentProfileContainer>
@override @override
void didUpdateWidget(EquipmentProfileContainer oldWidget) { void didUpdateWidget(EquipmentProfileContainer oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
_equipmentData = EquipmentProfileData( _equipmentData = EquipmentProfile(
id: widget.data.id, id: widget.data.id,
name: widget.data.name, name: widget.data.name,
apertureValues: widget.data.apertureValues, apertureValues: widget.data.apertureValues,
@ -195,7 +195,7 @@ class _AnimatedArrowButton extends AnimatedWidget {
} }
class _AnimatedEquipmentListTiles extends AnimatedWidget { class _AnimatedEquipmentListTiles extends AnimatedWidget {
final EquipmentProfileData equipmentData; final EquipmentProfile equipmentData;
final ValueChanged<List<ApertureValue>> onApertureValuesSelected; final ValueChanged<List<ApertureValue>> onApertureValuesSelected;
final ValueChanged<List<IsoValue>> onIsoValuesSelecred; final ValueChanged<List<IsoValue>> onIsoValuesSelecred;
final ValueChanged<List<NdValue>> onNdValuesSelected; final ValueChanged<List<NdValue>> onNdValuesSelected;

View file

@ -84,7 +84,7 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
}); });
} }
void _updateProfileAt(EquipmentProfileData data, int index) { void _updateProfileAt(EquipmentProfile data, int index) {
EquipmentProfileProvider.of(context).updateProdile(data); EquipmentProfileProvider.of(context).updateProdile(data);
} }

View file

@ -12,7 +12,7 @@ class EquipmentProfilesListTile extends StatelessWidget {
leading: const Icon(Icons.camera), leading: const Icon(Icons.camera),
title: Text(S.of(context).equipmentProfiles), title: Text(S.of(context).equipmentProfiles),
onTap: () { onTap: () {
Navigator.of(context).push<EquipmentProfileData>( Navigator.of(context).push<EquipmentProfile>(
MaterialPageRoute(builder: (_) => const EquipmentProfilesScreen()), MaterialPageRoute(builder: (_) => const EquipmentProfilesScreen()),
); );
}, },

View file

@ -1,7 +1,7 @@
name: lightmeter name: lightmeter
description: A new Flutter project. description: A new Flutter project.
publish_to: "none" publish_to: "none"
version: 0.12.0+31 version: 0.12.1+32
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

View file

@ -495,7 +495,7 @@ void main() {
group( group(
'`EquipmentProfileChangedEvent`', '`EquipmentProfileChangedEvent`',
() { () {
final reducedProfile = EquipmentProfileData( final reducedProfile = EquipmentProfile(
id: '0', id: '0',
name: 'Reduced', name: 'Reduced',
apertureValues: ApertureValue.values, apertureValues: ApertureValue.values,