updated about translators
This commit is contained in:
parent
11975b3c65
commit
3cf1e0cdac
5 changed files with 157 additions and 145 deletions
|
@ -2,6 +2,7 @@ import 'package:aves/widgets/about/app_ref.dart';
|
||||||
import 'package:aves/widgets/about/bug_report.dart';
|
import 'package:aves/widgets/about/bug_report.dart';
|
||||||
import 'package:aves/widgets/about/credits.dart';
|
import 'package:aves/widgets/about/credits.dart';
|
||||||
import 'package:aves/widgets/about/licenses.dart';
|
import 'package:aves/widgets/about/licenses.dart';
|
||||||
|
import 'package:aves/widgets/about/translators.dart';
|
||||||
import 'package:aves/widgets/common/basic/insets.dart';
|
import 'package:aves/widgets/common/basic/insets.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
|
@ -35,6 +36,8 @@ class AboutPage extends StatelessWidget {
|
||||||
Divider(),
|
Divider(),
|
||||||
AboutCredits(),
|
AboutCredits(),
|
||||||
Divider(),
|
Divider(),
|
||||||
|
AboutTranslators(),
|
||||||
|
Divider(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
import 'package:aves/utils/constants.dart';
|
import 'package:aves/utils/constants.dart';
|
||||||
import 'package:aves/widgets/common/basic/link_chip.dart';
|
import 'package:aves/widgets/common/basic/link_chip.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/viewer/info/common.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AboutCredits extends StatelessWidget {
|
class AboutCredits extends StatelessWidget {
|
||||||
const AboutCredits({super.key});
|
const AboutCredits({super.key});
|
||||||
|
|
||||||
static const translators = {
|
|
||||||
'Bahasa Indonesia': 'MeFinity',
|
|
||||||
'Deutsch': 'JanWaldhorn',
|
|
||||||
'Español (México)': 'n-berenice',
|
|
||||||
'Italiano': 'glemco',
|
|
||||||
'Nederlands': 'Martijn Fabrie, Koen Koppens',
|
|
||||||
'Português (Brasil)': 'Jonatas De Almeida Barros',
|
|
||||||
'Türkçe': 'metezd',
|
|
||||||
'Ελληνικά': 'Emmanouil Papavergis',
|
|
||||||
'Русский': 'D3ZOXY, kha84',
|
|
||||||
'日本語': 'Maki',
|
|
||||||
'简体中文': '小默, Aerowolf',
|
|
||||||
};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
|
@ -36,6 +21,7 @@ class AboutCredits extends StatelessWidget {
|
||||||
child: Text(l10n.aboutCreditsSectionTitle, style: Constants.knownTitleTextStyle),
|
child: Text(l10n.aboutCreditsSectionTitle, style: Constants.knownTitleTextStyle),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
children: [
|
children: [
|
||||||
|
@ -52,15 +38,7 @@ class AboutCredits extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ConstrainedBox(
|
const SizedBox(height: 8),
|
||||||
constraints: const BoxConstraints(minHeight: 48),
|
|
||||||
child: Align(
|
|
||||||
alignment: AlignmentDirectional.centerStart,
|
|
||||||
child: Text(l10n.aboutTranslatorsSectionTitle, style: Constants.knownTitleTextStyle),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const InfoRowGroup(info: translators),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
149
lib/widgets/about/translators.dart
Normal file
149
lib/widgets/about/translators.dart
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:aves/utils/constants.dart';
|
||||||
|
import 'package:aves/widgets/common/basic/animated_text.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AboutTranslators extends StatelessWidget {
|
||||||
|
const AboutTranslators({super.key});
|
||||||
|
|
||||||
|
static const translators = {
|
||||||
|
Contributor('D3ZOXY', 'its.ghost.message@gmail.com'),
|
||||||
|
Contributor('JanWaldhorn', 'weblate@jwh.anonaddy.com'),
|
||||||
|
Contributor('n-berenice', null),
|
||||||
|
Contributor('Jonatas de Almeida Barros', 'ajonatas56@gmail.com'),
|
||||||
|
Contributor('MeFinity', 'me.dot.finity@gmail.com'),
|
||||||
|
Contributor('Maki', null),
|
||||||
|
Contributor('HiSubway', 'shenyusoftware@gmail.com'),
|
||||||
|
Contributor('glemco', null),
|
||||||
|
Contributor('Aerowolf', null),
|
||||||
|
Contributor('小默', null),
|
||||||
|
Contributor('metezd', 'itoldyouthat@protonmail.com'),
|
||||||
|
Contributor('Martijn Fabrie', null),
|
||||||
|
Contributor('Koen Koppens', 'koenkoppens@proton.me'),
|
||||||
|
Contributor('Emmanouil Papavergis', null),
|
||||||
|
Contributor('kha84', 'khalukhin@gmail.com'),
|
||||||
|
Contributor('gallegonovato', 'fran-carro@hotmail.es'),
|
||||||
|
Contributor('Havokdan', 'havokdan@yahoo.com.br'),
|
||||||
|
Contributor('Jean Mareilles', 'waged1266@tutanota.com'),
|
||||||
|
Contributor('이정희', 'daemul72@gmail.com'),
|
||||||
|
Contributor('Translator-3000', 'weblate.m1d0h@8shield.net'),
|
||||||
|
// Contributor('Allan Nordhøy', 'epost@anotheragency.no'),
|
||||||
|
// Contributor('Piotr K', '1337.kelt@gmail.com'),
|
||||||
|
// Contributor('امیر جهانگرد', 'ijahangard.a@gmail.com'),
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(minHeight: 48),
|
||||||
|
child: Align(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: Text(l10n.aboutTranslatorsSectionTitle, style: Constants.knownTitleTextStyle),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_RandomTextSpanHighlighter(
|
||||||
|
spans: translators.map((v) => v.name).toList(),
|
||||||
|
highlightColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RandomTextSpanHighlighter extends StatefulWidget {
|
||||||
|
final List<String> spans;
|
||||||
|
final Color highlightColor;
|
||||||
|
|
||||||
|
const _RandomTextSpanHighlighter({
|
||||||
|
required this.spans,
|
||||||
|
required this.highlightColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_RandomTextSpanHighlighter> createState() => _RandomTextSpanHighlighterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RandomTextSpanHighlighterState extends State<_RandomTextSpanHighlighter> with SingleTickerProviderStateMixin {
|
||||||
|
late final AnimationController _controller;
|
||||||
|
late final Animation<TextStyle> _animatedStyle;
|
||||||
|
late final TextStyle _baseStyle;
|
||||||
|
int _highlightedIndex = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_baseStyle = TextStyle(
|
||||||
|
shadows: [
|
||||||
|
Shadow(
|
||||||
|
color: widget.highlightColor.withOpacity(0),
|
||||||
|
blurRadius: 0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
final highlightStyle = TextStyle(
|
||||||
|
shadows: [
|
||||||
|
Shadow(
|
||||||
|
color: widget.highlightColor,
|
||||||
|
blurRadius: 3,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
_controller = AnimationController(
|
||||||
|
duration: const Duration(seconds: 1),
|
||||||
|
vsync: this,
|
||||||
|
)
|
||||||
|
..addListener(() => setState(() {}))
|
||||||
|
..addStatusListener((status) {
|
||||||
|
if (status == AnimationStatus.forward) {
|
||||||
|
_highlightedIndex = Random().nextInt(widget.spans.length);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
..repeat(reverse: true);
|
||||||
|
_animatedStyle = ShadowedTextStyleTween(begin: _baseStyle, end: highlightStyle).animate(CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: Curves.linear,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
...widget.spans.expandIndexed((i, v) => [
|
||||||
|
if (i != 0) const TextSpan(text: ' • '),
|
||||||
|
TextSpan(text: v, style: i == _highlightedIndex ? _animatedStyle.value : _baseStyle),
|
||||||
|
])
|
||||||
|
],
|
||||||
|
),
|
||||||
|
strutStyle: const StrutStyle(height: 1.5, forceStrutHeight: true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Contributor {
|
||||||
|
final String name;
|
||||||
|
final String? weblateEmail;
|
||||||
|
|
||||||
|
const Contributor(this.name, this.weblateEmail);
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ class _AnimatedTextState extends State<AnimatedText> with SingleTickerProviderSt
|
||||||
)
|
)
|
||||||
..value = 1
|
..value = 1
|
||||||
..addListener(() => setState(() {}));
|
..addListener(() => setState(() {}));
|
||||||
_style = _ShadowedTextStyleTween(begin: widget.changedStyle, end: widget.style).animate(CurvedAnimation(
|
_style = ShadowedTextStyleTween(begin: widget.changedStyle, end: widget.style).animate(CurvedAnimation(
|
||||||
parent: _controller,
|
parent: _controller,
|
||||||
curve: widget.curve,
|
curve: widget.curve,
|
||||||
));
|
));
|
||||||
|
@ -64,8 +64,8 @@ class _AnimatedTextState extends State<AnimatedText> with SingleTickerProviderSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ShadowedTextStyleTween extends Tween<TextStyle> {
|
class ShadowedTextStyleTween extends Tween<TextStyle> {
|
||||||
_ShadowedTextStyleTween({super.begin, super.end});
|
ShadowedTextStyleTween({super.begin, super.end});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TextStyle lerp(double t) {
|
TextStyle lerp(double t) {
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
{
|
{
|
||||||
"de": [
|
|
||||||
"editEntryLocationDialogSetCustom",
|
|
||||||
"settingsAllowMediaManagement",
|
|
||||||
"tagEditorSectionPlaceholders",
|
|
||||||
"tagPlaceholderCountry",
|
|
||||||
"tagPlaceholderPlace"
|
|
||||||
],
|
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
"settingsAllowMediaManagement",
|
"settingsAllowMediaManagement",
|
||||||
|
@ -1046,29 +1038,6 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
"id": [
|
|
||||||
"chipActionFilterOut",
|
|
||||||
"chipActionFilterIn",
|
|
||||||
"viewerTransitionNone",
|
|
||||||
"widgetOpenPageHome",
|
|
||||||
"widgetOpenPageCollection",
|
|
||||||
"widgetOpenPageViewer",
|
|
||||||
"durationDialogSeconds",
|
|
||||||
"editEntryLocationDialogSetCustom",
|
|
||||||
"tileLayoutMosaic",
|
|
||||||
"albumGroupType",
|
|
||||||
"albumMimeTypeMixed",
|
|
||||||
"settingsDisabled",
|
|
||||||
"settingsSlideshowAnimatedZoomEffect",
|
|
||||||
"settingsAllowMediaManagement",
|
|
||||||
"settingsWidgetOpenPage",
|
|
||||||
"statsTopAlbumsSectionTitle",
|
|
||||||
"wallpaperUseScrollEffect",
|
|
||||||
"tagEditorSectionPlaceholders",
|
|
||||||
"tagPlaceholderCountry",
|
|
||||||
"tagPlaceholderPlace"
|
|
||||||
],
|
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"chipActionFilterOut",
|
"chipActionFilterOut",
|
||||||
"chipActionFilterIn",
|
"chipActionFilterIn",
|
||||||
|
@ -1191,19 +1160,6 @@
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
|
||||||
"widgetOpenPageCollection",
|
|
||||||
"widgetOpenPageViewer",
|
|
||||||
"durationDialogSeconds",
|
|
||||||
"editEntryLocationDialogSetCustom",
|
|
||||||
"aboutLinkPolicy",
|
|
||||||
"policyPageTitle",
|
|
||||||
"settingsAllowMediaManagement",
|
|
||||||
"tagEditorSectionPlaceholders",
|
|
||||||
"tagPlaceholderCountry",
|
|
||||||
"tagPlaceholderPlace"
|
|
||||||
],
|
|
||||||
|
|
||||||
"pl": [
|
"pl": [
|
||||||
"itemCount",
|
"itemCount",
|
||||||
"timeSeconds",
|
"timeSeconds",
|
||||||
|
@ -1693,80 +1649,6 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
|
||||||
"editEntryLocationDialogSetCustom",
|
|
||||||
"settingsAllowMediaManagement",
|
|
||||||
"tagEditorSectionPlaceholders",
|
|
||||||
"tagPlaceholderCountry",
|
|
||||||
"tagPlaceholderPlace"
|
|
||||||
],
|
|
||||||
|
|
||||||
"tr": [
|
|
||||||
"chipActionFilterOut",
|
|
||||||
"chipActionFilterIn",
|
|
||||||
"slideshowActionResume",
|
|
||||||
"slideshowActionShowInCollection",
|
|
||||||
"entryInfoActionEditTitleDescription",
|
|
||||||
"filterNoDateLabel",
|
|
||||||
"filterNoTitleLabel",
|
|
||||||
"filterOnThisDayLabel",
|
|
||||||
"filterRecentlyAddedLabel",
|
|
||||||
"videoPlaybackSkip",
|
|
||||||
"videoPlaybackMuted",
|
|
||||||
"videoPlaybackWithSound",
|
|
||||||
"viewerTransitionSlide",
|
|
||||||
"viewerTransitionParallax",
|
|
||||||
"viewerTransitionFade",
|
|
||||||
"viewerTransitionZoomIn",
|
|
||||||
"viewerTransitionNone",
|
|
||||||
"wallpaperTargetHome",
|
|
||||||
"wallpaperTargetLock",
|
|
||||||
"wallpaperTargetHomeLock",
|
|
||||||
"widgetOpenPageHome",
|
|
||||||
"widgetOpenPageCollection",
|
|
||||||
"widgetOpenPageViewer",
|
|
||||||
"durationDialogSeconds",
|
|
||||||
"editEntryLocationDialogSetCustom",
|
|
||||||
"menuActionSlideshow",
|
|
||||||
"viewDialogReverseSortOrder",
|
|
||||||
"tileLayoutMosaic",
|
|
||||||
"sortOrderNewestFirst",
|
|
||||||
"sortOrderOldestFirst",
|
|
||||||
"sortOrderAtoZ",
|
|
||||||
"sortOrderZtoA",
|
|
||||||
"sortOrderHighestFirst",
|
|
||||||
"sortOrderLowestFirst",
|
|
||||||
"sortOrderLargestFirst",
|
|
||||||
"sortOrderSmallestFirst",
|
|
||||||
"albumGroupType",
|
|
||||||
"albumMimeTypeMixed",
|
|
||||||
"searchMetadataSectionTitle",
|
|
||||||
"settingsDisabled",
|
|
||||||
"settingsConfirmationAfterMoveToBinItems",
|
|
||||||
"settingsViewerGestureSideTapNext",
|
|
||||||
"settingsViewerSlideshowTile",
|
|
||||||
"settingsViewerSlideshowPageTitle",
|
|
||||||
"settingsSlideshowRepeat",
|
|
||||||
"settingsSlideshowShuffle",
|
|
||||||
"settingsSlideshowFillScreen",
|
|
||||||
"settingsSlideshowAnimatedZoomEffect",
|
|
||||||
"settingsSlideshowTransitionTile",
|
|
||||||
"settingsSlideshowIntervalTile",
|
|
||||||
"settingsSlideshowVideoPlaybackTile",
|
|
||||||
"settingsSlideshowVideoPlaybackDialogTitle",
|
|
||||||
"settingsAllowMediaManagement",
|
|
||||||
"settingsScreenSaverPageTitle",
|
|
||||||
"settingsWidgetShowOutline",
|
|
||||||
"settingsWidgetOpenPage",
|
|
||||||
"statsTopAlbumsSectionTitle",
|
|
||||||
"viewerSetWallpaperButtonLabel",
|
|
||||||
"viewerInfoLabelDescription",
|
|
||||||
"wallpaperUseScrollEffect",
|
|
||||||
"tagEditorSectionPlaceholders",
|
|
||||||
"tagPlaceholderCountry",
|
|
||||||
"tagPlaceholderPlace"
|
|
||||||
],
|
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
"settingsAllowMediaManagement",
|
"settingsAllowMediaManagement",
|
||||||
|
|
Loading…
Reference in a new issue