Skip to content

Commit

Permalink
0.2.12
Browse files Browse the repository at this point in the history
### Feature
- Note list context menu
- Note translate
### Change
- image save webp to png
  • Loading branch information
ChenDoXiu committed Apr 6, 2024
1 parent 2f2390d commit 3e71743
Show file tree
Hide file tree
Showing 17 changed files with 333 additions and 81 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Changelog

## 0.2.12
### Feature
- Note list context menu
- Note translate
### Change
- image save webp to png

## 0.2.11
### Feature
- image save webp to jpeg
Expand Down
3 changes: 1 addition & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
Expand All @@ -24,7 +23,7 @@ class HttpProxy extends HttpOverrides {
@override
String findProxyFromEnvironment(Uri url, Map<String, String>? environment) {
// if (kDebugMode) {
// proxyServer = "127.0.0.1:7890";
// proxyServer = "172.20.1.200:7890";
// }
if (proxyServer == "") {
return super.findProxyFromEnvironment(url, environment);
Expand Down
6 changes: 5 additions & 1 deletion lib/models/note.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_tabler_icons/flutter_tabler_icons.dart';
import 'package:moekey/models/translate.dart';
import 'package:moekey/models/user_simple.dart';

import 'drive.dart';
Expand Down Expand Up @@ -28,6 +29,9 @@ class NoteModel {
String userId;
NoteVisibility visibility;
NotePollModel? poll;

NoteTranslate? noteTranslate;

NoteModel({
required this.id,
required this.clippedCount,
Expand Down Expand Up @@ -56,7 +60,7 @@ class NoteModel {

@override
String toString() {
return 'NoteModel{id: $id, clippedCount: $clippedCount, createdAt: $createdAt, cw: $cw, emojis: $emojis, files: $files, localOnly: $localOnly, reactionAcceptance: $reactionAcceptance, reactionEmojis: $reactionEmojis, reactions: $reactions, myReaction: $myReaction, renote: $renote, renoteCount: $renoteCount, renoteId: $renoteId, repliesCount: $repliesCount, reply: $reply, replyId: $replyId, text: $text, uri: $uri, user: $user, userId: $userId, visibility: $visibility, poll: $poll}';
return 'NoteModel{id: $id, clippedCount: $clippedCount, createdAt: $createdAt, cw: $cw, emojis: $emojis, files: $files, localOnly: $localOnly, reactionAcceptance: $reactionAcceptance, reactionEmojis: $reactionEmojis, reactions: $reactions, myReaction: $myReaction, renote: $renote, renoteCount: $renoteCount, renoteId: $renoteId, repliesCount: $repliesCount, reply: $reply, replyId: $replyId, text: $text, uri: $uri, user: $user, userId: $userId, visibility: $visibility, poll: $poll, noteTranslate: $noteTranslate}';
}

String createReplyAtText(String? currentUserId) {
Expand Down
22 changes: 22 additions & 0 deletions lib/models/translate.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class NoteTranslate {
String sourceLang;
String text;
bool loading = true;

NoteTranslate({
required this.sourceLang,
required this.text,
});

factory NoteTranslate.fromMap(dynamic map) {
return NoteTranslate(
sourceLang: map['sourceLang'],
text: map['text'],
);
}

@override
String toString() {
return 'Translate{sourceLang: $sourceLang, text: $text}';
}
}
14 changes: 14 additions & 0 deletions lib/networks/apis.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/services.dart';
import 'package:moekey/networks/dio.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../models/translate.dart';
import '../state/server.dart';
import '../state/themes.dart';

Expand Down Expand Up @@ -125,3 +126,16 @@ Future<dynamic> getUriInfo(GetUriInfoRef ref, String url) async {

return res.data;
}

@riverpod
Future<NoteTranslate> noteTranslate(NoteTranslateRef ref, String noteId) async {
var http = await ref.watch(httpProvider.future);
var user = await ref.watch(currentLoginUserProvider.future);

var res = await http.post("/notes/translate", data: {
"noteId": noteId,
"targetLang": Platform.localeName.replaceAll("_", "-"),
"i": user?.token ?? "",
});
return NoteTranslate.fromMap(res.data);
}
2 changes: 2 additions & 0 deletions lib/networks/notes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Notes extends _$Notes {
@override
FutureOr<NotesState> build(String noteId) async {
var data = await ref.watch(getNoteProvider(noteId).future);
var noteTranslate = ref.watch(noteListProvider)[noteId]?.noteTranslate;
data?.noteTranslate = noteTranslate;
var note = NotesState();
ref
.read(noteListProvider.notifier)
Expand Down
75 changes: 75 additions & 0 deletions lib/pages/notes/note_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'package:moekey/widgets/loading_weight.dart';
import 'package:moekey/widgets/mk_header.dart';

import '../../main.dart';
import '../../models/translate.dart';
import '../../networks/apis.dart';
import '../../networks/notes.dart';
import '../../router/main_router_delegate.dart';
import '../../utils/time_ago_since_date.dart';
Expand Down Expand Up @@ -314,6 +316,7 @@ class NotesPageNoteCard extends HookConsumerWidget {
var data = ref.watch(
noteListProvider.select((value) => value[this.data.id] ?? this.data));
var links = extractLinksFromMarkdown(data.text ?? "");
var meta = ref.watch(apiMetaProvider).valueOrNull;
return LayoutBuilder(
builder: (context, constraints) {
return Column(
Expand Down Expand Up @@ -360,6 +363,78 @@ class NotesPageNoteCard extends HookConsumerWidget {
currentServerHost: data.user.host,
isSelection: true,
),
if (meta != null &&
meta.containsKey("translatorAvailable") &&
meta["translatorAvailable"] &&
data.noteTranslate == null)
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
var note = ref.read(noteListProvider)[data.id] ?? data;
note = note.copyWith();
note.noteTranslate =
NoteTranslate(text: "", sourceLang: "");
ref.read(noteListProvider.notifier).registerNote(note);
var res = ref.read(noteTranslateProvider(data.id).future);
res.then(
(res) {
res.loading = false;
note = note.copyWith();
note.noteTranslate = res;
ref
.read(noteListProvider.notifier)
.registerNote(note);
},
);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: Text(
"翻译帖子",
style: TextStyle(color: themes.accentColor),
),
),
),
),

if (data.noteTranslate != null)
Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: themes.dividerColor, width: 1),
borderRadius: const BorderRadius.all(
Radius.circular(6),
),
),
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
margin: const EdgeInsets.only(top: 8, bottom: 2),
child: [
if (data.noteTranslate!.loading)
const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: LoadingCircularProgress(
size: 22,
strokeWidth: 4,
),
),
)
else
MFMText(
emojis: data.emojis,
currentServerHost: data.user.host,
before: [
TextSpan(
text: "从${data.noteTranslate!.sourceLang}翻译:\n",
style:
const TextStyle(fontWeight: FontWeight.bold))
],
text: data.noteTranslate!.text ?? "",
),
][0],
),
const SizedBox(height: 4),
// 投票
if (data.poll != null) PollCard(data: data),
Expand Down
36 changes: 20 additions & 16 deletions lib/utils/save_image.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:ui';

import 'package:dio/dio.dart';
import 'package:extended_image/extended_image.dart';
import 'package:file_picker/file_picker.dart';
import 'package:gal/gal.dart';
import 'package:jpeg_encode/jpeg_encode.dart';
import 'package:path/path.dart';
import 'dart:ui' as ui;

import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

Future<bool> saveImage({
required Dio http,
required String url,
String album = "moekey",
}) async {
print(url);
var name = basename(url);
var ext = extension(name);
var fileBasename = basenameWithoutExtension(name);
Expand All @@ -27,25 +28,28 @@ Future<bool> saveImage({

var codec = await ui.instantiateImageCodec(data);

// webp 单帧图片转换成jpeg
if(ext.toLowerCase().contains("webp") && codec.frameCount == 1){
final frame = await codec.getNextFrame();
final image = frame.image;
final byteData = await image.toByteData(format: ImageByteFormat.rawRgba);
data = JpegEncoder().compress(byteData!.buffer.asUint8List(), image.width, image.height, 100);
name = "$fileBasename.jpg";
}


if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
// webp 单帧图片转换成png
if (ext.toLowerCase().contains("webp") && codec.frameCount == 1) {
final frame = await codec.getNextFrame();
final image = frame.image;
final byteData = await image.toByteData(format: ImageByteFormat.png);
if (byteData == null) {
return false;
}
data = Uint8List.view(byteData.buffer);
name = "$fileBasename.png";
}

var prefs = await SharedPreferences.getInstance();
var initialDirectory = prefs.getString("saveInitialDirectory");
String? outputFile = await FilePicker.platform.saveFile(
dialogTitle: 'Please select an output file:',
fileName: name,
type: FileType.image,
initialDirectory: initialDirectory
);
dialogTitle: 'Please select an output file:',
fileName: name,
type: FileType.image,
initialDirectory: initialDirectory);
if (outputFile == null) {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions lib/widgets/login/servers_select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ServersSelectCard extends HookConsumerWidget {
ref.invalidate(instanceListStateProvider);
},
child: ListView.separated(
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
var data = filterList[index];
return ListTile(
Expand Down
Loading

0 comments on commit 3e71743

Please sign in to comment.