From 39dd4ad94835ce386fd2712b1da66edead4f6301 Mon Sep 17 00:00:00 2001 From: MiaoMint <1981324730@qq.com> Date: Tue, 11 Jul 2023 17:50:22 +0800 Subject: [PATCH] =?UTF-8?q?feat!:=20=E6=89=A9=E5=B1=95=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/i18n/en.json | 11 + assets/i18n/zh.json | 13 +- lib/main.dart | 9 + lib/models/extension_setting.dart | 49 + lib/models/extension_setting.g.dart | 2101 +++++++++++++++++ lib/models/history.g.dart | 250 +- .../detail/widgets/detail_continue_play.dart | 5 +- lib/pages/detail/widgets/detail_episodes.dart | 4 +- .../extension/widgets/extension_tile.dart | 14 +- lib/pages/extension_settings/controller.dart | 26 + lib/pages/extension_settings/view.dart | 400 ++++ .../extension_settings/widgets/info_card.dart | 59 + lib/pages/home/view.dart | 2 +- lib/pages/settings/view.dart | 8 +- lib/utils/database.dart | 88 + lib/utils/extension_runtime.dart | 66 +- lib/utils/miru_storage.dart | 3 +- .../card_tile.dart} | 6 +- .../widgets/settings_input_tile.dart | 9 +- .../widgets/settings_radios_tile.dart | 12 +- .../widgets/settings_switch_tile.dart | 6 +- .../settings => }/widgets/settings_tile.dart | 10 +- pubspec.yaml | 2 +- 23 files changed, 2986 insertions(+), 167 deletions(-) create mode 100644 lib/models/extension_setting.dart create mode 100644 lib/models/extension_setting.g.dart create mode 100644 lib/pages/extension_settings/controller.dart create mode 100644 lib/pages/extension_settings/view.dart create mode 100644 lib/pages/extension_settings/widgets/info_card.dart rename lib/{pages/detail/widgets/detail_tile.dart => widgets/card_tile.dart} (92%) rename lib/{pages/settings => }/widgets/settings_input_tile.dart (91%) rename lib/{pages/settings => }/widgets/settings_radios_tile.dart (90%) rename lib/{pages/settings => }/widgets/settings_switch_tile.dart (91%) rename lib/{pages/settings => }/widgets/settings_tile.dart (91%) diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 41bac91d..c32e6256 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -107,5 +107,16 @@ "video": "Video", "novel": "Novel", "comics": "Comics" + }, + + "extension-info": { + "author": "Author", + "description": "Description", + "version": "Version", + "language": "Language", + "original-site": "Original Site", + "other-infomation": "Other Infomation", + "license": "License", + "title": "Extension Info" } } diff --git a/assets/i18n/zh.json b/assets/i18n/zh.json index 895d5954..1e5df83c 100644 --- a/assets/i18n/zh.json +++ b/assets/i18n/zh.json @@ -76,7 +76,7 @@ "source-code": "开源", "source-code-training": "前往 Star", "license": "许可", - "license-subtitle": "许可" + "license-subtitle": "许可证" }, "detail": { @@ -112,5 +112,16 @@ "video": "影视", "novel": "小说", "comics": "漫画" + }, + + "extension-info": { + "author": "作者", + "description": "描述", + "version": "版本", + "language": "语言", + "original-site": "源站", + "other-infomation": "其他信息", + "license": "许可", + "title": "扩展详情" } } diff --git a/lib/main.dart b/lib/main.dart index 621a1c58..44bc841e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,6 +12,7 @@ import 'package:miru_app/pages/detail/view.dart'; import 'package:miru_app/pages/extension/view.dart'; import 'package:miru_app/pages/extension_log/view.dart'; import 'package:miru_app/pages/extension_repo/view.dart'; +import 'package:miru_app/pages/extension_settings/view.dart'; import 'package:miru_app/pages/home/view.dart'; import 'package:miru_app/pages/main/view.dart'; import 'package:miru_app/pages/search/view.dart'; @@ -158,6 +159,14 @@ final router = GoRouter( path: '/extension', builder: (context, state) => _animation(const ExtensionPage()), ), + GoRoute( + path: '/extension_settings', + builder: (context, state) => _animation( + ExtensionSettingsPage( + package: state.queryParameters['package']!, + ), + ), + ), GoRoute( path: '/settings', builder: (context, state) => _animation(const SettingsPage()), diff --git a/lib/models/extension_setting.dart b/lib/models/extension_setting.dart new file mode 100644 index 00000000..1ef46524 --- /dev/null +++ b/lib/models/extension_setting.dart @@ -0,0 +1,49 @@ +import 'package:isar/isar.dart'; + +part 'extension_setting.g.dart'; + +enum ExtensionSettingType { + // 输入框 + input, + // 单选 + radio, + // 开关 + toggle, +} + +@collection +class ExtensionSetting { + Id id = Isar.autoIncrement; + + @Index(composite: [CompositeIndex('key')], unique: true) + late String package; + // 标题 + late String title; + // 键 + late String key; + // 值 + String? value; + // 默认值 + late String defaultValue; + // 类型 + @Enumerated(EnumType.name) + late ExtensionSettingType type; + // 描述 + String? description; + // 如果是 radio 类型,这里是各项选项,且必填 , 存储为 ["key:value","key:value"] + // 为啥不直接用 map,因为 isar 还不支持 map 类型 + List? options; + + static ExtensionSettingType stringToType(String type) { + switch (type) { + case 'input': + return ExtensionSettingType.input; + case 'radio': + return ExtensionSettingType.radio; + case 'toggle': + return ExtensionSettingType.toggle; + default: + return ExtensionSettingType.input; + } + } +} diff --git a/lib/models/extension_setting.g.dart b/lib/models/extension_setting.g.dart new file mode 100644 index 00000000..55be672e --- /dev/null +++ b/lib/models/extension_setting.g.dart @@ -0,0 +1,2101 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'extension_setting.dart'; + +// ************************************************************************** +// IsarCollectionGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types + +extension GetExtensionSettingCollection on Isar { + IsarCollection get extensionSettings => this.collection(); +} + +const ExtensionSettingSchema = CollectionSchema( + name: r'ExtensionSetting', + id: -7314426202638088585, + properties: { + r'defaultValue': PropertySchema( + id: 0, + name: r'defaultValue', + type: IsarType.string, + ), + r'description': PropertySchema( + id: 1, + name: r'description', + type: IsarType.string, + ), + r'key': PropertySchema( + id: 2, + name: r'key', + type: IsarType.string, + ), + r'options': PropertySchema( + id: 3, + name: r'options', + type: IsarType.stringList, + ), + r'package': PropertySchema( + id: 4, + name: r'package', + type: IsarType.string, + ), + r'title': PropertySchema( + id: 5, + name: r'title', + type: IsarType.string, + ), + r'type': PropertySchema( + id: 6, + name: r'type', + type: IsarType.string, + enumMap: _ExtensionSettingtypeEnumValueMap, + ), + r'value': PropertySchema( + id: 7, + name: r'value', + type: IsarType.string, + ) + }, + estimateSize: _extensionSettingEstimateSize, + serialize: _extensionSettingSerialize, + deserialize: _extensionSettingDeserialize, + deserializeProp: _extensionSettingDeserializeProp, + idName: r'id', + indexes: { + r'package_key': IndexSchema( + id: -372028747178333220, + name: r'package_key', + unique: true, + replace: false, + properties: [ + IndexPropertySchema( + name: r'package', + type: IndexType.hash, + caseSensitive: true, + ), + IndexPropertySchema( + name: r'key', + type: IndexType.hash, + caseSensitive: true, + ) + ], + ) + }, + links: {}, + embeddedSchemas: {}, + getId: _extensionSettingGetId, + getLinks: _extensionSettingGetLinks, + attach: _extensionSettingAttach, + version: '3.1.0+1', +); + +int _extensionSettingEstimateSize( + ExtensionSetting object, + List offsets, + Map> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.defaultValue.length * 3; + { + final value = object.description; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + bytesCount += 3 + object.key.length * 3; + { + final list = object.options; + if (list != null) { + bytesCount += 3 + list.length * 3; + { + for (var i = 0; i < list.length; i++) { + final value = list[i]; + bytesCount += value.length * 3; + } + } + } + } + bytesCount += 3 + object.package.length * 3; + bytesCount += 3 + object.title.length * 3; + bytesCount += 3 + object.type.name.length * 3; + { + final value = object.value; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + return bytesCount; +} + +void _extensionSettingSerialize( + ExtensionSetting object, + IsarWriter writer, + List offsets, + Map> allOffsets, +) { + writer.writeString(offsets[0], object.defaultValue); + writer.writeString(offsets[1], object.description); + writer.writeString(offsets[2], object.key); + writer.writeStringList(offsets[3], object.options); + writer.writeString(offsets[4], object.package); + writer.writeString(offsets[5], object.title); + writer.writeString(offsets[6], object.type.name); + writer.writeString(offsets[7], object.value); +} + +ExtensionSetting _extensionSettingDeserialize( + Id id, + IsarReader reader, + List offsets, + Map> allOffsets, +) { + final object = ExtensionSetting(); + object.defaultValue = reader.readString(offsets[0]); + object.description = reader.readStringOrNull(offsets[1]); + object.id = id; + object.key = reader.readString(offsets[2]); + object.options = reader.readStringList(offsets[3]); + object.package = reader.readString(offsets[4]); + object.title = reader.readString(offsets[5]); + object.type = + _ExtensionSettingtypeValueEnumMap[reader.readStringOrNull(offsets[6])] ?? + ExtensionSettingType.input; + object.value = reader.readStringOrNull(offsets[7]); + return object; +} + +P _extensionSettingDeserializeProp

( + IsarReader reader, + int propertyId, + int offset, + Map> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readString(offset)) as P; + case 1: + return (reader.readStringOrNull(offset)) as P; + case 2: + return (reader.readString(offset)) as P; + case 3: + return (reader.readStringList(offset)) as P; + case 4: + return (reader.readString(offset)) as P; + case 5: + return (reader.readString(offset)) as P; + case 6: + return (_ExtensionSettingtypeValueEnumMap[ + reader.readStringOrNull(offset)] ?? + ExtensionSettingType.input) as P; + case 7: + return (reader.readStringOrNull(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +const _ExtensionSettingtypeEnumValueMap = { + r'input': r'input', + r'radio': r'radio', + r'toggle': r'toggle', +}; +const _ExtensionSettingtypeValueEnumMap = { + r'input': ExtensionSettingType.input, + r'radio': ExtensionSettingType.radio, + r'toggle': ExtensionSettingType.toggle, +}; + +Id _extensionSettingGetId(ExtensionSetting object) { + return object.id; +} + +List> _extensionSettingGetLinks(ExtensionSetting object) { + return []; +} + +void _extensionSettingAttach( + IsarCollection col, Id id, ExtensionSetting object) { + object.id = id; +} + +extension ExtensionSettingByIndex on IsarCollection { + Future getByPackageKey(String package, String key) { + return getByIndex(r'package_key', [package, key]); + } + + ExtensionSetting? getByPackageKeySync(String package, String key) { + return getByIndexSync(r'package_key', [package, key]); + } + + Future deleteByPackageKey(String package, String key) { + return deleteByIndex(r'package_key', [package, key]); + } + + bool deleteByPackageKeySync(String package, String key) { + return deleteByIndexSync(r'package_key', [package, key]); + } + + Future> getAllByPackageKey( + List packageValues, List keyValues) { + final len = packageValues.length; + assert( + keyValues.length == len, 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([packageValues[i], keyValues[i]]); + } + + return getAllByIndex(r'package_key', values); + } + + List getAllByPackageKeySync( + List packageValues, List keyValues) { + final len = packageValues.length; + assert( + keyValues.length == len, 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([packageValues[i], keyValues[i]]); + } + + return getAllByIndexSync(r'package_key', values); + } + + Future deleteAllByPackageKey( + List packageValues, List keyValues) { + final len = packageValues.length; + assert( + keyValues.length == len, 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([packageValues[i], keyValues[i]]); + } + + return deleteAllByIndex(r'package_key', values); + } + + int deleteAllByPackageKeySync( + List packageValues, List keyValues) { + final len = packageValues.length; + assert( + keyValues.length == len, 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([packageValues[i], keyValues[i]]); + } + + return deleteAllByIndexSync(r'package_key', values); + } + + Future putByPackageKey(ExtensionSetting object) { + return putByIndex(r'package_key', object); + } + + Id putByPackageKeySync(ExtensionSetting object, {bool saveLinks = true}) { + return putByIndexSync(r'package_key', object, saveLinks: saveLinks); + } + + Future> putAllByPackageKey(List objects) { + return putAllByIndex(r'package_key', objects); + } + + List putAllByPackageKeySync(List objects, + {bool saveLinks = true}) { + return putAllByIndexSync(r'package_key', objects, saveLinks: saveLinks); + } +} + +extension ExtensionSettingQueryWhereSort + on QueryBuilder { + QueryBuilder anyId() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(const IdWhereClause.any()); + }); + } +} + +extension ExtensionSettingQueryWhere + on QueryBuilder { + QueryBuilder idEqualTo( + Id id) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: id, + upper: id, + )); + }); + } + + QueryBuilder + idNotEqualTo(Id id) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ) + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ); + } else { + return query + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ) + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ); + } + }); + } + + QueryBuilder + idGreaterThan(Id id, {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: include), + ); + }); + } + + QueryBuilder + idLessThan(Id id, {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: include), + ); + }); + } + + QueryBuilder idBetween( + Id lowerId, + Id upperId, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: lowerId, + includeLower: includeLower, + upper: upperId, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder + packageEqualToAnyKey(String package) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'package_key', + value: [package], + )); + }); + } + + QueryBuilder + packageNotEqualToAnyKey(String package) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [], + upper: [package], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [], + upper: [package], + includeUpper: false, + )); + } + }); + } + + QueryBuilder + packageKeyEqualTo(String package, String key) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'package_key', + value: [package, key], + )); + }); + } + + QueryBuilder + packageEqualToKeyNotEqualTo(String package, String key) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package], + upper: [package, key], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package, key], + includeLower: false, + upper: [package], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package, key], + includeLower: false, + upper: [package], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'package_key', + lower: [package], + upper: [package, key], + includeUpper: false, + )); + } + }); + } +} + +extension ExtensionSettingQueryFilter + on QueryBuilder { + QueryBuilder + defaultValueEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'defaultValue', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'defaultValue', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'defaultValue', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + defaultValueIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'defaultValue', + value: '', + )); + }); + } + + QueryBuilder + defaultValueIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'defaultValue', + value: '', + )); + }); + } + + QueryBuilder + descriptionIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'description', + )); + }); + } + + QueryBuilder + descriptionIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'description', + )); + }); + } + + QueryBuilder + descriptionEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'description', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'description', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'description', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + descriptionIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'description', + value: '', + )); + }); + } + + QueryBuilder + descriptionIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'description', + value: '', + )); + }); + } + + QueryBuilder + idEqualTo(Id value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idGreaterThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idLessThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder + idBetween( + Id lower, + Id upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'id', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder + keyEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'key', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'key', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'key', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + keyIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'key', + value: '', + )); + }); + } + + QueryBuilder + keyIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'key', + value: '', + )); + }); + } + + QueryBuilder + optionsIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'options', + )); + }); + } + + QueryBuilder + optionsIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'options', + )); + }); + } + + QueryBuilder + optionsElementEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'options', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'options', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'options', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + optionsElementIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'options', + value: '', + )); + }); + } + + QueryBuilder + optionsElementIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'options', + value: '', + )); + }); + } + + QueryBuilder + optionsLengthEqualTo(int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder + optionsIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder + optionsIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder + optionsLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder + optionsLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder + optionsLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'options', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder + packageEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'package', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'package', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'package', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + packageIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'package', + value: '', + )); + }); + } + + QueryBuilder + packageIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'package', + value: '', + )); + }); + } + + QueryBuilder + titleEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'title', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'title', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'title', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + titleIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'title', + value: '', + )); + }); + } + + QueryBuilder + titleIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'title', + value: '', + )); + }); + } + + QueryBuilder + typeEqualTo( + ExtensionSettingType value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeGreaterThan( + ExtensionSettingType value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeLessThan( + ExtensionSettingType value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeBetween( + ExtensionSettingType lower, + ExtensionSettingType upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'type', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'type', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'type', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + typeIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'type', + value: '', + )); + }); + } + + QueryBuilder + typeIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'type', + value: '', + )); + }); + } + + QueryBuilder + valueIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'value', + )); + }); + } + + QueryBuilder + valueIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'value', + )); + }); + } + + QueryBuilder + valueEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'value', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'value', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'value', + value: '', + )); + }); + } + + QueryBuilder + valueIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'value', + value: '', + )); + }); + } +} + +extension ExtensionSettingQueryObject + on QueryBuilder {} + +extension ExtensionSettingQueryLinks + on QueryBuilder {} + +extension ExtensionSettingQuerySortBy + on QueryBuilder { + QueryBuilder + sortByDefaultValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'defaultValue', Sort.asc); + }); + } + + QueryBuilder + sortByDefaultValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'defaultValue', Sort.desc); + }); + } + + QueryBuilder + sortByDescription() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'description', Sort.asc); + }); + } + + QueryBuilder + sortByDescriptionDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'description', Sort.desc); + }); + } + + QueryBuilder sortByKey() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'key', Sort.asc); + }); + } + + QueryBuilder + sortByKeyDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'key', Sort.desc); + }); + } + + QueryBuilder + sortByPackage() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'package', Sort.asc); + }); + } + + QueryBuilder + sortByPackageDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'package', Sort.desc); + }); + } + + QueryBuilder sortByTitle() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'title', Sort.asc); + }); + } + + QueryBuilder + sortByTitleDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'title', Sort.desc); + }); + } + + QueryBuilder sortByType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.asc); + }); + } + + QueryBuilder + sortByTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.desc); + }); + } + + QueryBuilder sortByValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.asc); + }); + } + + QueryBuilder + sortByValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.desc); + }); + } +} + +extension ExtensionSettingQuerySortThenBy + on QueryBuilder { + QueryBuilder + thenByDefaultValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'defaultValue', Sort.asc); + }); + } + + QueryBuilder + thenByDefaultValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'defaultValue', Sort.desc); + }); + } + + QueryBuilder + thenByDescription() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'description', Sort.asc); + }); + } + + QueryBuilder + thenByDescriptionDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'description', Sort.desc); + }); + } + + QueryBuilder thenById() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.asc); + }); + } + + QueryBuilder + thenByIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.desc); + }); + } + + QueryBuilder thenByKey() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'key', Sort.asc); + }); + } + + QueryBuilder + thenByKeyDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'key', Sort.desc); + }); + } + + QueryBuilder + thenByPackage() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'package', Sort.asc); + }); + } + + QueryBuilder + thenByPackageDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'package', Sort.desc); + }); + } + + QueryBuilder thenByTitle() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'title', Sort.asc); + }); + } + + QueryBuilder + thenByTitleDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'title', Sort.desc); + }); + } + + QueryBuilder thenByType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.asc); + }); + } + + QueryBuilder + thenByTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.desc); + }); + } + + QueryBuilder thenByValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.asc); + }); + } + + QueryBuilder + thenByValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.desc); + }); + } +} + +extension ExtensionSettingQueryWhereDistinct + on QueryBuilder { + QueryBuilder + distinctByDefaultValue({bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'defaultValue', caseSensitive: caseSensitive); + }); + } + + QueryBuilder + distinctByDescription({bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'description', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByKey( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'key', caseSensitive: caseSensitive); + }); + } + + QueryBuilder + distinctByOptions() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'options'); + }); + } + + QueryBuilder distinctByPackage( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'package', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByTitle( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'title', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByType( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'type', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByValue( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'value', caseSensitive: caseSensitive); + }); + } +} + +extension ExtensionSettingQueryProperty + on QueryBuilder { + QueryBuilder idProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'id'); + }); + } + + QueryBuilder + defaultValueProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'defaultValue'); + }); + } + + QueryBuilder + descriptionProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'description'); + }); + } + + QueryBuilder keyProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'key'); + }); + } + + QueryBuilder?, QQueryOperations> + optionsProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'options'); + }); + } + + QueryBuilder packageProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'package'); + }); + } + + QueryBuilder titleProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'title'); + }); + } + + QueryBuilder + typeProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'type'); + }); + } + + QueryBuilder valueProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'value'); + }); + } +} diff --git a/lib/models/history.g.dart b/lib/models/history.g.dart index e2641a60..e466f106 100644 --- a/lib/models/history.g.dart +++ b/lib/models/history.g.dart @@ -32,19 +32,19 @@ const HistorySchema = CollectionSchema( name: r'episodeGroupId', type: IsarType.long, ), - r'package': PropertySchema( + r'episodeId': PropertySchema( id: 3, - name: r'package', - type: IsarType.string, + name: r'episodeId', + type: IsarType.long, ), - r'progress': PropertySchema( + r'episodeTitle': PropertySchema( id: 4, - name: r'progress', - type: IsarType.long, + name: r'episodeTitle', + type: IsarType.string, ), - r'progressTitle': PropertySchema( + r'package': PropertySchema( id: 5, - name: r'progressTitle', + name: r'package', type: IsarType.string, ), r'title': PropertySchema( @@ -104,8 +104,8 @@ int _historyEstimateSize( ) { var bytesCount = offsets.last; bytesCount += 3 + object.cover.length * 3; - bytesCount += 3 + object.package.length * 3; bytesCount += 3 + object.episodeTitle.length * 3; + bytesCount += 3 + object.package.length * 3; bytesCount += 3 + object.title.length * 3; bytesCount += 3 + object.type.name.length * 3; bytesCount += 3 + object.url.length * 3; @@ -121,9 +121,9 @@ void _historySerialize( writer.writeString(offsets[0], object.cover); writer.writeDateTime(offsets[1], object.date); writer.writeLong(offsets[2], object.episodeGroupId); - writer.writeString(offsets[3], object.package); - writer.writeLong(offsets[4], object.episodeId); - writer.writeString(offsets[5], object.episodeTitle); + writer.writeLong(offsets[3], object.episodeId); + writer.writeString(offsets[4], object.episodeTitle); + writer.writeString(offsets[5], object.package); writer.writeString(offsets[6], object.title); writer.writeString(offsets[7], object.type.name); writer.writeString(offsets[8], object.url); @@ -139,10 +139,10 @@ History _historyDeserialize( object.cover = reader.readString(offsets[0]); object.date = reader.readDateTime(offsets[1]); object.episodeGroupId = reader.readLong(offsets[2]); + object.episodeId = reader.readLong(offsets[3]); + object.episodeTitle = reader.readString(offsets[4]); object.id = id; - object.package = reader.readString(offsets[3]); - object.episodeId = reader.readLong(offsets[4]); - object.episodeTitle = reader.readString(offsets[5]); + object.package = reader.readString(offsets[5]); object.title = reader.readString(offsets[6]); object.type = _HistorytypeValueEnumMap[reader.readStringOrNull(offsets[7])] ?? ExtensionType.manga; @@ -164,9 +164,9 @@ P _historyDeserializeProp

( case 2: return (reader.readLong(offset)) as P; case 3: - return (reader.readString(offset)) as P; - case 4: return (reader.readLong(offset)) as P; + case 4: + return (reader.readString(offset)) as P; case 5: return (reader.readString(offset)) as P; case 6: @@ -608,50 +608,51 @@ extension HistoryQueryFilter }); } - QueryBuilder idEqualTo(Id value) { + QueryBuilder episodeIdEqualTo( + int value) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'id', + property: r'episodeId', value: value, )); }); } - QueryBuilder idGreaterThan( - Id value, { + QueryBuilder episodeIdGreaterThan( + int value, { bool include = false, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( include: include, - property: r'id', + property: r'episodeId', value: value, )); }); } - QueryBuilder idLessThan( - Id value, { + QueryBuilder episodeIdLessThan( + int value, { bool include = false, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.lessThan( include: include, - property: r'id', + property: r'episodeId', value: value, )); }); } - QueryBuilder idBetween( - Id lower, - Id upper, { + QueryBuilder episodeIdBetween( + int lower, + int upper, { bool includeLower = true, bool includeUpper = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.between( - property: r'id', + property: r'episodeId', lower: lower, includeLower: includeLower, upper: upper, @@ -660,20 +661,20 @@ extension HistoryQueryFilter }); } - QueryBuilder packageEqualTo( + QueryBuilder episodeTitleEqualTo( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageGreaterThan( + QueryBuilder episodeTitleGreaterThan( String value, { bool include = false, bool caseSensitive = true, @@ -681,14 +682,14 @@ extension HistoryQueryFilter return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( include: include, - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageLessThan( + QueryBuilder episodeTitleLessThan( String value, { bool include = false, bool caseSensitive = true, @@ -696,14 +697,14 @@ extension HistoryQueryFilter return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.lessThan( include: include, - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageBetween( + QueryBuilder episodeTitleBetween( String lower, String upper, { bool includeLower = true, @@ -712,7 +713,7 @@ extension HistoryQueryFilter }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.between( - property: r'package', + property: r'episodeTitle', lower: lower, includeLower: includeLower, upper: upper, @@ -722,119 +723,119 @@ extension HistoryQueryFilter }); } - QueryBuilder packageStartsWith( + QueryBuilder episodeTitleStartsWith( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.startsWith( - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageEndsWith( + QueryBuilder episodeTitleEndsWith( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.endsWith( - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageContains( + QueryBuilder episodeTitleContains( String value, {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.contains( - property: r'package', + property: r'episodeTitle', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageMatches( + QueryBuilder episodeTitleMatches( String pattern, {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.matches( - property: r'package', + property: r'episodeTitle', wildcard: pattern, caseSensitive: caseSensitive, )); }); } - QueryBuilder packageIsEmpty() { + QueryBuilder episodeTitleIsEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'package', + property: r'episodeTitle', value: '', )); }); } - QueryBuilder packageIsNotEmpty() { + QueryBuilder + episodeTitleIsNotEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( - property: r'package', + property: r'episodeTitle', value: '', )); }); } - QueryBuilder progressEqualTo( - int value) { + QueryBuilder idEqualTo(Id value) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'progress', + property: r'id', value: value, )); }); } - QueryBuilder progressGreaterThan( - int value, { + QueryBuilder idGreaterThan( + Id value, { bool include = false, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( include: include, - property: r'progress', + property: r'id', value: value, )); }); } - QueryBuilder progressLessThan( - int value, { + QueryBuilder idLessThan( + Id value, { bool include = false, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.lessThan( include: include, - property: r'progress', + property: r'id', value: value, )); }); } - QueryBuilder progressBetween( - int lower, - int upper, { + QueryBuilder idBetween( + Id lower, + Id upper, { bool includeLower = true, bool includeUpper = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.between( - property: r'progress', + property: r'id', lower: lower, includeLower: includeLower, upper: upper, @@ -843,21 +844,20 @@ extension HistoryQueryFilter }); } - QueryBuilder progressTitleEqualTo( + QueryBuilder packageEqualTo( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder - progressTitleGreaterThan( + QueryBuilder packageGreaterThan( String value, { bool include = false, bool caseSensitive = true, @@ -865,14 +865,14 @@ extension HistoryQueryFilter return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( include: include, - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleLessThan( + QueryBuilder packageLessThan( String value, { bool include = false, bool caseSensitive = true, @@ -880,14 +880,14 @@ extension HistoryQueryFilter return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.lessThan( include: include, - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleBetween( + QueryBuilder packageBetween( String lower, String upper, { bool includeLower = true, @@ -896,7 +896,7 @@ extension HistoryQueryFilter }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.between( - property: r'progressTitle', + property: r'package', lower: lower, includeLower: includeLower, upper: upper, @@ -906,70 +906,69 @@ extension HistoryQueryFilter }); } - QueryBuilder progressTitleStartsWith( + QueryBuilder packageStartsWith( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.startsWith( - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleEndsWith( + QueryBuilder packageEndsWith( String value, { bool caseSensitive = true, }) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.endsWith( - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleContains( + QueryBuilder packageContains( String value, {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.contains( - property: r'progressTitle', + property: r'package', value: value, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleMatches( + QueryBuilder packageMatches( String pattern, {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.matches( - property: r'progressTitle', + property: r'package', wildcard: pattern, caseSensitive: caseSensitive, )); }); } - QueryBuilder progressTitleIsEmpty() { + QueryBuilder packageIsEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'progressTitle', + property: r'package', value: '', )); }); } - QueryBuilder - progressTitleIsNotEmpty() { + QueryBuilder packageIsNotEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( - property: r'progressTitle', + property: r'package', value: '', )); }); @@ -1409,39 +1408,39 @@ extension HistoryQuerySortBy on QueryBuilder { }); } - QueryBuilder sortByPackage() { + QueryBuilder sortByEpisodeId() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'package', Sort.asc); + return query.addSortBy(r'episodeId', Sort.asc); }); } - QueryBuilder sortByPackageDesc() { + QueryBuilder sortByEpisodeIdDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'package', Sort.desc); + return query.addSortBy(r'episodeId', Sort.desc); }); } - QueryBuilder sortByProgress() { + QueryBuilder sortByEpisodeTitle() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progress', Sort.asc); + return query.addSortBy(r'episodeTitle', Sort.asc); }); } - QueryBuilder sortByProgressDesc() { + QueryBuilder sortByEpisodeTitleDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progress', Sort.desc); + return query.addSortBy(r'episodeTitle', Sort.desc); }); } - QueryBuilder sortByProgressTitle() { + QueryBuilder sortByPackage() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progressTitle', Sort.asc); + return query.addSortBy(r'package', Sort.asc); }); } - QueryBuilder sortByProgressTitleDesc() { + QueryBuilder sortByPackageDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progressTitle', Sort.desc); + return query.addSortBy(r'package', Sort.desc); }); } @@ -1520,51 +1519,51 @@ extension HistoryQuerySortThenBy }); } - QueryBuilder thenById() { + QueryBuilder thenByEpisodeId() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'id', Sort.asc); + return query.addSortBy(r'episodeId', Sort.asc); }); } - QueryBuilder thenByIdDesc() { + QueryBuilder thenByEpisodeIdDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'id', Sort.desc); + return query.addSortBy(r'episodeId', Sort.desc); }); } - QueryBuilder thenByPackage() { + QueryBuilder thenByEpisodeTitle() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'package', Sort.asc); + return query.addSortBy(r'episodeTitle', Sort.asc); }); } - QueryBuilder thenByPackageDesc() { + QueryBuilder thenByEpisodeTitleDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'package', Sort.desc); + return query.addSortBy(r'episodeTitle', Sort.desc); }); } - QueryBuilder thenByProgress() { + QueryBuilder thenById() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progress', Sort.asc); + return query.addSortBy(r'id', Sort.asc); }); } - QueryBuilder thenByProgressDesc() { + QueryBuilder thenByIdDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progress', Sort.desc); + return query.addSortBy(r'id', Sort.desc); }); } - QueryBuilder thenByProgressTitle() { + QueryBuilder thenByPackage() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progressTitle', Sort.asc); + return query.addSortBy(r'package', Sort.asc); }); } - QueryBuilder thenByProgressTitleDesc() { + QueryBuilder thenByPackageDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'progressTitle', Sort.desc); + return query.addSortBy(r'package', Sort.desc); }); } @@ -1626,24 +1625,23 @@ extension HistoryQueryWhereDistinct }); } - QueryBuilder distinctByPackage( - {bool caseSensitive = true}) { + QueryBuilder distinctByEpisodeId() { return QueryBuilder.apply(this, (query) { - return query.addDistinctBy(r'package', caseSensitive: caseSensitive); + return query.addDistinctBy(r'episodeId'); }); } - QueryBuilder distinctByProgress() { + QueryBuilder distinctByEpisodeTitle( + {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { - return query.addDistinctBy(r'progress'); + return query.addDistinctBy(r'episodeTitle', caseSensitive: caseSensitive); }); } - QueryBuilder distinctByProgressTitle( + QueryBuilder distinctByPackage( {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { - return query.addDistinctBy(r'progressTitle', - caseSensitive: caseSensitive); + return query.addDistinctBy(r'package', caseSensitive: caseSensitive); }); } @@ -1695,21 +1693,21 @@ extension HistoryQueryProperty }); } - QueryBuilder packageProperty() { + QueryBuilder episodeIdProperty() { return QueryBuilder.apply(this, (query) { - return query.addPropertyName(r'package'); + return query.addPropertyName(r'episodeId'); }); } - QueryBuilder progressProperty() { + QueryBuilder episodeTitleProperty() { return QueryBuilder.apply(this, (query) { - return query.addPropertyName(r'progress'); + return query.addPropertyName(r'episodeTitle'); }); } - QueryBuilder progressTitleProperty() { + QueryBuilder packageProperty() { return QueryBuilder.apply(this, (query) { - return query.addPropertyName(r'progressTitle'); + return query.addPropertyName(r'package'); }); } diff --git a/lib/pages/detail/widgets/detail_continue_play.dart b/lib/pages/detail/widgets/detail_continue_play.dart index effdb840..a52d03c0 100644 --- a/lib/pages/detail/widgets/detail_continue_play.dart +++ b/lib/pages/detail/widgets/detail_continue_play.dart @@ -37,7 +37,8 @@ class _DetailContinuePlayState extends State { if (c.isLoading.value) { return noEpisodes; } - if (c.history.value != null) { + // 之前弄错了,所以需要判断标题是否为空 + if (c.history.value != null && c.history.value!.episodeTitle.isNotEmpty) { return FilledButton.icon( onPressed: () { c.goWatch( @@ -91,7 +92,7 @@ class _DetailContinuePlayState extends State { return Obx(() { final history = c.history.value; final data = c.data.value!; - if (history != null) { + if (history != null && c.history.value!.episodeTitle.isNotEmpty) { return fluent.FilledButton( onPressed: () { c.goWatch( diff --git a/lib/pages/detail/widgets/detail_episodes.dart b/lib/pages/detail/widgets/detail_episodes.dart index 3ab721fc..6f66e33d 100644 --- a/lib/pages/detail/widgets/detail_episodes.dart +++ b/lib/pages/detail/widgets/detail_episodes.dart @@ -5,7 +5,7 @@ import 'package:get/get.dart'; import 'package:miru_app/models/extension.dart'; import 'package:miru_app/pages/detail/controller.dart'; import 'package:miru_app/pages/detail/widgets/detail_continue_play.dart'; -import 'package:miru_app/pages/detail/widgets/detail_tile.dart'; +import 'package:miru_app/widgets/card_tile.dart'; import 'package:miru_app/utils/i18n.dart'; import 'package:miru_app/widgets/platform_widget.dart'; @@ -94,7 +94,7 @@ class _DetailEpisodesState extends State { } Widget _buildDesktopEpisodes(BuildContext context) { - return DetailTile( + return CardTile( title: 'detail.episodes'.i18n, trailing: Row( children: [ diff --git a/lib/pages/extension/widgets/extension_tile.dart b/lib/pages/extension/widgets/extension_tile.dart index 32ad73ec..a6114ce7 100644 --- a/lib/pages/extension/widgets/extension_tile.dart +++ b/lib/pages/extension/widgets/extension_tile.dart @@ -1,12 +1,13 @@ import 'package:fluent_ui/fluent_ui.dart' as fluent; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:miru_app/main.dart'; import 'package:miru_app/models/extension.dart'; import 'package:miru_app/pages/code_edit/view.dart'; +import 'package:miru_app/pages/extension_settings/view.dart'; import 'package:miru_app/utils/extension.dart'; import 'package:miru_app/utils/i18n.dart'; import 'package:miru_app/widgets/cache_network_image.dart'; -import 'package:miru_app/widgets/messenger.dart'; import 'package:miru_app/widgets/platform_widget.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:path/path.dart' as path; @@ -40,7 +41,7 @@ class _ExtensionTileState extends State { '${widget.extension.version} ${ExtensionUtils.typeToString(widget.extension.type)} ', ), onTap: () { - showPlatformSnackbar(context: context, title: '😣', content: '还没写的('); + Get.to(ExtensionSettingsPage(package: widget.extension.package)); }, trailing: IconButton( onPressed: () { @@ -121,11 +122,10 @@ class _ExtensionTileState extends State { child: Text('common.settings'.i18n), ), onPressed: () { - fluent.displayInfoBar(context, builder: (builder, colse) { - return const fluent.InfoBar( - title: Text("还没做的"), - ); - }); + router.push(Uri( + path: '/extension_settings', + queryParameters: {'package': widget.extension.package}, + ).toString()); }), const SizedBox(width: 16), fluent.FlyoutTarget( diff --git a/lib/pages/extension_settings/controller.dart b/lib/pages/extension_settings/controller.dart new file mode 100644 index 00000000..e9c0a939 --- /dev/null +++ b/lib/pages/extension_settings/controller.dart @@ -0,0 +1,26 @@ +import 'package:get/get.dart'; +import 'package:miru_app/models/extension_setting.dart'; +import 'package:miru_app/utils/database.dart'; +import 'package:miru_app/utils/extension.dart'; +import 'package:miru_app/utils/extension_runtime.dart'; + +class ExtensionSettingsPageController extends GetxController { + ExtensionSettingsPageController(this.package); + final String package; + + final Rx runtime = Rx(null); + + final List settings = [].obs; + + @override + void onInit() { + onRefresh(); + super.onInit(); + } + + onRefresh() async { + runtime.value = ExtensionUtils.extensions[package]; + settings.clear(); + settings.addAll(await DatabaseUtils.getExtensionSettings(package)); + } +} diff --git a/lib/pages/extension_settings/view.dart b/lib/pages/extension_settings/view.dart new file mode 100644 index 00000000..facf559a --- /dev/null +++ b/lib/pages/extension_settings/view.dart @@ -0,0 +1,400 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:fluent_ui/fluent_ui.dart' as fluent; +import 'package:get/get.dart'; +import 'package:miru_app/main.dart'; +import 'package:miru_app/models/extension_setting.dart'; +import 'package:miru_app/pages/code_edit/view.dart'; +import 'package:miru_app/pages/extension_settings/controller.dart'; +import 'package:miru_app/pages/extension_settings/widgets/info_card.dart'; +import 'package:miru_app/utils/database.dart'; +import 'package:miru_app/utils/extension.dart'; +import 'package:miru_app/utils/i18n.dart'; +import 'package:miru_app/widgets/cache_network_image.dart'; +import 'package:miru_app/widgets/card_tile.dart'; +import 'package:miru_app/widgets/platform_widget.dart'; +import 'package:miru_app/widgets/progress_ring.dart'; +import 'package:miru_app/widgets/settings_input_tile.dart'; +import 'package:miru_app/widgets/settings_radios_tile.dart'; +import 'package:miru_app/widgets/settings_switch_tile.dart'; + +class ExtensionSettingsPage extends StatefulWidget { + const ExtensionSettingsPage({ + Key? key, + required this.package, + }) : super(key: key); + final String package; + + @override + State createState() => _ExtensionSettingsPageState(); +} + +class _ExtensionSettingsPageState extends State { + late ExtensionSettingsPageController c; + + @override + void initState() { + c = Get.put( + ExtensionSettingsPageController(widget.package), + tag: widget.package, + ); + super.initState(); + } + + @override + void dispose() { + Get.delete(tag: widget.package); + super.dispose(); + } + + List settingsContent() { + final list = []; + + for (final setting in c.settings) { + if (setting.type == ExtensionSettingType.input) { + list.add(SettingsIntpuTile( + title: setting.title, + onChanged: (value) async { + await DatabaseUtils.putExtensionSetting( + setting.package, + setting.key, + value, + ); + setting.value = value; + setState(() {}); + }, + text: setting.value ?? setting.defaultValue, + buildSubtitle: () { + if (Platform.isAndroid) { + return '${setting.value ?? setting.defaultValue}\n${setting.description ?? ''}'; + } + return setting.description ?? ''; + }, + )); + } + if (setting.type == ExtensionSettingType.radio) { + final map = {}; + list.add(SettingsRadiosTile( + title: setting.title, + itemNameValue: () { + for (final item in setting.options!) { + final split = item.split(':'); + map[split[0]] = split[1]; + } + return map; + }(), + buildSubtitle: () => setting.description ?? '', + applyValue: (value) { + DatabaseUtils.putExtensionSetting( + setting.package, + setting.key, + value, + ); + setting.value = value; + setState(() {}); + }, + buildGroupValue: () => setting.value ?? setting.defaultValue, + trailing: Text( + map.entries + .firstWhere((element) => element.value == setting.value) + .key, + ), + )); + } + if (setting.type == ExtensionSettingType.toggle) { + list.add(SettingsSwitchTile( + title: setting.title, + onChanged: (value) { + DatabaseUtils.putExtensionSetting( + setting.package, + setting.key, + value.toString(), + ); + setting.value = value.toString(); + }, + buildSubtitle: () => setting.description ?? '', + buildValue: () { + return (setting.value ?? setting.defaultValue).toLowerCase() == + 'true'; + }, + )); + } + list.add(const SizedBox(height: 8)); + } + return list; + } + + Widget _buildAndroid(BuildContext context) { + return Obx(() { + if (c.runtime.value == null) { + return const Center( + child: ProgressRing(), + ); + } + final extension = c.runtime.value!.extension; + return Scaffold( + appBar: AppBar( + title: Text('extension-info.title'.i18n), + ), + body: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 30), + Center( + child: Container( + height: 100, + width: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + ), + clipBehavior: Clip.antiAlias, + child: CacheNetWorkImage( + extension.icon ?? '', + fit: BoxFit.contain, + ), + ), + ), + const SizedBox(height: 16), + Text( + extension.name, + style: Theme.of(context).textTheme.titleLarge, + ), + Text( + extension.package, + style: Theme.of(context).textTheme.bodySmall, + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: GridView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 3, + crossAxisSpacing: 2, + mainAxisSpacing: 8, + ), + children: [ + InfoCard( + icon: Icons.person, + title: 'extension-info.author'.i18n, + content: extension.author, + ), + InfoCard( + icon: Icons.info, + title: 'extension-info.version'.i18n, + content: extension.version, + ), + InfoCard( + icon: Icons.language, + title: 'extension-info.language'.i18n, + content: extension.lang, + ), + InfoCard( + icon: Icons.description, + title: 'extension-info.license'.i18n, + content: extension.license, + ), + InfoCard( + icon: Icons.link, + title: 'extension-info.original-site'.i18n, + content: extension.webSite, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: OutlinedButton( + onPressed: () async { + await ExtensionUtils.uninstall(extension.package); + Get.back(); + }, + child: Text('common.uninstall'.i18n), + ), + ), + const SizedBox(width: 16), + Expanded( + child: FilledButton( + onPressed: () { + Get.to(CodeEditPage(extension: extension)); + }, + child: Text('extension.edit-code'.i18n), + ), + ) + ], + ), + ), + if (c.settings.isNotEmpty) ...[ + const Divider(), + ...settingsContent(), + ] + ], + ), + ), + ); + }); + } + + Widget _buildDesktop(BuildContext context) { + return Obx(() { + if (c.runtime.value == null) { + return const Center( + child: ProgressRing(), + ); + } + + final extension = c.runtime.value!.extension; + return Padding( + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 320, + child: fluent.Card( + borderRadius: BorderRadius.circular(10), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 100, + width: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + ), + clipBehavior: Clip.antiAlias, + child: CacheNetWorkImage( + extension.icon ?? '', + fit: BoxFit.contain, + ), + ), + const SizedBox(height: 16), + SelectableText( + extension.name, + style: + fluent.FluentTheme.of(context).typography.bodyLarge, + ), + Text( + extension.package, + style: fluent.FluentTheme.of(context).typography.body, + ), + const SizedBox(height: 16), + fluent.FilledButton( + onPressed: () async { + await ExtensionUtils.uninstall(extension.package); + router.pop(); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 2), + child: Text('common.uninstall'.i18n), + ), + ), + const SizedBox(height: 50), + fluent.Card( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 4, + ), + borderRadius: BorderRadius.circular(100), + child: Text( + ExtensionUtils.typeToString(extension.type), + ), + ), + ], + ), + ), + ), + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.only(left: 16), + child: Obx( + () => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (extension.description != null) ...[ + CardTile( + title: 'extension-info.description'.i18n, + child: SelectableText( + extension.description!, + ), + ), + const SizedBox(height: 16), + ], + CardTile( + title: 'extension-info.other-infomation'.i18n, + child: GridView( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 16, + mainAxisSpacing: 10, + childAspectRatio: 3, + ), + shrinkWrap: true, + children: [ + InfoCard( + icon: fluent.FluentIcons.contact, + title: 'extension-info.author'.i18n, + content: extension.author, + ), + InfoCard( + icon: fluent.FluentIcons.code, + title: 'extension-info.version'.i18n, + content: extension.version, + ), + InfoCard( + icon: fluent.FluentIcons.locale_language, + title: 'extension-info.language'.i18n, + content: extension.lang, + ), + InfoCard( + icon: fluent.FluentIcons.page, + title: 'extension-info.license'.i18n, + content: extension.license, + ), + InfoCard( + icon: fluent.FluentIcons.globe, + title: 'extension-info.original-site'.i18n, + content: extension.webSite, + ), + ], + ), + ), + const SizedBox(height: 16), + if (c.settings.isNotEmpty) ...[ + Text( + 'common.settings'.i18n, + style: fluent.FluentTheme.of(context) + .typography + .subtitle, + ), + const SizedBox(height: 16), + ...settingsContent(), + const SizedBox(height: 16), + ], + ], + ), + ), + ), + ) + ], + ), + ); + }); + } + + @override + Widget build(BuildContext context) { + return PlatformBuildWidget( + androidBuilder: _buildAndroid, + desktopBuilder: _buildDesktop, + ); + } +} diff --git a/lib/pages/extension_settings/widgets/info_card.dart b/lib/pages/extension_settings/widgets/info_card.dart new file mode 100644 index 00000000..16dcb392 --- /dev/null +++ b/lib/pages/extension_settings/widgets/info_card.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:miru_app/widgets/platform_widget.dart'; + +class InfoCard extends StatelessWidget { + const InfoCard({ + Key? key, + required this.icon, + required this.title, + required this.content, + }) : super(key: key); + final IconData icon; + final String title; + final String content; + + @override + Widget build(BuildContext context) { + return PlatformWidget( + androidWidget: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + content, + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 4), + Expanded( + child: Text( + title, + style: Theme.of(context).textTheme.labelMedium!.copyWith( + color: Theme.of(context).colorScheme.secondary, + ), + )), + ], + ), + desktopWidget: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + icon, + size: 14, + ), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title), + const SizedBox(height: 4), + Text(content), + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index b1467a49..975b771d 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -41,7 +41,7 @@ class _HomePageState extends State { ), const SizedBox(height: 16), Text( - "no record".i18n, + "home.no-record".i18n, ), ], ), diff --git a/lib/pages/settings/view.dart b/lib/pages/settings/view.dart index 8c3850c5..eb807cb6 100644 --- a/lib/pages/settings/view.dart +++ b/lib/pages/settings/view.dart @@ -7,10 +7,10 @@ import 'package:get/get.dart'; import 'package:miru_app/pages/extension_repo/controller.dart'; import 'package:miru_app/pages/main/controller.dart'; import 'package:miru_app/pages/settings/controller.dart'; -import 'package:miru_app/pages/settings/widgets/settings_input_tile.dart'; -import 'package:miru_app/pages/settings/widgets/settings_radios_tile.dart'; -import 'package:miru_app/pages/settings/widgets/settings_switch_tile.dart'; -import 'package:miru_app/pages/settings/widgets/settings_tile.dart'; +import 'package:miru_app/widgets/settings_input_tile.dart'; +import 'package:miru_app/widgets/settings_radios_tile.dart'; +import 'package:miru_app/widgets/settings_switch_tile.dart'; +import 'package:miru_app/widgets/settings_tile.dart'; import 'package:miru_app/utils/i18n.dart'; import 'package:miru_app/utils/miru_storage.dart'; import 'package:miru_app/utils/package_info.dart'; diff --git a/lib/utils/database.dart b/lib/utils/database.dart index c47a66e1..68d04550 100644 --- a/lib/utils/database.dart +++ b/lib/utils/database.dart @@ -1,5 +1,7 @@ +import 'package:fluent_ui/fluent_ui.dart'; import 'package:isar/isar.dart'; import 'package:miru_app/models/extension.dart'; +import 'package:miru_app/models/extension_setting.dart'; import 'package:miru_app/models/favorite.dart'; import 'package:miru_app/models/history.dart'; import 'package:miru_app/utils/extension.dart'; @@ -94,4 +96,90 @@ class DatabaseUtils { return db.writeTxn(() => db.historys.put(history)); } + + // 扩展设置 + // 获取扩展设置 + static Future> getExtensionSettings(String package) { + return db.extensionSettings.filter().packageEqualTo(package).findAll(); + } + + // 更新扩展设置 + static Future putExtensionSetting( + String package, String key, String value) async { + final extensionSetting = await getExtensionSetting(package, key); + if (extensionSetting == null) { + return null; + } + extensionSetting.value = value; + debugPrint(extensionSetting.value); + return db.writeTxn(() => db.extensionSettings.put(extensionSetting)); + } + + // 获取扩展设置 + static Future getExtensionSetting( + String package, String key) async { + return db.extensionSettings + .filter() + .packageEqualTo(package) + .and() + .keyEqualTo(key) + .findFirst(); + } + + // 添加扩展设置 + static Future addExtensionSetting( + ExtensionSetting extensionSetting, + ) async { + if (extensionSetting.type == ExtensionSettingType.radio && + extensionSetting.options == null) { + throw Exception('options is null'); + } + + final extSetting = await getExtensionSetting( + extensionSetting.package, extensionSetting.key); + // 如果不存在相同设置,则添加 + if (extSetting == null) { + return db.writeTxn(() => db.extensionSettings.put(extensionSetting)); + } + + extSetting.defaultValue = extensionSetting.defaultValue; + + // 如果类型不同,重置值 + if (extSetting.type != extensionSetting.type) { + extSetting.type = extensionSetting.type; + } + extSetting.value = extensionSetting.defaultValue; + extSetting.defaultValue = extensionSetting.defaultValue; + extSetting.description = extensionSetting.description; + extSetting.options = extensionSetting.options; + extSetting.title = extensionSetting.title; + return db.writeTxn(() => db.extensionSettings.put(extSetting)); + } + + // 删除扩展设置 + static Future deleteExtensionSetting(String package) async { + return db.writeTxn( + () => db.extensionSettings.filter().packageEqualTo(package).deleteAll(), + ); + } + + // 清理不需要的扩展设置 + static Future cleanExtensionSettings( + String package, + List keys, + ) async { + // 需要删除的 id; + final ids = []; + + final extSettings = + await db.extensionSettings.filter().packageEqualTo(package).findAll(); + + for (final extSetting in extSettings) { + if (!keys.contains(extSetting.key)) { + ids.add(extSetting.id); + } + } + + return db.writeTxn(() => db.extensionSettings.deleteAll(ids)); + } } diff --git a/lib/utils/extension_runtime.dart b/lib/utils/extension_runtime.dart index eaf74ded..5051f961 100644 --- a/lib/utils/extension_runtime.dart +++ b/lib/utils/extension_runtime.dart @@ -2,8 +2,11 @@ import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_js/flutter_js.dart'; import 'package:miru_app/models/extension.dart'; +import 'package:miru_app/models/extension_setting.dart'; +import 'package:miru_app/utils/database.dart'; import 'package:miru_app/utils/extension.dart'; class ExtensionRuntime { @@ -22,6 +25,7 @@ class ExtensionRuntime { runtime = getJavascriptRuntime(); // 注册方法 + // 日志 runtime.onMessage('log', (dynamic args) { ExtensionUtils.addLog( extension, @@ -29,6 +33,7 @@ class ExtensionRuntime { args[0], ); }); + // 请求 runtime.onMessage('request', (dynamic args) async { ExtensionUtils.addLog( extension, @@ -42,6 +47,44 @@ class ExtensionRuntime { ))) .data; }); + + // 设置 + runtime.onMessage('registerSetting', (dynamic args) async { + args[0]['package'] = extension.package; + + List? options; + if (args[0]['options'] != null) { + options = []; + for (final option in (args[0]['options'] as Map).entries) { + options.add('${option.key}:${option.value}'); + } + } + + return DatabaseUtils.addExtensionSetting( + ExtensionSetting() + ..package = extension.package + ..title = args[0]['title'] + ..key = args[0]['key'] + ..value = args[0]['value'] + ..type = ExtensionSetting.stringToType(args[0]['type']) + ..description = args[0]['description'] + ..defaultValue = args[0]['defaultValue'] + ..options = options, + ); + }); + runtime.onMessage('getSetting', (dynamic args) async { + final setting = + await DatabaseUtils.getExtensionSetting(extension.package, args[0]); + return setting?.value; + }); + + // 清理扩展设置 + runtime.onMessage('cleanSettings', (dynamic args) async { + debugPrint('cleanSettings: ${args[0]}'); + return DatabaseUtils.cleanExtensionSettings( + extension.package, List.from(args[0])); + }); + // 初始化运行扩展 await _initRunExtension(content); return this; @@ -52,9 +95,16 @@ class ExtensionRuntime { // 重写 console.log var window = global = globalThis; console.log = function (message) { + if (typeof message === "object") { + message = JSON.stringify(message); + } sendMessage("log", JSON.stringify([message.toString()])); }; class Extension { + package = "${extension.package}"; + name = "${extension.name}"; + // 在 load 中注册的 keys + settingKeys = []; async request(url, options) { options = options || {}; options.headers = options.headers || {}; @@ -83,13 +133,16 @@ class ExtensionRuntime { throw new Error("not implement"); } async getSetting(key) { - return ""; + return sendMessage("getSetting", JSON.stringify([key])); + } + async registerSetting(settings) { + console.log(JSON.stringify([settings])); + this.settingKeys.push(settings.key) + return sendMessage("registerSetting", JSON.stringify([settings])); } - async registerSetting(settings) {} - load() {} - unload() {} + async load() {} } - + async function stringify(callback){ const data = await callback(); return typeof data === "object" ? JSON.stringify(data) : data; @@ -102,6 +155,9 @@ class ExtensionRuntime { JsEvalResult jsResult = await runtime.evaluateAsync(''' $ext var extenstion = new Ext(); + extenstion.load().then(()=>{ + sendMessage("cleanSettings", JSON.stringify([extenstion.settingKeys])); + }); '''); await runtime.handlePromise(jsResult); } diff --git a/lib/utils/miru_storage.dart b/lib/utils/miru_storage.dart index fa4ccc79..1817e809 100644 --- a/lib/utils/miru_storage.dart +++ b/lib/utils/miru_storage.dart @@ -1,5 +1,6 @@ import 'package:hive_flutter/adapters.dart'; import 'package:isar/isar.dart'; +import 'package:miru_app/models/extension_setting.dart'; import 'package:miru_app/models/favorite.dart'; import 'package:miru_app/models/history.dart'; import 'package:miru_app/utils/miru_directory.dart'; @@ -12,7 +13,7 @@ class MiruStorage { final path = await MiruDirectory.getDirectory; // 初始化数据库 database = await Isar.open( - [FavoriteSchema, HistorySchema], + [FavoriteSchema, HistorySchema, ExtensionSettingSchema], directory: path, ); // 初始化设置 diff --git a/lib/pages/detail/widgets/detail_tile.dart b/lib/widgets/card_tile.dart similarity index 92% rename from lib/pages/detail/widgets/detail_tile.dart rename to lib/widgets/card_tile.dart index 2b275df0..9d0bfddc 100644 --- a/lib/pages/detail/widgets/detail_tile.dart +++ b/lib/widgets/card_tile.dart @@ -1,7 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; -class DetailTile extends StatelessWidget { - const DetailTile({ +class CardTile extends StatelessWidget { + const CardTile({ Key? key, required this.title, required this.child, @@ -16,7 +16,7 @@ class DetailTile extends StatelessWidget { return Container( padding: const EdgeInsets.symmetric(vertical: 13), decoration: BoxDecoration( - color: FluentTheme.of(context).acrylicBackgroundColor, + color: FluentTheme.of(context).cardColor, borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.grey.withOpacity(0.1), width: 1), ), diff --git a/lib/pages/settings/widgets/settings_input_tile.dart b/lib/widgets/settings_input_tile.dart similarity index 91% rename from lib/pages/settings/widgets/settings_input_tile.dart rename to lib/widgets/settings_input_tile.dart index 0af9b3f4..cf9cc5a8 100644 --- a/lib/pages/settings/widgets/settings_input_tile.dart +++ b/lib/widgets/settings_input_tile.dart @@ -1,22 +1,24 @@ import 'package:fluent_ui/fluent_ui.dart' as fluent; import 'package:flutter/material.dart'; -import 'package:miru_app/pages/settings/widgets/settings_tile.dart'; import 'package:miru_app/utils/i18n.dart'; import 'package:miru_app/widgets/platform_widget.dart'; +import 'package:miru_app/widgets/settings_tile.dart'; class SettingsIntpuTile extends fluent.StatefulWidget { const SettingsIntpuTile({ Key? key, - required this.icon, + this.icon, required this.title, required this.onChanged, required this.text, required this.buildSubtitle, + this.trailing = const Icon(Icons.chevron_right), }) : super(key: key); - final Widget icon; + final Widget? icon; final String title; final String Function() buildSubtitle; final String text; + final Widget trailing; final Function(String) onChanged; @override @@ -29,6 +31,7 @@ class _SettingsIntpuTileState extends fluent.State { leading: widget.icon, title: Text(widget.title), subtitle: Text(widget.buildSubtitle()), + trailing: widget.trailing, onTap: () { showDialog( context: context, diff --git a/lib/pages/settings/widgets/settings_radios_tile.dart b/lib/widgets/settings_radios_tile.dart similarity index 90% rename from lib/pages/settings/widgets/settings_radios_tile.dart rename to lib/widgets/settings_radios_tile.dart index a2e24c57..708d12e8 100644 --- a/lib/pages/settings/widgets/settings_radios_tile.dart +++ b/lib/widgets/settings_radios_tile.dart @@ -1,24 +1,26 @@ import 'package:fluent_ui/fluent_ui.dart' as fluent; import 'package:flutter/material.dart'; -import 'package:miru_app/pages/settings/widgets/settings_tile.dart'; +import 'package:miru_app/widgets/settings_tile.dart'; import 'package:miru_app/widgets/platform_widget.dart'; class SettingsRadiosTile extends fluent.StatefulWidget { const SettingsRadiosTile({ Key? key, - required this.icon, + this.icon, required this.title, this.buildSubtitle, required this.itemNameValue, required this.applyValue, required this.buildGroupValue, + this.trailing = const Icon(Icons.chevron_right), }) : super(key: key); - final Widget icon; + final Widget? icon; final String title; final String Function()? buildSubtitle; final Function(T value) applyValue; final Map itemNameValue; final T Function() buildGroupValue; + final Widget trailing; @override fluent.State> createState() => @@ -31,7 +33,7 @@ class _SettingsRadiosTileState extends fluent.State> { icon: widget.icon, title: widget.title, buildSubtitle: widget.buildSubtitle, - trailing: const Icon(Icons.chevron_right), + trailing: widget.trailing, onTap: () { showDialog( context: context, @@ -48,6 +50,7 @@ class _SettingsRadiosTileState extends fluent.State> { onChanged: (value) { Navigator.pop(context); widget.applyValue(value as T); + setState(() {}); }, ), ], @@ -74,6 +77,7 @@ class _SettingsRadiosTileState extends fluent.State> { value: widget.buildGroupValue(), onChanged: (value) { widget.applyValue(value as T); + setState(() {}); }, ), ); diff --git a/lib/pages/settings/widgets/settings_switch_tile.dart b/lib/widgets/settings_switch_tile.dart similarity index 91% rename from lib/pages/settings/widgets/settings_switch_tile.dart rename to lib/widgets/settings_switch_tile.dart index 65040e46..fd202a3e 100644 --- a/lib/pages/settings/widgets/settings_switch_tile.dart +++ b/lib/widgets/settings_switch_tile.dart @@ -1,18 +1,18 @@ import 'package:fluent_ui/fluent_ui.dart' as fluent; import 'package:flutter/material.dart'; -import 'package:miru_app/pages/settings/widgets/settings_tile.dart'; +import 'package:miru_app/widgets/settings_tile.dart'; import 'package:miru_app/widgets/platform_widget.dart'; class SettingsSwitchTile extends fluent.StatefulWidget { const SettingsSwitchTile({ Key? key, - required this.icon, + this.icon, required this.title, required this.buildValue, required this.onChanged, this.buildSubtitle, }) : super(key: key); - final Widget icon; + final Widget? icon; final String title; final String Function()? buildSubtitle; final bool Function() buildValue; diff --git a/lib/pages/settings/widgets/settings_tile.dart b/lib/widgets/settings_tile.dart similarity index 91% rename from lib/pages/settings/widgets/settings_tile.dart rename to lib/widgets/settings_tile.dart index 1fccb567..d93265c5 100644 --- a/lib/pages/settings/widgets/settings_tile.dart +++ b/lib/widgets/settings_tile.dart @@ -5,13 +5,13 @@ import 'package:miru_app/widgets/platform_widget.dart'; class SettingsTile extends StatefulWidget { const SettingsTile({ Key? key, - required this.icon, + this.icon, required this.title, this.trailing, this.buildSubtitle, this.onTap, }) : super(key: key); - final Widget icon; + final Widget? icon; final String title; final String Function()? buildSubtitle; final Function()? onTap; @@ -36,8 +36,10 @@ class _SettingsTileState extends State { return fluent.Card( child: Row( children: [ - widget.icon, - const SizedBox(width: 16), + if (widget.icon != null) ...[ + widget.icon!, + const SizedBox(width: 16), + ], Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/pubspec.yaml b/pubspec.yaml index 0bf2bae7..e08f3301 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: miru_app description: A new Flutter project. publish_to: "none" -version: 1.2.1+6 +version: 1.3.0+7 environment: sdk: ">=3.0.3 <4.0.0"