diff --git a/Fk/Config.qml b/Fk/Config.qml
index 8f544b53..8609754d 100644
--- a/Fk/Config.qml
+++ b/Fk/Config.qml
@@ -40,6 +40,7 @@ QtObject {
property int roomTimeout: 0
property bool enableFreeAssign: false
property bool observing: false
+ property bool replaying: false
property var blockedUsers: []
function loadConf() {
diff --git a/Fk/Logic.js b/Fk/Logic.js
index 3d15eb4b..2639edc1 100644
--- a/Fk/Logic.js
+++ b/Fk/Logic.js
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+/*
var generalsOverviewPage, cardsOverviewPage;
var clientPageCreated = false;
function createClientPages() {
@@ -13,6 +14,7 @@ function createClientPages() {
mainWindow.cardsOverviewPage = cardsOverviewPage;
}
}
+*/
var callbacks = {};
let sheduled_download = "";
@@ -98,7 +100,7 @@ callbacks["BackToStart"] = (jsonData) => {
callbacks["EnterLobby"] = (jsonData) => {
// depth == 1 means the lobby page is not present in mainStack
- createClientPages();
+ // createClientPages();
if (mainStack.depth === 1) {
// we enter the lobby successfully, so save password now.
config.lastLoginServer = config.serverAddr;
diff --git a/Fk/Pages/Lobby.qml b/Fk/Pages/Lobby.qml
index 75303d62..1cf33337 100644
--- a/Fk/Pages/Lobby.qml
+++ b/Fk/Pages/Lobby.qml
@@ -168,6 +168,7 @@ Item {
lobby_dialog.sourceComponent = Qt.createComponent("../LobbyElement/CreateRoom.qml");
lobby_drawer.open();
config.observing = false;
+ config.replaying = false;
}
}
@@ -197,6 +198,9 @@ Item {
}
Button {
text: Backend.translate("Replay")
+ onClicked: {
+ mainStack.push(mainWindow.replayPage);
+ }
}
Button {
text: Backend.translate("About")
@@ -279,6 +283,7 @@ Item {
}
function enterRoom(roomId, playerNum, capacity, pw) {
+ config.replaying = false;
if (playerNum < capacity) {
config.observing = false;
Backend.callLuaFunction("SetObserving", [false]);
diff --git a/Fk/Pages/Replay.qml b/Fk/Pages/Replay.qml
new file mode 100644
index 00000000..81b461b0
--- /dev/null
+++ b/Fk/Pages/Replay.qml
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Fk
+
+Item {
+ id: root
+
+ ToolBar {
+ id: bar
+ width: parent.width
+ RowLayout {
+ anchors.fill: parent
+ ToolButton {
+ icon.source: AppPath + "/image/modmaker/back"
+ onClicked: mainStack.pop();
+ }
+ Label {
+ text: Backend.translate("Replay Manager")
+ horizontalAlignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ }
+ ToolButton {
+ icon.source: AppPath + "/image/modmaker/menu"
+ onClicked: menu.open()
+
+ Menu {
+ id: menu
+ y: bar.height
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ width: parent.width
+ height: parent.height - bar.height
+ anchors.top: bar.bottom
+ color: "snow"
+ opacity: 0.75
+ clip: true
+
+ ListView {
+ id: list
+ clip: true
+ anchors.fill: parent
+ model: ListModel {
+ id: model
+ }
+ delegate: Item {
+ width: root.width
+ height: 64
+
+ Image {
+ id: generalPic
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.margins: 8
+ width: 48
+ height: 48
+ source: SkinBank.getGeneralExtraPic(general, "avatar/") ?? SkinBank.getGeneralPicture(general)
+ sourceClipRect: sourceSize.width > 200 ? Qt.rect(61, 0, 128, 128) : undefined
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.width: 1
+ }
+ }
+
+ ColumnLayout {
+ anchors.left: generalPic.right
+ anchors.margins: 8
+ Text {
+ text: {
+ const win = winner.split("+").indexOf(role) !== -1;
+ const winStr = win ? Backend.translate("Game Win") : Backend.translate("Game Lose");
+ return "" + Backend.translate(general) + " " + Backend.translate(role) + " " + winStr;
+ }
+ font.pixelSize: 20
+ textFormat: Text.RichText
+ }
+ Text {
+ text: {
+ const y = repDate.slice(0,4);
+ const month = repDate.slice(4,6);
+ const d = repDate.slice(6,8);
+ const h = repDate.slice(8,10);
+ const m = repDate.slice(10,12);
+ const s = repDate.slice(12,14);
+ const dateStr = y + "-" + month + "-" + d + " " + h + ":" + m + ":" + s;
+
+ return playerName + " " + Backend.translate(gameMode) + " " + dateStr
+ }
+ }
+ }
+
+ Button {
+ id: replayBtn
+ text: Backend.translate("Play the Replay")
+ anchors.right: delBtn.left
+ anchors.rightMargin: 8
+ onClicked: {
+ config.observing = true;
+ config.replaying = true;
+ Backend.playRecord(fileName);
+ }
+ }
+
+ Button {
+ id: delBtn
+ text: Backend.translate("Delete Replay")
+ anchors.right: parent.right
+ anchors.rightMargin: 8
+ onClicked: {
+ Backend.removeRecord(fileName);
+ removeModel(index);
+ }
+ }
+ }
+ }
+ }
+
+ function updateList() {
+ model.clear();
+ const data = Backend.ls("recording");
+ data.reverse();
+ data.forEach(s => {
+ const d = s.split(".");
+ if (d.length !== 8) return;
+ // s: