Compare commits
No commits in common. "a16c957a8bd13e0cfd09928ca0a22fecd3681e44" and "4684e8a24fa34c790d1d448cb00efa151bedb225" have entirely different histories.
a16c957a8b
...
4684e8a24f
14 changed files with 129 additions and 280 deletions
|
|
@ -75,12 +75,10 @@ endif()
|
|||
if("m3shapes" IN_LIST ENABLE_MODULES)
|
||||
message(STATUS "Fetching M3Shapes module")
|
||||
include(FetchContent)
|
||||
set(M3SHAPES_REV bdc327b29f95394a732baf3c9b19658ba23755b6)
|
||||
FetchContent_Declare(
|
||||
m3shapes_external
|
||||
GIT_REPOSITORY https://github.com/soramanew/m3shapes.git
|
||||
GIT_TAG ${M3SHAPES_REV}
|
||||
SOURCE_DIR "${CMAKE_BINARY_DIR}/_deps/m3shapes-${M3SHAPES_REV}"
|
||||
GIT_TAG 356825d31f16052a782735cce264331cba0cb71b
|
||||
)
|
||||
FetchContent_MakeAvailable(m3shapes_external)
|
||||
message(STATUS "Done fetching M3Shapes module")
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ For example, to disable the bar on DP-1:
|
|||
"maxWindowIcons": 5,
|
||||
"activeTrail": false,
|
||||
"perMonitorWorkspaces": true,
|
||||
"label": " ",
|
||||
"label": " ",
|
||||
"occupiedLabel": "",
|
||||
"activeLabel": "",
|
||||
"capitalisation": "preserve",
|
||||
|
|
|
|||
|
|
@ -94,12 +94,6 @@ MouseArea {
|
|||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onWheel: e => e.accepted = true
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
|
|
|
|||
7
flake.lock
generated
7
flake.lock
generated
|
|
@ -24,17 +24,16 @@
|
|||
"m3shapes": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1781017666,
|
||||
"narHash": "sha256-kfHyzZaPHgqZML48OA+5JwBOsLdQJ2ci/aGPShvUB4Y=",
|
||||
"lastModified": 1777812556,
|
||||
"narHash": "sha256-E5nqOucRQBWKuT31AMekmfgMywRdHgSbU86R7t4BKKA=",
|
||||
"owner": "soramanew",
|
||||
"repo": "m3shapes",
|
||||
"rev": "bdc327b29f95394a732baf3c9b19658ba23755b6",
|
||||
"rev": "356825d31f16052a782735cce264331cba0cb71b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "soramanew",
|
||||
"repo": "m3shapes",
|
||||
"rev": "bdc327b29f95394a732baf3c9b19658ba23755b6",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
};
|
||||
|
||||
m3shapes = {
|
||||
url = "github:soramanew/m3shapes/bdc327b29f95394a732baf3c9b19658ba23755b6";
|
||||
url = "github:soramanew/m3shapes/356825d31f16052a782735cce264331cba0cb71b";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -189,11 +189,7 @@ Item {
|
|||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: {
|
||||
const min = Weather.formatTemp(forecastItem.modelData.minTempC).slice(0, -1);
|
||||
const max = Weather.formatTemp(forecastItem.modelData.maxTempC).slice(0, -1);
|
||||
return `${min} / ${max}`;
|
||||
}
|
||||
text: GlobalConfig.services.useFahrenheit ? forecastItem.modelData.maxTempF + "°" + " / " + forecastItem.modelData.minTempF + "°" : forecastItem.modelData.maxTempC + "°" + " / " + forecastItem.modelData.minTempC + "°"
|
||||
font: Tokens.font.body.builders.small.weight(Font.DemiBold).build()
|
||||
color: Colours.palette.m3tertiary
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ StyledWindow {
|
|||
|
||||
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
|
||||
readonly property bool hasSpecialWorkspace: (monitor?.lastIpcObject.specialWorkspace?.name.length ?? 0) > 0
|
||||
readonly property bool hasFullscreenOnNormalWs: monitor?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false
|
||||
readonly property bool hasFullscreen: {
|
||||
if (hasSpecialWorkspace) {
|
||||
const specialName = monitor?.lastIpcObject.specialWorkspace?.name;
|
||||
|
|
@ -30,7 +29,7 @@ StyledWindow {
|
|||
const specialWs = Hypr.workspaces.values.find(ws => ws.name === specialName);
|
||||
return specialWs?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false;
|
||||
}
|
||||
return hasFullscreenOnNormalWs;
|
||||
return monitor?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false;
|
||||
}
|
||||
|
||||
property real fsTransitionProg: hasFullscreen ? 1 : 0
|
||||
|
|
@ -65,7 +64,7 @@ StyledWindow {
|
|||
|
||||
name: "drawers"
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.layer: (fsTransitionProg > 0 && contentItem.Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
|
||||
WlrLayershell.layer: fsTransitionProg > 0 && contentItem.Config.general.showOverFullscreen ? WlrLayer.Overlay : WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.session ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
mask: hasFullscreen ? emptyRegion : regions
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ ColumnLayout {
|
|||
|
||||
PasswordInput {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
centerScale: Math.max(0.8, root.centerScale)
|
||||
centerWidth: root.centerWidth
|
||||
lock: root.lock
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import M3Shapes
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.services
|
||||
|
|
@ -11,19 +10,9 @@ import qs.modules.lock
|
|||
Item {
|
||||
id: root
|
||||
|
||||
required property real centerScale
|
||||
required property Pam pam
|
||||
readonly property alias placeholder: placeholder
|
||||
readonly property alias placeholderWidth: nonAnimPlaceholder.width
|
||||
property string buffer
|
||||
readonly property list<int> shapeQueue: {
|
||||
const shapes = [MaterialShape.Slanted, MaterialShape.Arch, MaterialShape.Fan, MaterialShape.Arrow, MaterialShape.SemiCircle, MaterialShape.Triangle, MaterialShape.Diamond, MaterialShape.ClamShell, MaterialShape.Pentagon, MaterialShape.Gem, MaterialShape.Sunny, MaterialShape.VerySunny, MaterialShape.Cookie4Sided, MaterialShape.Ghostish, MaterialShape.SoftBurst];
|
||||
for (let i = shapes.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[shapes[i], shapes[j]] = [shapes[j], shapes[i]];
|
||||
}
|
||||
return shapes;
|
||||
}
|
||||
|
||||
clip: true
|
||||
|
||||
|
|
@ -42,30 +31,22 @@ Item {
|
|||
target: root.pam
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: nonAnimPlaceholder
|
||||
StyledText {
|
||||
id: placeholder
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
text: {
|
||||
if (root.pam.passwd.active)
|
||||
return qsTr("Loading...");
|
||||
if (root.pam.state === "max")
|
||||
return qsTr("Max tries reached");
|
||||
return qsTr("You have reached the maximum number of tries");
|
||||
return qsTr("Enter your password");
|
||||
}
|
||||
font: placeholder.font
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: placeholder
|
||||
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 1
|
||||
|
||||
text: nonAnimPlaceholder.text
|
||||
|
||||
animate: true
|
||||
color: root.pam.passwd.active ? Colours.palette.m3secondary : Colours.palette.m3outline
|
||||
font: Tokens.font.body.builders.medium.scale(root.centerScale).width(110).build()
|
||||
font: Tokens.font.mono.medium
|
||||
|
||||
opacity: root.buffer ? 0 : 1
|
||||
|
||||
|
|
@ -79,12 +60,7 @@ Item {
|
|||
ListView {
|
||||
id: charList
|
||||
|
||||
readonly property int fullWidth: {
|
||||
let w = (count - 1) * spacing;
|
||||
for (let i = 0; i < count; i++)
|
||||
w += ((itemAtIndex(i) as CharItem)?.nonAnimWidthScale ?? 1) * implicitHeight;
|
||||
return w + implicitHeight; // Extra padding at ends
|
||||
}
|
||||
readonly property int fullWidth: count * (implicitHeight + spacing) - spacing
|
||||
|
||||
function bindImWidth(): void {
|
||||
imWidthBehavior.enabled = false;
|
||||
|
|
@ -106,7 +82,63 @@ Item {
|
|||
values: root.buffer.split("")
|
||||
}
|
||||
|
||||
delegate: CharItem {}
|
||||
delegate: StyledRect {
|
||||
id: ch
|
||||
|
||||
implicitWidth: implicitHeight
|
||||
implicitHeight: charList.implicitHeight
|
||||
|
||||
color: Colours.palette.m3onSurface
|
||||
radius: Tokens.rounding.medium / 2
|
||||
|
||||
opacity: 0
|
||||
scale: 0
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
scale = 1;
|
||||
}
|
||||
ListView.onRemove: removeAnim.start()
|
||||
|
||||
SequentialAnimation {
|
||||
id: removeAnim
|
||||
|
||||
PropertyAction {
|
||||
target: ch
|
||||
property: "ListView.delayRemove"
|
||||
value: true
|
||||
}
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
target: ch
|
||||
property: "opacity"
|
||||
to: 0
|
||||
}
|
||||
Anim {
|
||||
target: ch
|
||||
property: "scale"
|
||||
to: 0.5
|
||||
}
|
||||
}
|
||||
PropertyAction {
|
||||
target: ch
|
||||
property: "ListView.delayRemove"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
Anim {
|
||||
type: Anim.FastSpatial
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitWidth {
|
||||
id: imWidthBehavior
|
||||
|
|
@ -114,121 +146,4 @@ Item {
|
|||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
component CharItem: Item {
|
||||
id: char
|
||||
|
||||
required property int index
|
||||
property real nonAnimWidthScale: 1
|
||||
|
||||
implicitHeight: charList.implicitHeight
|
||||
|
||||
ListView.onRemove: {
|
||||
initAnim.stop();
|
||||
removeAnim.start();
|
||||
}
|
||||
|
||||
MaterialShape {
|
||||
id: charShape
|
||||
|
||||
anchors.centerIn: parent
|
||||
implicitSize: charList.implicitHeight * 1.5
|
||||
shape: root.shapeQueue[char.index % root.shapeQueue.length] ?? MaterialShape.Circle
|
||||
color: Colours.palette.m3onSurface
|
||||
|
||||
Behavior on color {
|
||||
CAnim {}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: initAnim
|
||||
|
||||
running: true
|
||||
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
target: charShape
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
Anim {
|
||||
target: charShape
|
||||
property: "scale"
|
||||
from: 0
|
||||
to: 1
|
||||
type: Anim.FastSpatial
|
||||
}
|
||||
Anim {
|
||||
target: char
|
||||
property: "implicitWidth"
|
||||
from: charList.implicitHeight
|
||||
to: charList.implicitHeight * 1.3
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
PropertyAction {
|
||||
target: char
|
||||
property: "nonAnimWidthScale"
|
||||
value: 1.5
|
||||
}
|
||||
}
|
||||
PauseAnimation {
|
||||
duration: 180 * Tokens.anim.durations.scale
|
||||
}
|
||||
PropertyAction {
|
||||
target: charShape
|
||||
property: "shape"
|
||||
value: MaterialShape.Circle
|
||||
}
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
target: charShape
|
||||
property: "scale"
|
||||
to: 2 / 3
|
||||
type: Anim.FastSpatial
|
||||
}
|
||||
Anim {
|
||||
target: char
|
||||
property: "implicitWidth"
|
||||
to: charList.implicitHeight
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
PropertyAction {
|
||||
target: char
|
||||
property: "nonAnimWidthScale"
|
||||
value: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: removeAnim
|
||||
|
||||
PropertyAction {
|
||||
target: char
|
||||
property: "ListView.delayRemove"
|
||||
value: true
|
||||
}
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
target: charShape
|
||||
property: "opacity"
|
||||
to: 0
|
||||
}
|
||||
Anim {
|
||||
target: charShape
|
||||
property: "scale"
|
||||
to: 0.5
|
||||
}
|
||||
}
|
||||
PropertyAction {
|
||||
target: char
|
||||
property: "ListView.delayRemove"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import M3Shapes
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
|
|
@ -11,14 +8,10 @@ import qs.services
|
|||
StyledRect {
|
||||
id: root
|
||||
|
||||
required property real centerScale
|
||||
required property int centerWidth
|
||||
required property var lock
|
||||
|
||||
implicitWidth: {
|
||||
const w = centerWidth * 0.8;
|
||||
return lock.pam.buffer ? w : Math.min(w, inputField.placeholderWidth + iconWrapper.implicitWidth + enterButton.implicitWidth + input.spacing * 2 + Tokens.padding.medium * 2);
|
||||
}
|
||||
implicitWidth: centerWidth * 0.8
|
||||
implicitHeight: input.implicitHeight + Tokens.padding.small
|
||||
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
|
|
@ -40,10 +33,6 @@ StyledRect {
|
|||
root.lock.pam.handleKey(event);
|
||||
}
|
||||
|
||||
Behavior on implicitWidth {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
StateLayer {
|
||||
hoverEnabled: false
|
||||
cursorShape: Qt.IBeamCursor
|
||||
|
|
@ -58,39 +47,44 @@ StyledRect {
|
|||
spacing: Tokens.spacing.medium
|
||||
|
||||
Item {
|
||||
id: iconWrapper
|
||||
|
||||
Layout.fillHeight: true
|
||||
implicitWidth: height
|
||||
|
||||
AnimLoader {
|
||||
MaterialIcon {
|
||||
id: fprintIcon
|
||||
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: sourceComponent === iconComp ? 1 : 0
|
||||
sourceComp: root.lock.pam.passwd.active ? loadingComp : iconComp
|
||||
}
|
||||
animate: true
|
||||
text: {
|
||||
if (root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries)
|
||||
return "fingerprint_off";
|
||||
if (root.lock.pam.fprint.active)
|
||||
return "fingerprint";
|
||||
return "lock";
|
||||
}
|
||||
color: root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries ? Colours.palette.m3error : Colours.palette.m3onSurface
|
||||
opacity: root.lock.pam.passwd.active ? 0 : 1
|
||||
|
||||
Component {
|
||||
id: iconComp
|
||||
|
||||
MaterialIcon {
|
||||
animate: true
|
||||
text: {
|
||||
if (root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries)
|
||||
return "fingerprint_off";
|
||||
if (root.lock.pam.fprint.active)
|
||||
return "fingerprint";
|
||||
return "lock";
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
color: root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant
|
||||
fontStyle: Tokens.font.icon.builders.medium.scale(root.centerScale).build()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loadingComp
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Tokens.padding.small
|
||||
|
||||
LoadingIndicator {
|
||||
implicitSize: iconWrapper.height - Tokens.padding.small * 2
|
||||
active: opacity > 0
|
||||
opacity: root.lock.pam.passwd.active ? 1 : 0
|
||||
|
||||
sourceComponent: LoadingIndicator {}
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,45 +95,19 @@ StyledRect {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
centerScale: root.centerScale
|
||||
pam: root.lock.pam
|
||||
}
|
||||
|
||||
Item {
|
||||
id: enterButton
|
||||
|
||||
StyledRect {
|
||||
implicitWidth: implicitHeight
|
||||
implicitHeight: {
|
||||
const h = enterIcon.implicitHeight + Tokens.padding.extraSmall * 2;
|
||||
return h % 2 === 0 ? h : h + 1;
|
||||
}
|
||||
implicitHeight: enterIcon.implicitHeight + Tokens.padding.small
|
||||
|
||||
MaterialShape {
|
||||
anchors.fill: parent
|
||||
color: root.lock.pam.buffer ? Colours.palette.m3primary : Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
||||
radius: Tokens.rounding.full
|
||||
|
||||
color: root.lock.pam.buffer ? Colours.palette.m3primary : Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
||||
shape: root.lock.pam.buffer ? MaterialShape.Arrow : MaterialShape.Circle
|
||||
scale: !root.lock.pam.buffer ? 1 : mouse.pressed ? 0.6 : mouse.containsMouse ? 0.8 : 0.7
|
||||
rotation: 90
|
||||
|
||||
Behavior on scale {
|
||||
Anim {
|
||||
type: Anim.FastSpatial
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
CAnim {}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: root.lock.pam.buffer ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: root.lock.pam.buffer && root.lock.pam.passwd.start()
|
||||
}
|
||||
StateLayer {
|
||||
color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
|
||||
onClicked: root.lock.pam.passwd.start()
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
|
|
@ -147,15 +115,8 @@ StyledRect {
|
|||
|
||||
anchors.centerIn: parent
|
||||
text: "arrow_forward"
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
fontStyle: Tokens.font.icon.builders.medium.scale(root.centerScale * 1.2).build()
|
||||
opacity: root.lock.pam.buffer ? 0 : 1
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
|
||||
fontStyle: Tokens.font.icon.size(Tokens.font.icon.large.pointSize).weight(Font.Medium).build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ Item {
|
|||
opacity: root.stateMsgShouldBeVisible && !root.msg ? 1 : 0
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
|
||||
font: Tokens.font.body.small
|
||||
font: Tokens.font.mono.small
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
lineHeight: 1.2
|
||||
|
|
@ -145,7 +145,7 @@ Item {
|
|||
opacity: 0
|
||||
color: Colours.palette.m3error
|
||||
|
||||
font: Tokens.font.body.small
|
||||
font: Tokens.font.mono.small
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ class UserPaths : public ConfigObject {
|
|||
|
||||
CONFIG_GLOBAL_PROPERTY(
|
||||
QString, wallpaperDir, QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + u"/Wallpapers"_s)
|
||||
CONFIG_GLOBAL_PROPERTY(
|
||||
QString, lyricsDir, QStandardPaths::writableLocation(QStandardPaths::MusicLocation) + u"/Lyrics/"_s)
|
||||
CONFIG_GLOBAL_PROPERTY(QString, lyricsDir, QDir::homePath() + u"/Music/lyrics/"_s)
|
||||
CONFIG_PROPERTY(QString, sessionGif, u"root:/assets/kurukuru.gif"_s)
|
||||
CONFIG_PROPERTY(QString, mediaGif, u"root:/assets/bongocat.gif"_s)
|
||||
CONFIG_PROPERTY(QString, noNotifsPic, u"root:/assets/dino.png"_s)
|
||||
|
|
|
|||
|
|
@ -788,6 +788,7 @@ void Lyrics::onPreferredBackendConfigChanged() {
|
|||
}
|
||||
|
||||
void Lyrics::onLyricsDirChanged() {
|
||||
loadLyricsMap();
|
||||
scheduleLoad();
|
||||
}
|
||||
|
||||
|
|
@ -827,7 +828,11 @@ void Lyrics::persistTrackPrefs() {
|
|||
}
|
||||
m_lyricsMap.insert(key, entry);
|
||||
|
||||
QDir().mkpath(stateDir());
|
||||
const QString dir = lyricsDir();
|
||||
if (dir.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QDir().mkpath(dir);
|
||||
|
||||
QSaveFile out(lyricsMapPath());
|
||||
if (!out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
|
|
@ -850,11 +855,6 @@ QString Lyrics::lyricsDir() const {
|
|||
if (dir.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
if (dir == u"~"_s) {
|
||||
dir = QDir::homePath();
|
||||
} else if (dir.startsWith(u"~/"_s)) {
|
||||
dir.replace(0, 1, QDir::homePath());
|
||||
}
|
||||
while (dir.endsWith(QLatin1Char('/')) && dir.size() > 1) {
|
||||
dir.chop(1);
|
||||
}
|
||||
|
|
@ -862,7 +862,8 @@ QString Lyrics::lyricsDir() const {
|
|||
}
|
||||
|
||||
QString Lyrics::lyricsMapPath() const {
|
||||
return stateDir() + u"/lyrics_map.json"_s;
|
||||
const QString dir = lyricsDir();
|
||||
return dir.isEmpty() ? QString() : dir + u"/lyrics_map.json"_s;
|
||||
}
|
||||
|
||||
QString Lyrics::trackKey() const {
|
||||
|
|
@ -875,41 +876,30 @@ QString Lyrics::trackKey() const {
|
|||
QString Lyrics::backendKey(LyricsBackend::Backend value) {
|
||||
switch (value) {
|
||||
case LyricsBackend::Local:
|
||||
return u"Local"_s;
|
||||
return u"LyricsBackend::Local"_s;
|
||||
case LyricsBackend::LRCLIB:
|
||||
return u"LRCLIB"_s;
|
||||
return u"LyricsBackend::LRCLIB"_s;
|
||||
case LyricsBackend::NetEase:
|
||||
return u"NetEase"_s;
|
||||
return u"LyricsBackend::NetEase"_s;
|
||||
case LyricsBackend::Auto:
|
||||
default:
|
||||
return u"Auto"_s;
|
||||
return u"LyricsBackend::Auto"_s;
|
||||
}
|
||||
}
|
||||
|
||||
LyricsBackend::Backend Lyrics::backendFromKey(const QString& key) {
|
||||
if (key.compare(u"Local"_s, Qt::CaseInsensitive) == 0) {
|
||||
if (key.compare(u"LyricsBackend::Local"_s, Qt::CaseInsensitive) == 0) {
|
||||
return LyricsBackend::Local;
|
||||
}
|
||||
if (key.compare(u"LRCLIB"_s, Qt::CaseInsensitive) == 0) {
|
||||
if (key.compare(u"LyricsBackend::LRCLIB"_s, Qt::CaseInsensitive) == 0) {
|
||||
return LyricsBackend::LRCLIB;
|
||||
}
|
||||
if (key.compare(u"NetEase"_s, Qt::CaseInsensitive) == 0) {
|
||||
if (key.compare(u"LyricsBackend::NetEase"_s, Qt::CaseInsensitive) == 0) {
|
||||
return LyricsBackend::NetEase;
|
||||
}
|
||||
return LyricsBackend::Auto;
|
||||
}
|
||||
|
||||
const QString& Lyrics::stateDir() {
|
||||
static const QString s_dir = [] {
|
||||
QString state = qEnvironmentVariable("XDG_STATE_HOME");
|
||||
if (state.isEmpty()) {
|
||||
state = QDir::homePath() + u"/.local/state"_s;
|
||||
}
|
||||
return state + u"/caelestia/lyrics"_s;
|
||||
}();
|
||||
return s_dir;
|
||||
}
|
||||
|
||||
const QString& Lyrics::cacheDir() {
|
||||
static const QString s_dir = [] {
|
||||
QString cache = qEnvironmentVariable("XDG_CACHE_HOME");
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ private:
|
|||
[[nodiscard]] static QString backendKey(LyricsBackend::Backend value);
|
||||
[[nodiscard]] static LyricsBackend::Backend backendFromKey(const QString& key);
|
||||
|
||||
[[nodiscard]] static const QString& stateDir();
|
||||
[[nodiscard]] static const QString& cacheDir();
|
||||
[[nodiscard]] static QString cachePathFor(LyricsBackend::Backend backend, const QString& id);
|
||||
[[nodiscard]] static QString readCachedLrc(LyricsBackend::Backend backend, const QString& id);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue