Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/l10n/app_ja.arb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@
"openNoteInBrowsers": "ブラウザでノートを開く",
"changeFullScreen": "フルスクリーンに切り替え",
"shareNotes": "ノートを共有",
"translateNote": "ノートを翻訳",
"translatedFrom": "{lang}から翻訳",
"@translatedFrom": {
"placeholders": {
"lang": {
"type": "String"
}
}
},
"deleteFavorite": "お気に入り解除",
"notesAfterRenote": "リノート直後のノート",
"deletedRecreate": "削除してなおす",
Expand Down
12 changes: 12 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,18 @@ abstract class S {
/// **'ノートを共有'**
String get shareNotes;

/// No description provided for @translateNote.
///
/// In ja, this message translates to:
/// **'ノートを翻訳'**
String get translateNote;

/// No description provided for @translatedFrom.
///
/// In ja, this message translates to:
/// **'{lang}から翻訳'**
String translatedFrom(String lang);

/// No description provided for @deleteFavorite.
///
/// In ja, this message translates to:
Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/app_localizations_ja.dart
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,14 @@ class SJa extends S {
@override
String get shareNotes => 'ノートを共有';

@override
String get translateNote => 'ノートを翻訳';

@override
String translatedFrom(String lang) {
return '$langから翻訳';
}

@override
String get deleteFavorite => 'お気に入り解除';

Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/app_localizations_zh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ class SZh extends S {
@override
String get shareNotes => '分享帖子';

@override
String get translateNote => 'ノートを翻訳';

@override
String translatedFrom(String lang) {
return '$langから翻訳';
}

@override
String get deleteFavorite => '取消收藏';

Expand Down
2 changes: 2 additions & 0 deletions lib/router/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import "package:miria/view/common/color_picker_dialog.dart";
import "package:miria/view/common/misskey_notes/reaction_user_dialog.dart";
import "package:miria/view/common/misskey_notes/renote_modal_sheet.dart";
import "package:miria/view/common/misskey_notes/renote_user_dialog.dart";
import "package:miria/view/common/misskey_notes/translate_note_modal_sheet.dart";
import "package:miria/view/explore_page/explore_page.dart";
import "package:miria/view/explore_page/explore_role_users_page.dart";
import "package:miria/view/favorited_note_page/favorited_note_page.dart";
Expand Down Expand Up @@ -179,6 +180,7 @@ class AppRouter extends RootStackRouter {
AutoModalRouteSheet(page: AntennaModalRoute.page),
AutoModalRouteSheet(page: ClipModalRoute.page),
AutoModalRouteSheet(page: UsersListModalRoute.page),
AutoModalRouteSheet(page: TranslateNoteModalRoute.page),
AutoModalRouteSheet<DriveModalSheetReturnValue>(page: DriveModalRoute.page),
];
}
Expand Down
67 changes: 67 additions & 0 deletions lib/router/app_router.gr.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 109 additions & 0 deletions lib/view/common/misskey_notes/translate_note_modal_sheet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import "package:auto_route/auto_route.dart";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:miria/l10n/app_localizations.dart";
import "package:miria/providers.dart";
import "package:miria/view/common/account_scope.dart";
import "package:miria/view/common/error_detail.dart";
import "package:miria/view/common/misskey_notes/mfm_text.dart";
import "package:misskey_dart/misskey_dart.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";

part "translate_note_modal_sheet.g.dart";

@Riverpod(dependencies: [misskeyPostContext])
FutureOr<NotesTranslateResponse> _notesTranslate(
Ref ref, {
required String noteId,
required String targetLang,
}) {
return ref
.read(misskeyPostContextProvider)
.notes
.translate(NotesTranslateRequest(noteId: noteId, targetLang: targetLang));
}

@RoutePage()
class TranslateNoteModalSheet extends ConsumerWidget
implements AutoRouteWrapper {
const TranslateNoteModalSheet({
required this.accountContext,
required this.note,
super.key,
});

final AccountContext accountContext;
final Note note;

@override
Widget wrappedRoute(BuildContext context) =>
AccountContextScope(context: accountContext, child: this);

@override
Widget build(BuildContext context, WidgetRef ref) {
final translatedNote = ref.watch(
_notesTranslateProvider(
noteId: note.id,
targetLang: Localizations.localeOf(context).toLanguageTag(),
),
);

return Scaffold(
body: ListView(
children: [
...switch (translatedNote) {
AsyncValue(value: final translatedNote?) => [
ListTile(
title: Text(
S.of(context).translatedFrom(translatedNote.sourceLang),
),
trailing: IconButton(
tooltip: S.of(context).copyContents,
onPressed: () async {
await Clipboard.setData(
ClipboardData(text: translatedNote.text),
);
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(S.of(context).doneCopy),
duration: const Duration(seconds: 1),
),
);
},
icon: const Icon(Icons.copy),
),
),
const Divider(height: 0.0),
SizedBox(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: MfmText(
mfmText: translatedNote.text,
host: note.user.host,
emoji: note.emojis,
isEnableAnimatedMFM: ref
.watch(generalSettingsRepositoryProvider)
.settings
.enableAnimatedMFM,
),
),
),
],
AsyncValue(:final error?, :final stackTrace) => [
ErrorDetail(error: error, stackTrace: stackTrace),
],
_ => [
const Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: CircularProgressIndicator.adaptive()),
),
],
},
],
),
);
}
}
107 changes: 107 additions & 0 deletions lib/view/common/misskey_notes/translate_note_modal_sheet.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions lib/view/note_modal_sheet/note_modal_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,18 @@ class NoteModalSheet extends ConsumerWidget implements AutoRouteWrapper {
});
},
),
if (accountContext.postAccount.i.policies.canUseTranslator &&
(accountContext.postAccount.meta?.translatorAvailable ?? false))
ListTile(
leading: const Icon(Icons.translate),
title: Text(S.of(context).translateNote),
onTap: () async => await context.pushRoute(
TranslateNoteModalRoute(
accountContext: accountContext,
note: targetNote,
),
),
),
if (accountContext.isSame)
switch (noteStatus) {
null => const SizedBox.shrink(),
Expand Down