diff --git a/lib/pages/main/info/lab/global_comments.dart b/lib/pages/main/info/lab/global_comments.dart new file mode 100644 index 000000000..859b8acd1 --- /dev/null +++ b/lib/pages/main/info/lab/global_comments.dart @@ -0,0 +1,240 @@ +// This source code is a part of Project Violet. +// Copyright (C) 2020-2021. violet-team. Licensed under the Apache-2.0 License. + +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:mdi/mdi.dart'; +import 'package:tuple/tuple.dart'; +import 'package:violet/locale/locale.dart'; +import 'package:violet/other/dialogs.dart'; +import 'package:violet/pages/main/info/lab/recent_user_record.dart'; +import 'package:violet/pages/segment/card_panel.dart'; +import 'package:violet/server/community/anon.dart'; +import 'package:violet/settings/settings.dart'; + +class LabGlobalComments extends StatefulWidget { + @override + _LabGlobalCommentsState createState() => _LabGlobalCommentsState(); +} + +class _LabGlobalCommentsState extends State { + List> comments = + >[]; + + @override + void initState() { + super.initState(); + + Future.delayed(Duration(milliseconds: 100)) + .then((value) async => await readComments()); + } + + TextEditingController text = TextEditingController(); + + Future readComments() async { + var tcomments = (await VioletCommunityAnonymous.getArtistComments( + 'global_general'))['result'] as List; + + comments = tcomments + .map((e) => Tuple3( + DateTime.parse(e['TimeStamp']), e['UserAppId'], e['Body'])) + .toList() + .reversed + .toList(); + + if (comments.length > 0) setState(() {}); + } + + @override + Widget build(BuildContext context) { + return CardPanel.build( + context, + enableBackgroundColor: true, + child: Column( + children: [ + Expanded( + child: ListView.separated( + padding: EdgeInsets.only(top: 16.0), + reverse: true, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return CommentUnit( + author: comments[index].item2, + body: comments[index].item3, + dateTime: comments[index].item1, + ); + }, + separatorBuilder: (context, index) { + return Container( + margin: const EdgeInsets.only( + left: 24.0, + right: 24.0, + // top: 16.0, + ), + width: double.infinity, + height: 1.0, + color: Settings.themeWhat + ? Colors.grey.shade800 + : Colors.grey.shade300, + ); + }, + itemCount: comments.length, + ), + ), + Container( + margin: EdgeInsets.all(8.0), + padding: EdgeInsets.symmetric(horizontal: 12.0), + height: 36.0, + decoration: new BoxDecoration( + color: Settings.themeWhat + ? Colors.grey.shade800 + : Color(0xffe2e4e7), + borderRadius: new BorderRadius.all(const Radius.circular(6.0))), + child: Row( + children: [ + Expanded( + child: TextField( + style: TextStyle(fontSize: 14.0, color: Colors.grey), + decoration: new InputDecoration.collapsed( + hintText: '500자까지 입력할 수 있습니다.'), + controller: text, + // onEditingComplete: () async {}, + ), + ), + Align( + alignment: Alignment.centerRight, + child: TextButton( + style: TextButton.styleFrom( + primary: Settings.themeWhat + ? Colors.grey.shade600 + : Color(0xff3a4e66), + padding: EdgeInsets.zero, + minimumSize: const Size(50, 36), + ), + child: Text( + '작성', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + onPressed: () async { + if (text.text.length < 5 || text.text.length > 500) { + await showOkDialog(context, '너무 짧아요!', + Translations.of(context).trans('comment')); + return; + } + await VioletCommunityAnonymous.postArtistComment( + 'global_general', text.text); + await readComments(); + }, + ), + ), + ], + ), + ), + ], + ), + ); + } +} + +class CommentUnit extends StatelessWidget { + final String author; + final String body; + final DateTime dateTime; + + static const String dev = 'aee70691afaa'; + + const CommentUnit({this.author, this.body, this.dateTime}); + + @override + Widget build(BuildContext context) { + return InkWell( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + Text( + author.substring(0, 7), + style: TextStyle( + fontWeight: FontWeight.bold, + color: Settings.themeWhat + ? Colors.grey.shade300 + : Color(0xff373a3c), + fontSize: 15.0, + ), + ), + Container(width: 4.0), + if (author.startsWith(dev)) + Icon( + MdiIcons.starCheckOutline, + size: 15.0, + color: const Color(0xffffd700), + ) + ], + ), + RichText( + text: new TextSpan( + style: TextStyle( + color: Settings.themeWhat + ? Colors.grey.shade300 + : Color(0xff373a3c), + fontSize: 12.0, + ), + children: [ + new TextSpan(text: body), + new TextSpan(text: ' '), + new TextSpan( + text: '${DateFormat('yyyy.MM.dd HH:mm').format(dateTime)}', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Settings.themeWhat + ? Colors.grey.shade500 + : Color(0xff989dab), + ), + ), + ], + ), + ), + ], + ), + ), + onDoubleTap: () { + if (!author.startsWith(dev)) + _navigate(context, LabUserRecentRecords(author)); + }, + ); + } + + _navigate(context, Widget page) { + if (!Platform.isIOS) { + Navigator.of(context).push(PageRouteBuilder( + transitionDuration: Duration(milliseconds: 500), + transitionsBuilder: (context, animation, secondaryAnimation, child) { + var begin = Offset(0.0, 1.0); + var end = Offset.zero; + var curve = Curves.ease; + + var tween = + Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); + + return SlideTransition( + position: animation.drive(tween), + child: child, + ); + }, + pageBuilder: (_, __, ___) => page, + )); + } else { + Navigator.of(context).push(CupertinoPageRoute(builder: (_) => page)); + } + } +} diff --git a/lib/pages/main/info/lab/search_message.dart b/lib/pages/main/info/lab/search_message.dart index a8a28a9fa..f47d2eb1d 100644 --- a/lib/pages/main/info/lab/search_message.dart +++ b/lib/pages/main/info/lab/search_message.dart @@ -261,15 +261,6 @@ class _LabSearchMessageState extends State { messages = >>[]; - _urls.forEach((element) async { - await CachedNetworkImageProvider(element).evict(); - }); - - _height = List.filled(messages.length, 0); - _keys = List.generate( - messages.length, (index) => GlobalKey()); - _urls = List.filled(messages.length, ''); - setState(() { selected = value; }); @@ -287,6 +278,15 @@ class _LabSearchMessageState extends State { .toList())) .toList(); + _urls.forEach((element) async { + await CachedNetworkImageProvider(element).evict(); + }); + + _height = List.filled(messages.length, 0); + _keys = List.generate( + messages.length, (index) => GlobalKey()); + _urls = List.filled(messages.length, ''); + setState(() {}); }, ), @@ -303,15 +303,6 @@ class _LabSearchMessageState extends State { messages = >>[]; - _urls.forEach((element) async { - await CachedNetworkImageProvider(element).evict(); - }); - - _height = List.filled(messages.length, 0); - _keys = List.generate( - messages.length, (index) => GlobalKey()); - _urls = List.filled(messages.length, ''); - setState(() {}); var tmessages = (await VioletServer.searchMessage( selected.toLowerCase(), text.text)) as List; @@ -326,6 +317,16 @@ class _LabSearchMessageState extends State { .map((e) => double.parse(e.toString())) .toList())) .toList(); + + _urls.forEach((element) async { + await CachedNetworkImageProvider(element).evict(); + }); + + _height = List.filled(messages.length, 0); + _keys = List.generate( + messages.length, (index) => GlobalKey()); + _urls = List.filled(messages.length, ''); + setState(() {}); }, ), diff --git a/lib/pages/main/main_page.dart b/lib/pages/main/main_page.dart index 09739976d..a681f95de 100644 --- a/lib/pages/main/main_page.dart +++ b/lib/pages/main/main_page.dart @@ -33,6 +33,7 @@ import 'package:violet/pages/main/card/contact_card.dart'; import 'package:violet/pages/main/card/discord_card.dart'; import 'package:violet/pages/main/card/github_card.dart'; import 'package:violet/pages/main/info/info_page.dart'; +import 'package:violet/pages/main/info/lab/global_comments.dart'; import 'package:violet/pages/main/info/lab/recent_record.dart'; import 'package:violet/pages/main/info/lab/recent_record_u.dart'; import 'package:violet/pages/main/info/lab/recent_user_record.dart'; @@ -629,22 +630,38 @@ class _MainPage2State extends State child: const Icon(MdiIcons.accessPointNetwork), ), ), - Tooltip( - message: '유저 북마크 리스트', - child: ElevatedButton( - style: buttonStyle, - onPressed: () async { - if (await _checkMaterKey()) { - Navigator.of(context).push( - _buildServicePageRoute(() => LabUserBookmarkPage())); - } else { - await showOkDialog( - context, - 'You must unlock this feature using the master key! ' + - '이 기능은 현재 인가된 사용자만 사용할 수 있습니다.'); - } - }, - child: const Icon(MdiIcons.incognito), + // Tooltip( + // message: '유저 북마크 리스트', + // child: ElevatedButton( + // style: buttonStyle, + // onPressed: () async { + // if (await _checkMaterKey()) { + // Navigator.of(context).push( + // _buildServicePageRoute(() => LabUserBookmarkPage())); + // } else { + // await showOkDialog( + // context, + // 'You must unlock this feature using the master key! ' + + // '이 기능은 현재 인가된 사용자만 사용할 수 있습니다.'); + // } + // }, + // child: const Icon(MdiIcons.incognito), + // ), + // ), + Badge( + showBadge: true, + badgeContent: Text('N', + style: TextStyle(color: Colors.white, fontSize: 12.0)), + child: Tooltip( + message: '댓글', + child: ElevatedButton( + style: buttonStyle, + onPressed: () async { + Navigator.of(context) + .push(_buildServicePageRoute(() => LabGlobalComments())); + }, + child: const Icon(MdiIcons.commentTextMultiple), + ), ), ), Badge( diff --git a/lib/pages/segment/artist_panel.dart b/lib/pages/segment/artist_panel.dart new file mode 100644 index 000000000..082bbe9bb --- /dev/null +++ b/lib/pages/segment/artist_panel.dart @@ -0,0 +1,49 @@ +// This source code is a part of Project Violet. +// Copyright (C) 2020-2021. violet-team. Licensed under the Apache-2.0 License. + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:violet/pages/segment/card_panel.dart'; + +// class ArtistPanel extends StatelessWidget { +// final String author; +// final String body; + +// @override +// Widget build(BuildContext context) { +// return Padding( +// padding: EdgeInsets.all(8.0), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.stretch, +// children: [ +// Text( +// 'Meme50', +// style: TextStyle( +// fontWeight: FontWeight.bold, +// color: Color(0xff373a3c), +// fontSize: 15.0, +// ), +// ), +// RichText( +// text: new TextSpan( +// style: TextStyle( +// color: Color(0xff373a3c), +// fontSize: 12.0, +// ), +// children: [ +// new TextSpan(text: 'Hello'), +// new TextSpan(text: ' '), +// new TextSpan( +// text: '2021.09.19', +// style: new TextStyle( +// fontWeight: FontWeight.bold, +// color: Color(0xff989dab), +// )), +// ], +// ), +// ), +// ], +// ), +// ); +// } +// } diff --git a/lib/pages/settings/version_page.dart b/lib/pages/settings/version_page.dart index 5407ac8f8..47a6b991f 100644 --- a/lib/pages/settings/version_page.dart +++ b/lib/pages/settings/version_page.dart @@ -29,7 +29,7 @@ class VersionViewPage extends StatelessWidget { style: TextStyle(fontSize: 30), ), Text( - '1.16.2', + '1.16.3', style: TextStyle(fontSize: 20), ), Text(''), diff --git a/lib/pages/splash/splash_page.dart b/lib/pages/splash/splash_page.dart index 04d1c0542..a7e3f764a 100644 --- a/lib/pages/splash/splash_page.dart +++ b/lib/pages/splash/splash_page.dart @@ -191,10 +191,10 @@ class _SplashPageState extends State { await HisokiHash.init(); // await ScriptManager.init(); - if (Platform.isAndroid) - try { - await Logger.exportLog(); - } catch (_) {} + // if (Platform.isAndroid) + // try { + // await Logger.exportLog(); + // } catch (_) {} if ((await SharedPreferences.getInstance()).getInt('db_exists') == 1 && !widget.switching) { diff --git a/lib/version/update_sync.dart b/lib/version/update_sync.dart index be9f3f53c..95a2b5548 100644 --- a/lib/version/update_sync.dart +++ b/lib/version/update_sync.dart @@ -15,7 +15,7 @@ class UpdateSyncManager { // Current version static const int majorVersion = 1; static const int minorVersion = 16; - static const int patchVersion = 2; + static const int patchVersion = 3; static String get currentVersion => '$majorVersion.$minorVersion.$patchVersion';