Initial commit
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'shared/settings_persistence.dart';
|
||||
|
||||
|
||||
const kLanguageNames = <String, String>{
|
||||
'chi': '中文',
|
||||
'zho': '中文',
|
||||
'eng': '英语',
|
||||
'jpn': '日语',
|
||||
'kor': '韩语',
|
||||
'fre': '法语',
|
||||
'fra': '法语',
|
||||
'ger': '德语',
|
||||
'deu': '德语',
|
||||
'spa': '西班牙语',
|
||||
'ita': '意大利语',
|
||||
'por': '葡萄牙语',
|
||||
'rus': '俄语',
|
||||
'ara': '阿拉伯语',
|
||||
'hin': '印地语',
|
||||
'tha': '泰语',
|
||||
'vie': '越南语',
|
||||
'pol': '波兰语',
|
||||
'tur': '土耳其语',
|
||||
'dut': '荷兰语',
|
||||
'nld': '荷兰语',
|
||||
'dan': '丹麦语',
|
||||
'fin': '芬兰语',
|
||||
'swe': '瑞典语',
|
||||
'nor': '挪威语',
|
||||
'nob': '书面挪威语',
|
||||
'cat': '加泰罗尼亚语',
|
||||
'cze': '捷克语',
|
||||
'ces': '捷克语',
|
||||
'hun': '匈牙利语',
|
||||
'gre': '希腊语',
|
||||
'ell': '希腊语',
|
||||
'heb': '希伯来语',
|
||||
'ind': '印度尼西亚语',
|
||||
'may': '马来语',
|
||||
'msa': '马来语',
|
||||
'hrv': '克罗地亚语',
|
||||
'baq': '巴斯克语',
|
||||
'eus': '巴斯克语',
|
||||
'glg': '加利西亚语',
|
||||
'fil': '菲律宾语',
|
||||
'rum': '罗马尼亚语',
|
||||
'ron': '罗马尼亚语',
|
||||
'bul': '保加利亚语',
|
||||
'ukr': '乌克兰语',
|
||||
'srp': '塞尔维亚语',
|
||||
'slk': '斯洛伐克语',
|
||||
'slv': '斯洛文尼亚语',
|
||||
'lit': '立陶宛语',
|
||||
'lav': '拉脱维亚语',
|
||||
'est': '爱沙尼亚语',
|
||||
};
|
||||
|
||||
|
||||
class RememberedSubtitleTrack {
|
||||
final int streamIndex;
|
||||
final String? language;
|
||||
final String? title;
|
||||
final DateTime updatedAt;
|
||||
|
||||
const RememberedSubtitleTrack({
|
||||
required this.streamIndex,
|
||||
this.language,
|
||||
this.title,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
bool get isNone => streamIndex == -1;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'streamIndex': streamIndex,
|
||||
if (language != null) 'language': language,
|
||||
if (title != null) 'title': title,
|
||||
'updatedAt': updatedAt.toIso8601String(),
|
||||
};
|
||||
|
||||
factory RememberedSubtitleTrack.fromJson(Map<String, dynamic> json) {
|
||||
return RememberedSubtitleTrack(
|
||||
streamIndex: (json['streamIndex'] as num?)?.toInt() ?? -1,
|
||||
language: json['language'] as String?,
|
||||
title: json['title'] as String?,
|
||||
updatedAt:
|
||||
DateTime.tryParse(json['updatedAt'] as String? ?? '') ??
|
||||
DateTime.now(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SubtitleStyleSettings {
|
||||
final int position;
|
||||
final double fontSize;
|
||||
final double delay;
|
||||
final double bgOpacity;
|
||||
|
||||
const SubtitleStyleSettings({
|
||||
this.position = 100,
|
||||
this.fontSize = 55,
|
||||
this.delay = 0.0,
|
||||
this.bgOpacity = 0.0,
|
||||
});
|
||||
|
||||
SubtitleStyleSettings copyWith({
|
||||
int? position,
|
||||
double? fontSize,
|
||||
double? delay,
|
||||
double? bgOpacity,
|
||||
}) => SubtitleStyleSettings(
|
||||
position: position ?? this.position,
|
||||
fontSize: fontSize ?? this.fontSize,
|
||||
delay: delay ?? this.delay,
|
||||
bgOpacity: bgOpacity ?? this.bgOpacity,
|
||||
);
|
||||
}
|
||||
|
||||
class SubtitleSettingsNotifier extends AsyncNotifier<SubtitleStyleSettings>
|
||||
with SettingsPersistence {
|
||||
static const _keyPosition = 'smplayer.subtitle_position';
|
||||
static const _keyFontSize = 'smplayer.subtitle_font_size';
|
||||
static const _keyDelay = 'smplayer.subtitle_delay';
|
||||
static const _keyBgOpacity = 'smplayer.subtitle_bg_opacity';
|
||||
|
||||
static const _keyLastTracks = 'smplayer.subtitle_last_tracks_primary';
|
||||
static const _maxRememberedTracks = 200;
|
||||
|
||||
@override
|
||||
Future<SubtitleStyleSettings> build() async {
|
||||
final prefs = await getPrefs();
|
||||
for (final stale in const [
|
||||
'smplayer.subtitle_default_policy',
|
||||
'smplayer.subtitle_preferred_language',
|
||||
'smplayer.subtitle_secondary_position',
|
||||
'smplayer.subtitle_secondary_font_size',
|
||||
'smplayer.subtitle_secondary_delay',
|
||||
'smplayer.subtitle_secondary_bg_opacity',
|
||||
'smplayer.subtitle_secondary_follow_primary',
|
||||
'smplayer.subtitle_last_tracks_secondary',
|
||||
]) {
|
||||
await prefs.remove(stale);
|
||||
}
|
||||
return SubtitleStyleSettings(
|
||||
position: prefs.getInt(_keyPosition) ?? 100,
|
||||
fontSize: prefs.getDouble(_keyFontSize) ?? 55,
|
||||
delay: prefs.getDouble(_keyDelay) ?? 0.0,
|
||||
bgOpacity: prefs.getDouble(_keyBgOpacity) ?? 0.0,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setSettings(SubtitleStyleSettings settings) async {
|
||||
state = AsyncValue.data(settings);
|
||||
await persistFields({
|
||||
_keyPosition: settings.position,
|
||||
_keyFontSize: settings.fontSize,
|
||||
_keyDelay: settings.delay,
|
||||
_keyBgOpacity: settings.bgOpacity,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Future<void> saveLastSubtitleTrack(
|
||||
String key,
|
||||
RememberedSubtitleTrack? track,
|
||||
) async {
|
||||
if (track == null) return;
|
||||
await putRemembered(
|
||||
_keyLastTracks,
|
||||
key,
|
||||
track.toJson(),
|
||||
_maxRememberedTracks,
|
||||
);
|
||||
}
|
||||
|
||||
Future<RememberedSubtitleTrack?> getLastSubtitleTrack(String key) async {
|
||||
final entry = await readRemembered(_keyLastTracks, key);
|
||||
return entry == null ? null : RememberedSubtitleTrack.fromJson(entry);
|
||||
}
|
||||
}
|
||||
|
||||
final subtitleSettingsProvider =
|
||||
AsyncNotifierProvider<SubtitleSettingsNotifier, SubtitleStyleSettings>(
|
||||
SubtitleSettingsNotifier.new,
|
||||
);
|
||||
Reference in New Issue
Block a user