game comments

This commit is contained in:
niuhuan 2021-11-10 05:57:44 +08:00
parent 1011621f09
commit e694e7e706
12 changed files with 460 additions and 124 deletions

View File

@ -8,7 +8,7 @@ require (
github.com/go-flutter-desktop/plugins/url_launcher v0.1.2 github.com/go-flutter-desktop/plugins/url_launcher v0.1.2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265
github.com/miguelpruivo/flutter_file_picker/go v0.0.0-20210622152105-9f0a811028a0 github.com/miguelpruivo/flutter_file_picker/go v0.0.0-20210622152105-9f0a811028a0
github.com/niuhuan/pica-go v0.0.0-20211105060849-4f6ae99a942e github.com/niuhuan/pica-go v0.0.0-20211109050119-cf22461c638f
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
golang.org/x/image v0.0.0-20190802002840-cff245a6509b golang.org/x/image v0.0.0-20190802002840-cff245a6509b
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect

View File

@ -41,6 +41,12 @@ github.com/niuhuan/pica-go v0.0.0-20211102035530-65029bd4ee97 h1:wlsmZVsLrZ/dB1K
github.com/niuhuan/pica-go v0.0.0-20211102035530-65029bd4ee97/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M= github.com/niuhuan/pica-go v0.0.0-20211102035530-65029bd4ee97/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M=
github.com/niuhuan/pica-go v0.0.0-20211105060849-4f6ae99a942e h1:NR/RCPlbx7cMjk7p8GqfkhOqWTH6vyfgYq7Vubjn9mY= github.com/niuhuan/pica-go v0.0.0-20211105060849-4f6ae99a942e h1:NR/RCPlbx7cMjk7p8GqfkhOqWTH6vyfgYq7Vubjn9mY=
github.com/niuhuan/pica-go v0.0.0-20211105060849-4f6ae99a942e/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M= github.com/niuhuan/pica-go v0.0.0-20211105060849-4f6ae99a942e/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M=
github.com/niuhuan/pica-go v0.0.0-20211109012708-2cef9976dbaa h1:PnIE6Ltz/dy9K1jZCGfTvPDHGitSwXVvQfzwgVIJSWE=
github.com/niuhuan/pica-go v0.0.0-20211109012708-2cef9976dbaa/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M=
github.com/niuhuan/pica-go v0.0.0-20211109043215-974462cb2b0d h1:jwZdWp1PkEbWAi/w3cI+4kBvIyxHtZgVmFFOu7XnABw=
github.com/niuhuan/pica-go v0.0.0-20211109043215-974462cb2b0d/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M=
github.com/niuhuan/pica-go v0.0.0-20211109050119-cf22461c638f h1:SQ6vAF7nyIDjhUj/SsEHRlxae4XLtygSuxWrJJazN1g=
github.com/niuhuan/pica-go v0.0.0-20211109050119-cf22461c638f/go.mod h1:fx2m+OgMeEZf6/TrfblV9i85SjPsOGbnjIL2gohxP4M=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View File

@ -425,6 +425,23 @@ func postChildComment(params string) (string, error) {
return "", nil return "", nil
} }
func postGameChildComment(params string) (string, error) {
var paramsStruct struct {
GameId string `json:"gameId"`
CommentId string `json:"commentId"`
Content string `json:"content"`
}
json.Unmarshal([]byte(params), &paramsStruct)
err := client.PostChildComment(paramsStruct.CommentId, paramsStruct.Content)
if err != nil {
return "", err
}
network_cache.RemoveCaches(fmt.Sprintf("GAME_COMMENT_CHILDREN$%s$%%", paramsStruct.CommentId))
network_cache.RemoveCaches("MY_COMMENTS$%")
network_cache.RemoveCaches(fmt.Sprintf("GAME_COMMENTS$%s$%%", paramsStruct.GameId))
return "", nil
}
func switchLikeComment(params string) (string, error) { func switchLikeComment(params string) (string, error) {
var paramsStruct struct { var paramsStruct struct {
CommentId string `json:"commentId"` CommentId string `json:"commentId"`
@ -478,3 +495,68 @@ func game(gameId string) (string, error) {
}, },
) )
} }
func gameComments(params string) (string, error) {
var paramsStruct struct {
GameId string `json:"gameId"`
Page int `json:"page"`
}
json.Unmarshal([]byte(params), &paramsStruct)
gameId := paramsStruct.GameId
page := paramsStruct.Page
return cacheable(
fmt.Sprintf("GAME_COMMENTS$%s$%d", gameId, page),
time.Hour*2,
func() (interface{}, error) {
return client.GameCommentsPage(gameId, page)
},
)
}
func postGameComment(params string) (string, error) {
var paramsStruct struct {
GameId string `json:"gameId"`
Content string `json:"content"`
}
json.Unmarshal([]byte(params), &paramsStruct)
err := client.PostGameComment(paramsStruct.GameId, paramsStruct.Content)
if err != nil {
return "", err
}
network_cache.RemoveCaches("MY_COMMENTS$%")
network_cache.RemoveCaches(fmt.Sprintf("GAME_COMMENTS$%s$%%", paramsStruct.GameId))
return "", nil
}
func gameCommentChildren(params string) (string, error) {
var paramsStruct struct {
CommentId string `json:"commentId"`
Page int `json:"page"`
}
json.Unmarshal([]byte(params), &paramsStruct)
commentId := paramsStruct.CommentId
page := paramsStruct.Page
return cacheable(
fmt.Sprintf("GAME_COMMENT_CHILDREN$%s$%d", commentId, page),
time.Hour*2,
func() (interface{}, error) {
return client.GameCommentChildren(commentId, page)
},
)
}
func switchLikeGameComment(params string) (string, error) {
var paramsStruct struct {
CommentId string `json:"commentId"`
GameId string `json:"gameId"`
}
json.Unmarshal([]byte(params), &paramsStruct)
rsp, err := client.SwitchLikeComment(paramsStruct.CommentId)
if err != nil {
return "", err
}
network_cache.RemoveCaches(fmt.Sprintf("GAME_COMMENT_CHILDREN$%s$%%", paramsStruct.CommentId))
network_cache.RemoveCaches("MY_COMMENTS$%")
network_cache.RemoveCaches(fmt.Sprintf("GAME_COMMENTS$%s$%%", paramsStruct.GameId))
return *rsp, nil
}

View File

@ -585,6 +585,16 @@ func FlatInvoke(method string, params string) (string, error) {
return game(params) return game(params)
case "games": case "games":
return games(params) return games(params)
case "gameComments":
return gameComments(params)
case "postGameComment":
return postGameComment(params)
case "gameCommentChildren":
return gameCommentChildren(params)
case "switchLikeGameComment":
return switchLikeGameComment(params)
case "postGameChildComment":
return postGameChildComment(params)
case "viewLogPage": case "viewLogPage":
return viewLogPage(params) return viewLogPage(params)
case "clearAllViewLog": case "clearAllViewLog":

View File

@ -66,6 +66,8 @@ class Page {
this.page = json["page"]; this.page = json["page"];
this.pages = json["pages"]; this.pages = json["pages"];
} }
Page.of(this.total, this.limit, this.page, this.pages);
} }
/// ///
@ -255,12 +257,10 @@ class CommentPage extends Page {
} }
} }
/// class CommentBase {
class Comment {
late String id; late String id;
late String content; late String content;
late CommentUser user; late CommentUser user;
late String comic;
late bool isTop; late bool isTop;
late bool hide; late bool hide;
late String createdAt; late String createdAt;
@ -268,11 +268,10 @@ class Comment {
late int commentsCount; late int commentsCount;
late bool isLiked; late bool isLiked;
Comment.fromJson(Map<String, dynamic> json) { CommentBase.fromJson(Map<String, dynamic> json) {
this.id = json["_id"]; this.id = json["_id"];
this.content = json["content"]; this.content = json["content"];
this.user = CommentUser.fromJson(Map<String, dynamic>.of(json["_user"])); this.user = CommentUser.fromJson(Map<String, dynamic>.of(json["_user"]));
this.comic = json["_comic"];
this.isTop = json["isTop"]; this.isTop = json["isTop"];
this.hide = json["hide"]; this.hide = json["hide"];
this.createdAt = json["created_at"]; this.createdAt = json["created_at"];
@ -282,6 +281,24 @@ class Comment {
} }
} }
///
class ChildOfComment extends Comment {
late String parent;
ChildOfComment.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.parent = json["_parent"];
}
}
///
class Comment extends CommentBase {
late String comic;
Comment.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.comic = json["_comic"];
}
}
/// ///
class CommentUser extends BasicUser { class CommentUser extends BasicUser {
late String role; late String role;
@ -604,10 +621,54 @@ class CommentChildrenPage extends Page {
} }
/// ///
class CommentChild extends Comment { class CommentChild extends ChildOfComment {
late String parent; late String comic;
CommentChild.fromJson(Map<String, dynamic> json) : super.fromJson(json) { CommentChild.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.parent = json["_parent"]; this.comic = json["_comic"];
}
}
///
class GameCommentPage extends Page {
late List<GameComment> docs;
GameCommentPage.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.docs = List.from(json["docs"])
.map((e) => Map<String, dynamic>.from(e))
.map((e) => GameComment.fromJson(e))
.toList();
}
}
///
class GameComment extends CommentBase {
late String game;
GameComment.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.game = json["_game"];
}
}
///
class GameCommentChildrenPage extends Page {
late List<GameCommentChild> docs;
GameCommentChildrenPage.fromJson(Map<String, dynamic> json)
: super.fromJson(json) {
this.docs = [];
if (json["docs"] != null) {
docs.addAll(
List.of(json["docs"]).map((e) => GameCommentChild.fromJson(e)).toList());
}
}
}
///
class GameCommentChild extends ChildOfComment {
late String game;
GameCommentChild.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
this.game = json["_game"];
} }
} }

View File

@ -322,6 +322,14 @@ class Method {
return CommentChildrenPage.fromJson(json.decode(rsp)); return CommentChildrenPage.fromJson(json.decode(rsp));
} }
/// /
Future switchLikeComment(String commentId, String comicId) {
return _flatInvoke("switchLikeComment", {
"commentId": commentId,
"comicId": comicId,
});
}
/// ///
Future<MyCommentsPage> myComments(int page) async { Future<MyCommentsPage> myComments(int page) async {
String response = await _flatInvoke("myComments", "$page"); String response = await _flatInvoke("myComments", "$page");
@ -360,6 +368,53 @@ class Method {
return GameInfo.fromJson(json.decode(data)); return GameInfo.fromJson(json.decode(data));
} }
///
Future<GameCommentPage> gameComments(String gameId, int page) async {
var rsp = await _flatInvoke("gameComments", {
"gameId": gameId,
"page": page,
});
return GameCommentPage.fromJson(json.decode(rsp));
}
///
Future<dynamic> postGameComment(String gameId, String content) {
return _flatInvoke("postGameComment", {
"gameId": gameId,
"content": content,
});
}
///
Future<GameCommentChildrenPage> gameCommentChildren(
String gameId,
String commentId,
int page,
) async {
var rsp = await _flatInvoke("gameCommentChildren", {
"gameId": gameId,
"commentId": commentId,
"page": page,
});
return GameCommentChildrenPage.fromJson(json.decode(rsp));
}
/// /
Future switchLikeGameComment(String commentId, String gameId) {
return _flatInvoke("switchLikeGameComment", {
"commentId": commentId,
"gameId": gameId,
});
}
///
Future<dynamic> postGameChildComment(String commentId, String content) {
return _flatInvoke("postGameChildComment", {
"commentId": commentId,
"content": content,
});
}
/// ///
Future cleanNetworkCache() { Future cleanNetworkCache() {
return _flatInvoke("cleanNetworkCache", ""); return _flatInvoke("cleanNetworkCache", "");
@ -611,14 +666,6 @@ class Method {
return _flatInvoke("saveDownloadThreadCount", "$value"); return _flatInvoke("saveDownloadThreadCount", "$value");
} }
/// /
Future switchLikeComment(String commentId, String comicId) {
return _flatInvoke("switchLikeComment", {
"commentId": commentId,
"comicId": comicId,
});
}
/// PNG /// PNG
Future<Uint8List> convertToPNG(String path) async { Future<Uint8List> convertToPNG(String path) async {
return await _channel.invokeMethod("convertToPNG", {"path": path}); return await _channel.invokeMethod("convertToPNG", {"path": path});

View File

@ -5,11 +5,12 @@ import 'package:pikapi/basic/Cross.dart';
import 'package:pikapi/basic/Entities.dart'; import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/screens/ComicsScreen.dart'; import 'package:pikapi/screens/ComicsScreen.dart';
import 'package:pikapi/basic/Navigatior.dart'; import 'package:pikapi/basic/Navigatior.dart';
import 'package:pikapi/screens/components/CommentMainType.dart';
import 'package:pikapi/screens/components/ItemBuilder.dart'; import 'package:pikapi/screens/components/ItemBuilder.dart';
import 'package:pikapi/basic/Method.dart'; import 'package:pikapi/basic/Method.dart';
import 'ComicReaderScreen.dart'; import 'ComicReaderScreen.dart';
import 'DownloadConfirmScreen.dart'; import 'DownloadConfirmScreen.dart';
import 'components/ComicCommentList.dart'; import 'components/CommentList.dart';
import 'components/ComicDescriptionCard.dart'; import 'components/ComicDescriptionCard.dart';
import 'components/ComicInfoCard.dart'; import 'components/ComicInfoCard.dart';
import 'components/ComicTagsCard.dart'; import 'components/ComicTagsCard.dart';
@ -104,7 +105,7 @@ class _ComicInfoScreenState extends State<ComicInfoScreen> with RouteAware {
]; ];
var _views = <Widget>[ var _views = <Widget>[
_buildEpWrap(_epListFuture, _comicInfo), _buildEpWrap(_epListFuture, _comicInfo),
ComicCommentList(_comicInfo.id), CommentList(CommentMainType.COMIC, _comicInfo.id),
]; ];
return DefaultTabController( return DefaultTabController(
length: _tabs.length, length: _tabs.length,

View File

@ -1,15 +1,34 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pikapi/basic/Common.dart'; import 'package:pikapi/basic/Common.dart';
import 'package:pikapi/basic/Entities.dart'; import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/basic/Entities.dart' as e;
import 'package:pikapi/basic/Method.dart'; import 'package:pikapi/basic/Method.dart';
import 'package:pikapi/screens/components/ComicCommentItem.dart'; import 'package:pikapi/screens/components/CommentItem.dart';
import 'package:pikapi/screens/components/CommentMainType.dart';
import 'package:pikapi/screens/components/ContentBuilder.dart'; import 'package:pikapi/screens/components/ContentBuilder.dart';
class CommentScreen extends StatefulWidget { class _CommentChildPage extends e.Page {
final String comicId; late List<ChildOfComment> docs;
final Comment comment;
const CommentScreen(this.comicId, this.comment); _CommentChildPage.ofComic(CommentChildrenPage commentPage)
: super.of(commentPage.total, commentPage.limit, commentPage.page,
commentPage.pages) {
this.docs = commentPage.docs;
}
_CommentChildPage.ofGame(GameCommentChildrenPage commentPage)
: super.of(commentPage.total, commentPage.limit, commentPage.page,
commentPage.pages) {
this.docs = commentPage.docs;
}
}
class CommentScreen extends StatefulWidget {
final CommentMainType mainType;
final String mainId;
final CommentBase comment;
const CommentScreen(this.mainType, this.mainId, this.comment);
@override @override
State<StatefulWidget> createState() => _CommentScreenState(); State<StatefulWidget> createState() => _CommentScreenState();
@ -17,14 +36,23 @@ class CommentScreen extends StatefulWidget {
class _CommentScreenState extends State<CommentScreen> { class _CommentScreenState extends State<CommentScreen> {
late int _currentPage = 1; late int _currentPage = 1;
late Future<CommentChildrenPage> _future = _loadPage(); late Future<_CommentChildPage> _future = _loadPage();
Future<CommentChildrenPage> _loadPage() { Future<_CommentChildPage> _loadPage() async {
return method.commentChildren( switch (widget.mainType) {
widget.comicId, case CommentMainType.COMIC:
return _CommentChildPage.ofComic(await method.commentChildren(
widget.mainId,
widget.comment.id, widget.comment.id,
_currentPage, _currentPage,
); ));
case CommentMainType.GAME:
return _CommentChildPage.ofGame(await method.gameCommentChildren(
widget.mainId,
widget.comment.id,
_currentPage,
));
}
} }
Widget _buildChildrenPager() { Widget _buildChildrenPager() {
@ -32,7 +60,7 @@ class _CommentScreenState extends State<CommentScreen> {
future: _future, future: _future,
onRefresh: _loadPage, onRefresh: _loadPage,
successBuilder: successBuilder:
(BuildContext context, AsyncSnapshot<CommentChildrenPage> snapshot) { (BuildContext context, AsyncSnapshot<_CommentChildPage> snapshot) {
var page = snapshot.data!; var page = snapshot.data!;
return ListView( return ListView(
children: [ children: [
@ -54,7 +82,7 @@ class _CommentScreenState extends State<CommentScreen> {
), ),
body: Column( body: Column(
children: [ children: [
ComicCommentItem(widget.comment, widget.comicId), ComicCommentItem(widget.mainType, widget.mainId, widget.comment),
Container( Container(
height: 3, height: 3,
color: color:
@ -67,8 +95,8 @@ class _CommentScreenState extends State<CommentScreen> {
); );
} }
Widget _buildComment(CommentChild e) { Widget _buildComment(CommentBase e) {
return ComicCommentItem(e, widget.comicId); return ComicCommentItem(widget.mainType, widget.mainId, e);
} }
Widget _buildPostComment() { Widget _buildPostComment() {
@ -77,7 +105,14 @@ class _CommentScreenState extends State<CommentScreen> {
String? text = await inputString(context, '请输入评论内容'); String? text = await inputString(context, '请输入评论内容');
if (text != null && text.isNotEmpty) { if (text != null && text.isNotEmpty) {
try { try {
switch (widget.mainType) {
case CommentMainType.COMIC:
await method.postChildComment(widget.comment.id, text); await method.postChildComment(widget.comment.id, text);
break;
case CommentMainType.GAME:
await method.postGameChildComment(widget.comment.id, text);
break;
}
setState(() { setState(() {
_future = _loadPage(); _future = _loadPage();
widget.comment.commentsCount++; widget.comment.commentsCount++;
@ -110,7 +145,7 @@ class _CommentScreenState extends State<CommentScreen> {
); );
} }
Widget _buildPrePage(CommentChildrenPage page) { Widget _buildPrePage(_CommentChildPage page) {
if (page.page > 1) { if (page.page > 1) {
return InkWell( return InkWell(
onTap: () { onTap: () {
@ -130,7 +165,7 @@ class _CommentScreenState extends State<CommentScreen> {
return Container(); return Container();
} }
Widget _buildNextPage(CommentChildrenPage page) { Widget _buildNextPage(_CommentChildPage page) {
if (page.page < page.pages) { if (page.page < page.pages) {
return InkWell( return InkWell(
onTap: () { onTap: () {

View File

@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:pikapi/basic/Entities.dart'; import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/basic/Method.dart'; import 'package:pikapi/basic/Method.dart';
import 'package:pikapi/screens/components/CommentMainType.dart';
import 'package:pikapi/screens/components/ContentError.dart'; import 'package:pikapi/screens/components/ContentError.dart';
import 'package:pikapi/screens/components/ContentLoading.dart'; import 'package:pikapi/screens/components/ContentLoading.dart';
import 'package:pikapi/screens/components/Images.dart'; import 'package:pikapi/screens/components/Images.dart';
import 'GameDownloadScreen.dart'; import 'GameDownloadScreen.dart';
import 'components/CommentList.dart';
import 'components/GameTitleCard.dart'; import 'components/GameTitleCard.dart';
// //
@ -59,7 +61,9 @@ class _GameInfoScreenState extends State<GameInfoScreen> {
return LayoutBuilder( return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
var info = snapshot.data!; var info = snapshot.data!;
return Scaffold( return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(info.title), title: Text(info.title),
), ),
@ -68,7 +72,10 @@ class _GameInfoScreenState extends State<GameInfoScreen> {
GameTitleCard(info), GameTitleCard(info),
Container( Container(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 20, right: 20, top: 5, bottom: 10, left: 20,
right: 20,
top: 5,
bottom: 10,
), ),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5)), borderRadius: BorderRadius.all(Radius.circular(5)),
@ -79,7 +86,8 @@ class _GameInfoScreenState extends State<GameInfoScreen> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => GameDownloadScreen(info)), builder: (context) =>
GameDownloadScreen(info)),
); );
}, },
child: Container( child: Container(
@ -119,16 +127,51 @@ class _GameInfoScreenState extends State<GameInfoScreen> {
.toList(), .toList(),
), ),
), ),
Container(height: 20),
Container( Container(
padding: EdgeInsets.all(20), child: Column(
child: Text(info.description, style: descriptionStyle), children: [
Container(
height: 40,
color: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.025),
child: TabBar(
tabs: <Widget>[
Tab(text: '详情 '),
Tab(text: '评论 (${info.commentsCount})'),
],
indicatorColor:
Theme.of(context).colorScheme.secondary,
labelColor:
Theme.of(context).colorScheme.secondary,
onTap: (val) async {
setState(() {
_tabIndex = val;
});
},
),
), ),
], ],
), ),
),
_tabIndex == 0
? Container(
padding: EdgeInsets.all(20),
child:
Text(info.description, style: descriptionStyle),
)
: CommentList(CommentMainType.GAME, info.id),
],
),
),
); );
}, },
); );
}, },
); );
} }
var _tabIndex = 0;
} }

View File

@ -4,12 +4,14 @@ import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/basic/Method.dart'; import 'package:pikapi/basic/Method.dart';
import 'Avatar.dart'; import 'Avatar.dart';
import 'CommentMainType.dart';
class ComicCommentItem extends StatefulWidget { class ComicCommentItem extends StatefulWidget {
final String comicId; final CommentMainType mainType;
final Comment comment; final String mainId;
final CommentBase comment;
const ComicCommentItem(this.comment, this.comicId); const ComicCommentItem(this.mainType, this.mainId, this.comment);
@override @override
State<StatefulWidget> createState() => _ComicCommentItem(); State<StatefulWidget> createState() => _ComicCommentItem();
@ -21,7 +23,6 @@ class _ComicCommentItem extends State<ComicCommentItem> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var comment = widget.comment; var comment = widget.comment;
var comicId = widget.comicId;
var theme = Theme.of(context); var theme = Theme.of(context);
var nameStyle = TextStyle(fontWeight: FontWeight.bold); var nameStyle = TextStyle(fontWeight: FontWeight.bold);
var levelStyle = TextStyle( var levelStyle = TextStyle(
@ -111,10 +112,20 @@ class _ComicCommentItem extends State<ComicCommentItem> {
likeLoading = true; likeLoading = true;
}); });
try { try {
switch (widget.mainType) {
case CommentMainType.COMIC:
await method.switchLikeComment( await method.switchLikeComment(
comment.id, comment.id,
comicId, widget.mainId,
); );
break;
case CommentMainType.GAME:
await method.switchLikeGameComment(
comment.id,
widget.mainId,
);
break;
}
setState(() { setState(() {
if (comment.isLiked) { if (comment.isLiked) {
comment.isLiked = false; comment.isLiked = false;

View File

@ -1,27 +1,55 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pikapi/basic/Common.dart'; import 'package:pikapi/basic/Common.dart';
import 'package:pikapi/basic/Entities.dart'; import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/basic/Entities.dart' as e;
import 'package:pikapi/screens/CommentScreen.dart'; import 'package:pikapi/screens/CommentScreen.dart';
import 'package:pikapi/screens/components/ItemBuilder.dart'; import 'package:pikapi/screens/components/ItemBuilder.dart';
import 'package:pikapi/basic/Method.dart'; import 'package:pikapi/basic/Method.dart';
import 'ComicCommentItem.dart'; import 'CommentItem.dart';
import 'CommentMainType.dart';
// class _CommentBasePage extends e.Page {
class ComicCommentList extends StatefulWidget { late List<CommentBase> docs;
final String comicId;
ComicCommentList(this.comicId); _CommentBasePage.ofComic(CommentPage commentPage)
: super.of(commentPage.total, commentPage.limit, commentPage.page,
commentPage.pages) {
this.docs = commentPage.docs;
}
@override _CommentBasePage.ofGame(GameCommentPage commentPage)
State<StatefulWidget> createState() => _ComicCommentListState(); : super.of(commentPage.total, commentPage.limit, commentPage.page,
commentPage.pages) {
this.docs = commentPage.docs;
}
} }
class _ComicCommentListState extends State<ComicCommentList> { //
late int _currentPage = 1; class CommentList extends StatefulWidget {
late Future<CommentPage> _future = _loadPage(); final CommentMainType mainType;
final String mainId;
Future<CommentPage> _loadPage() { CommentList(this.mainType, this.mainId);
return method.comments(widget.comicId, _currentPage);
@override
State<StatefulWidget> createState() => _CommentListState();
}
class _CommentListState extends State<CommentList> {
late int _currentPage = 1;
late Future<_CommentBasePage> _future = _loadPage();
Future<_CommentBasePage> _loadPage() async {
switch (widget.mainType) {
case CommentMainType.COMIC:
return _CommentBasePage.ofComic(
await method.comments(widget.mainId, _currentPage),
);
case CommentMainType.GAME:
return _CommentBasePage.ofGame(
await method.gameComments(widget.mainId, _currentPage),
);
}
} }
@override @override
@ -29,7 +57,7 @@ class _ComicCommentListState extends State<ComicCommentList> {
return ItemBuilder( return ItemBuilder(
future: _future, future: _future,
successBuilder: successBuilder:
(BuildContext context, AsyncSnapshot<CommentPage> snapshot) { (BuildContext context, AsyncSnapshot<_CommentBasePage> snapshot) {
var page = snapshot.data!; var page = snapshot.data!;
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -50,16 +78,17 @@ class _ComicCommentListState extends State<ComicCommentList> {
); );
} }
Widget _buildComment(Comment comment) { Widget _buildComment(CommentBase comment) {
return InkWell( return InkWell(
onTap: () { onTap: () {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => CommentScreen(widget.comicId, comment), builder: (context) =>
CommentScreen(widget.mainType, widget.mainId, comment),
), ),
); );
}, },
child: ComicCommentItem(comment, widget.comicId), child: ComicCommentItem(widget.mainType, widget.mainId, comment),
); );
} }
@ -69,7 +98,14 @@ class _ComicCommentListState extends State<ComicCommentList> {
String? text = await inputString(context, '请输入评论内容'); String? text = await inputString(context, '请输入评论内容');
if (text != null && text.isNotEmpty) { if (text != null && text.isNotEmpty) {
try { try {
await method.postComment(widget.comicId, text); switch (widget.mainType) {
case CommentMainType.COMIC:
await method.postComment(widget.mainId, text);
break;
case CommentMainType.GAME:
await method.postGameComment(widget.mainId, text);
break;
}
setState(() { setState(() {
_future = _loadPage(); _future = _loadPage();
}); });
@ -101,7 +137,7 @@ class _ComicCommentListState extends State<ComicCommentList> {
); );
} }
Widget _buildPrePage(CommentPage page) { Widget _buildPrePage(_CommentBasePage page) {
if (page.page > 1) { if (page.page > 1) {
return InkWell( return InkWell(
onTap: () { onTap: () {
@ -121,7 +157,7 @@ class _ComicCommentListState extends State<ComicCommentList> {
return Container(); return Container();
} }
Widget _buildNextPage(CommentPage page) { Widget _buildNextPage(_CommentBasePage page) {
if (page.page < page.pages) { if (page.page < page.pages) {
return InkWell( return InkWell(
onTap: () { onTap: () {

View File

@ -0,0 +1,4 @@
enum CommentMainType {
COMIC,
GAME,
}