Files
dms-gamebar/widgets/NotepadWidget.qml
T

194 lines
5.9 KiB
QML

import QtQuick
import QtQuick.Controls
import Quickshell
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: widget
readonly property var currentTab: {
const tabs = NotepadStorageService.tabs || [];
const index = NotepadStorageService.currentTabIndex;
return (index >= 0 && index < tabs.length) ? tabs[index] : null;
}
// DMS only writes back temporary (scratch) tabs automatically; a tab backed
// by a real file is shown read-only so edits here cannot clobber it.
readonly property bool editable: currentTab !== null && currentTab.isTemporary === true
property bool contentLoaded: false
property int loadedTabId: -1
property bool applyingRemote: false
property bool dirty: false
function loadContent() {
if (!widget.currentTab)
return;
const tabId = widget.currentTab.id;
widget.contentLoaded = false;
NotepadStorageService.loadTabContent(NotepadStorageService.currentTabIndex, content => {
const buffer = NotepadStorageService.getSessionBuffer(tabId);
widget.applyingRemote = true;
editor.text = (buffer !== undefined) ? buffer.content : content;
widget.applyingRemote = false;
widget.loadedTabId = tabId;
widget.contentLoaded = true;
widget.dirty = false;
});
}
function save() {
if (!widget.contentLoaded || !widget.editable || widget.loadedTabId < 0)
return;
NotepadStorageService.setSessionBuffer(widget.loadedTabId, editor.text, editor.text);
NotepadStorageService.saveTabContent(NotepadStorageService.currentTabIndex, editor.text);
widget.dirty = false;
}
Ref {
service: NotepadStorageService
}
Component.onCompleted: widget.loadContent()
Component.onDestruction: {
if (widget.dirty)
widget.save();
}
Connections {
target: NotepadStorageService
function onCurrentTabIndexChanged() {
widget.loadContent();
}
}
Timer {
id: saveTimer
interval: 900
repeat: false
onTriggered: widget.save()
}
Rectangle {
id: editorFrame
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: footer.top
anchors.bottomMargin: Theme.spacingXS
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency)
border.color: editor.activeFocus ? Theme.primary : Theme.outlineLight
border.width: editor.activeFocus ? 1 : Theme.layerOutlineWidth
clip: true
DankFlickable {
id: editorFlick
anchors.fill: parent
anchors.margins: Theme.spacingS
contentWidth: width
contentHeight: editor.implicitHeight
clip: true
TextArea {
id: editor
width: editorFlick.width
readOnly: !widget.editable
wrapMode: TextArea.Wrap
selectByMouse: true
placeholderText: widget.editable ? "Notes, seeds, codes…" : "Open the DMS notepad to edit this tab"
color: Theme.surfaceText
placeholderTextColor: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeMedium
font.family: Theme.monoFontFamily
background: null
onTextChanged: {
if (widget.applyingRemote || !widget.contentLoaded || !widget.editable)
return;
widget.dirty = true;
saveTimer.restart();
}
}
}
}
Item {
id: footer
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 26
StyledText {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.right: openButton.left
anchors.rightMargin: Theme.spacingS
text: {
if (!widget.currentTab)
return "No notepad tab";
if (!widget.editable)
return widget.currentTab.title + " · read-only here";
return widget.currentTab.title + (widget.dirty ? " · saving…" : " · saved");
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
}
Rectangle {
id: openButton
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: openRow.width + Theme.spacingM * 2
height: 24
radius: Theme.cornerRadius
color: openArea.containsMouse ? Theme.surfaceHover : "transparent"
Row {
id: openRow
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
anchors.verticalCenter: parent.verticalCenter
name: "open_in_new"
size: Theme.fontSizeMedium
color: Theme.surfaceVariantText
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: "Full notepad"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
}
MouseArea {
id: openArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
widget.save();
Quickshell.execDetached(["dms", "ipc", "call", "notepad", "toggle"]);
}
}
}
}
}