mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
Compare commits
9 Commits
faddc46185
...
913bb2ff67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
913bb2ff67 | ||
|
|
3bb2696263 | ||
|
|
166843ded4 | ||
|
|
02166a4ca5 | ||
|
|
f0f2e6ef72 | ||
|
|
8d8d5de5fd | ||
|
|
6d76f0b476 | ||
|
|
f3f720bb37 | ||
|
|
2bf85bc4dd |
9
.github/workflows/prek.yml
vendored
9
.github/workflows/prek.yml
vendored
@@ -11,5 +11,14 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install flatpak
|
||||||
|
run: sudo apt update && sudo apt install -y flatpak
|
||||||
|
|
||||||
|
- name: Add flathub
|
||||||
|
run: sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
|
||||||
|
- name: Add a flatpak that mutagen could support
|
||||||
|
run: sudo flatpak install -y org.freedesktop.Platform/x86_64/24.08 app.zen_browser.zen
|
||||||
|
|
||||||
- name: run pre-commit hooks
|
- name: run pre-commit hooks
|
||||||
uses: j178/prek-action@v1
|
uses: j178/prek-action@v1
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ This file is more of a quick reference so I know what to account for before next
|
|||||||
- new IPC targets
|
- new IPC targets
|
||||||
- Initial RTL support/i18n
|
- Initial RTL support/i18n
|
||||||
- Theme registry
|
- Theme registry
|
||||||
|
- Notification persistence & history
|
||||||
|
|||||||
@@ -513,5 +513,6 @@ func getCommonCommands() []*cobra.Command {
|
|||||||
notifyActionCmd,
|
notifyActionCmd,
|
||||||
matugenCmd,
|
matugenCmd,
|
||||||
clipboardCmd,
|
clipboardCmd,
|
||||||
|
doctorCmd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
853
core/cmd/dms/commands_doctor.go
Normal file
853
core/cmd/dms/commands_doctor.go
Normal file
@@ -0,0 +1,853 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/config"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/distros"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/brightness"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/network"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/tui"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/version"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type status string
|
||||||
|
|
||||||
|
const (
|
||||||
|
statusOK status = "ok"
|
||||||
|
statusWarn status = "warn"
|
||||||
|
statusError status = "error"
|
||||||
|
statusInfo status = "info"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s status) IconStyle(styles tui.Styles) (string, lipgloss.Style) {
|
||||||
|
switch s {
|
||||||
|
case statusOK:
|
||||||
|
return "●", styles.Success
|
||||||
|
case statusWarn:
|
||||||
|
return "●", styles.Warning
|
||||||
|
case statusError:
|
||||||
|
return "●", styles.Error
|
||||||
|
default:
|
||||||
|
return "○", styles.Subtle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoctorStatus struct {
|
||||||
|
Errors []checkResult
|
||||||
|
Warnings []checkResult
|
||||||
|
OK []checkResult
|
||||||
|
Info []checkResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DoctorStatus) Add(r checkResult) {
|
||||||
|
switch r.status {
|
||||||
|
case statusError:
|
||||||
|
ds.Errors = append(ds.Errors, r)
|
||||||
|
case statusWarn:
|
||||||
|
ds.Warnings = append(ds.Warnings, r)
|
||||||
|
case statusOK:
|
||||||
|
ds.OK = append(ds.OK, r)
|
||||||
|
case statusInfo:
|
||||||
|
ds.Info = append(ds.Info, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DoctorStatus) HasIssues() bool {
|
||||||
|
return len(ds.Errors) > 0 || len(ds.Warnings) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DoctorStatus) ErrorCount() int {
|
||||||
|
return len(ds.Errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DoctorStatus) WarningCount() int {
|
||||||
|
return len(ds.Warnings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DoctorStatus) OKCount() int {
|
||||||
|
return len(ds.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
quickshellVersionRegex = regexp.MustCompile(`quickshell (\d+\.\d+\.\d+)`)
|
||||||
|
hyprlandVersionRegex = regexp.MustCompile(`v?(\d+\.\d+\.\d+)`)
|
||||||
|
niriVersionRegex = regexp.MustCompile(`niri (\d+\.\d+)`)
|
||||||
|
swayVersionRegex = regexp.MustCompile(`sway version (\d+\.\d+)`)
|
||||||
|
riverVersionRegex = regexp.MustCompile(`river (\d+\.\d+)`)
|
||||||
|
wayfireVersionRegex = regexp.MustCompile(`wayfire (\d+\.\d+)`)
|
||||||
|
)
|
||||||
|
|
||||||
|
var doctorCmd = &cobra.Command{
|
||||||
|
Use: "doctor",
|
||||||
|
Short: "Diagnose DMS installation and dependencies",
|
||||||
|
Long: "Check system health, verify dependencies, and diagnose configuration issues for DMS",
|
||||||
|
Run: runDoctor,
|
||||||
|
}
|
||||||
|
|
||||||
|
var doctorVerbose bool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
doctorCmd.Flags().BoolVarP(&doctorVerbose, "verbose", "v", false, "Show detailed output including paths and versions")
|
||||||
|
}
|
||||||
|
|
||||||
|
type category int
|
||||||
|
|
||||||
|
const (
|
||||||
|
catSystem category = iota
|
||||||
|
catVersions
|
||||||
|
catInstallation
|
||||||
|
catCompositor
|
||||||
|
catQuickshellFeatures
|
||||||
|
catOptionalFeatures
|
||||||
|
catConfigFiles
|
||||||
|
catServices
|
||||||
|
catEnvironment
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c category) String() string {
|
||||||
|
switch c {
|
||||||
|
case catSystem:
|
||||||
|
return "System"
|
||||||
|
case catVersions:
|
||||||
|
return "Versions"
|
||||||
|
case catInstallation:
|
||||||
|
return "Installation"
|
||||||
|
case catCompositor:
|
||||||
|
return "Compositor"
|
||||||
|
case catQuickshellFeatures:
|
||||||
|
return "Quickshell Features"
|
||||||
|
case catOptionalFeatures:
|
||||||
|
return "Optional Features"
|
||||||
|
case catConfigFiles:
|
||||||
|
return "Config Files"
|
||||||
|
case catServices:
|
||||||
|
return "Services"
|
||||||
|
case catEnvironment:
|
||||||
|
return "Environment"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
checkNameMaxLength = 21
|
||||||
|
)
|
||||||
|
|
||||||
|
type checkResult struct {
|
||||||
|
category category
|
||||||
|
name string
|
||||||
|
status status
|
||||||
|
message string
|
||||||
|
details string
|
||||||
|
}
|
||||||
|
|
||||||
|
func runDoctor(cmd *cobra.Command, args []string) {
|
||||||
|
printDoctorHeader()
|
||||||
|
|
||||||
|
qsFeatures, qsMissingFeatures := checkQuickshellFeatures()
|
||||||
|
|
||||||
|
results := slices.Concat(
|
||||||
|
checkSystemInfo(),
|
||||||
|
checkVersions(qsMissingFeatures),
|
||||||
|
checkDMSInstallation(),
|
||||||
|
checkWindowManagers(),
|
||||||
|
qsFeatures,
|
||||||
|
checkOptionalDependencies(),
|
||||||
|
checkConfigurationFiles(),
|
||||||
|
checkSystemdServices(),
|
||||||
|
checkEnvironmentVars(),
|
||||||
|
)
|
||||||
|
|
||||||
|
printResults(results)
|
||||||
|
printSummary(results, qsMissingFeatures)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printDoctorHeader() {
|
||||||
|
theme := tui.TerminalTheme()
|
||||||
|
styles := tui.NewStyles(theme)
|
||||||
|
|
||||||
|
fmt.Println(getThemedASCII())
|
||||||
|
fmt.Println(styles.Title.Render("System Health Check"))
|
||||||
|
fmt.Println(styles.Subtle.Render("──────────────────────────────────────"))
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSystemInfo() []checkResult {
|
||||||
|
var results []checkResult
|
||||||
|
|
||||||
|
osInfo, err := distros.GetOSInfo()
|
||||||
|
if err != nil {
|
||||||
|
status, message, details := statusWarn, fmt.Sprintf("Unknown (%v)", err), ""
|
||||||
|
|
||||||
|
if strings.Contains(err.Error(), "Unsupported distribution") {
|
||||||
|
osRelease := readOSRelease()
|
||||||
|
if osRelease["ID"] == "nixos" {
|
||||||
|
status = statusOK
|
||||||
|
message = osRelease["PRETTY_NAME"]
|
||||||
|
if message == "" {
|
||||||
|
message = fmt.Sprintf("NixOS %s", osRelease["VERSION_ID"])
|
||||||
|
}
|
||||||
|
details = "Supported for runtime (install via NixOS module or Flake)"
|
||||||
|
} else if osRelease["PRETTY_NAME"] != "" {
|
||||||
|
message = fmt.Sprintf("%s (not supported by dms setup)", osRelease["PRETTY_NAME"])
|
||||||
|
details = "DMS may work but automatic installation is not available"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, checkResult{catSystem, "Operating System", status, message, details})
|
||||||
|
} else {
|
||||||
|
status := statusOK
|
||||||
|
message := osInfo.PrettyName
|
||||||
|
if message == "" {
|
||||||
|
message = fmt.Sprintf("%s %s", osInfo.Distribution.ID, osInfo.VersionID)
|
||||||
|
}
|
||||||
|
if distros.IsUnsupportedDistro(osInfo.Distribution.ID, osInfo.VersionID) {
|
||||||
|
status = statusWarn
|
||||||
|
message += " (version may not be fully supported)"
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{
|
||||||
|
catSystem, "Operating System", status, message,
|
||||||
|
fmt.Sprintf("ID: %s, Version: %s, Arch: %s", osInfo.Distribution.ID, osInfo.VersionID, osInfo.Architecture),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
arch := runtime.GOARCH
|
||||||
|
archStatus := statusOK
|
||||||
|
if arch != "amd64" && arch != "arm64" {
|
||||||
|
archStatus = statusError
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catSystem, "Architecture", archStatus, arch, ""})
|
||||||
|
|
||||||
|
waylandDisplay := os.Getenv("WAYLAND_DISPLAY")
|
||||||
|
xdgSessionType := os.Getenv("XDG_SESSION_TYPE")
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case waylandDisplay != "" || xdgSessionType == "wayland":
|
||||||
|
results = append(results, checkResult{
|
||||||
|
catSystem, "Display Server", statusOK, "Wayland",
|
||||||
|
fmt.Sprintf("WAYLAND_DISPLAY=%s", waylandDisplay),
|
||||||
|
})
|
||||||
|
case xdgSessionType == "x11":
|
||||||
|
results = append(results, checkResult{catSystem, "Display Server", statusError, "X11 (DMS requires Wayland)", ""})
|
||||||
|
default:
|
||||||
|
results = append(results, checkResult{
|
||||||
|
catSystem, "Display Server", statusWarn, "Unknown (ensure you're running Wayland)",
|
||||||
|
fmt.Sprintf("XDG_SESSION_TYPE=%s", xdgSessionType),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkEnvironmentVars() []checkResult {
|
||||||
|
var results []checkResult
|
||||||
|
results = append(results, checkEnvVar("QT_QPA_PLATFORMTHEME")...)
|
||||||
|
results = append(results, checkEnvVar("QS_ICON_THEME")...)
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkEnvVar(name string) []checkResult {
|
||||||
|
value := os.Getenv(name)
|
||||||
|
if value != "" {
|
||||||
|
return []checkResult{{catEnvironment, name, statusInfo, value, ""}}
|
||||||
|
} else if doctorVerbose {
|
||||||
|
return []checkResult{{catEnvironment, name, statusInfo, "Not set", ""}}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readOSRelease() map[string]string {
|
||||||
|
result := make(map[string]string)
|
||||||
|
data, err := os.ReadFile("/etc/os-release")
|
||||||
|
if err != nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
for line := range strings.SplitSeq(string(data), "\n") {
|
||||||
|
if parts := strings.SplitN(line, "=", 2); len(parts) == 2 {
|
||||||
|
result[parts[0]] = strings.Trim(parts[1], "\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkVersions(qsMissingFeatures bool) []checkResult {
|
||||||
|
dmsCliPath, _ := os.Executable()
|
||||||
|
dmsCliDetails := ""
|
||||||
|
if doctorVerbose {
|
||||||
|
dmsCliDetails = dmsCliPath
|
||||||
|
}
|
||||||
|
|
||||||
|
results := []checkResult{
|
||||||
|
{catVersions, "DMS CLI", statusOK, formatVersion(Version), dmsCliDetails},
|
||||||
|
}
|
||||||
|
|
||||||
|
qsVersion, qsStatus, qsPath := getQuickshellVersionInfo(qsMissingFeatures)
|
||||||
|
qsDetails := ""
|
||||||
|
if doctorVerbose && qsPath != "" {
|
||||||
|
qsDetails = qsPath
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catVersions, "Quickshell", qsStatus, qsVersion, qsDetails})
|
||||||
|
|
||||||
|
dmsVersion, dmsPath := getDMSShellVersion()
|
||||||
|
if dmsVersion != "" {
|
||||||
|
results = append(results, checkResult{catVersions, "DMS Shell", statusOK, dmsVersion, dmsPath})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catVersions, "DMS Shell", statusError, "Not installed or not detected", "Run 'dms setup' to install"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDMSShellVersion() (version, path string) {
|
||||||
|
if err := findConfig(nil, nil); err == nil && configPath != "" {
|
||||||
|
versionFile := filepath.Join(configPath, "VERSION")
|
||||||
|
if data, err := os.ReadFile(versionFile); err == nil {
|
||||||
|
return strings.TrimSpace(string(data)), configPath
|
||||||
|
}
|
||||||
|
return "installed", configPath
|
||||||
|
}
|
||||||
|
|
||||||
|
if dmsPath, err := config.LocateDMSConfig(); err == nil {
|
||||||
|
versionFile := filepath.Join(dmsPath, "VERSION")
|
||||||
|
if data, err := os.ReadFile(versionFile); err == nil {
|
||||||
|
return strings.TrimSpace(string(data)), dmsPath
|
||||||
|
}
|
||||||
|
return "installed", dmsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getQuickshellVersionInfo(missingFeatures bool) (string, status, string) {
|
||||||
|
if !utils.CommandExists("qs") {
|
||||||
|
return "Not installed", statusError, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
qsPath, _ := exec.LookPath("qs")
|
||||||
|
|
||||||
|
output, err := exec.Command("qs", "--version").Output()
|
||||||
|
if err != nil {
|
||||||
|
return "Installed (version check failed)", statusWarn, qsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
fullVersion := strings.TrimSpace(string(output))
|
||||||
|
if matches := quickshellVersionRegex.FindStringSubmatch(fullVersion); len(matches) >= 2 {
|
||||||
|
if version.CompareVersions(matches[1], "0.2.0") < 0 {
|
||||||
|
return fmt.Sprintf("%s (needs >= 0.2.0)", fullVersion), statusError, qsPath
|
||||||
|
}
|
||||||
|
if missingFeatures {
|
||||||
|
return fullVersion, statusWarn, qsPath
|
||||||
|
}
|
||||||
|
return fullVersion, statusOK, qsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullVersion, statusWarn, qsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDMSInstallation() []checkResult {
|
||||||
|
var results []checkResult
|
||||||
|
|
||||||
|
dmsPath := ""
|
||||||
|
if err := findConfig(nil, nil); err == nil && configPath != "" {
|
||||||
|
dmsPath = configPath
|
||||||
|
} else if path, err := config.LocateDMSConfig(); err == nil {
|
||||||
|
dmsPath = path
|
||||||
|
}
|
||||||
|
|
||||||
|
if dmsPath == "" {
|
||||||
|
return []checkResult{{catInstallation, "DMS Configuration", statusError, "Not found", "shell.qml not found in any config path"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, checkResult{catInstallation, "DMS Configuration", statusOK, "Found", dmsPath})
|
||||||
|
|
||||||
|
shellQml := filepath.Join(dmsPath, "shell.qml")
|
||||||
|
if _, err := os.Stat(shellQml); err != nil {
|
||||||
|
results = append(results, checkResult{catInstallation, "shell.qml", statusError, "Missing", shellQml})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catInstallation, "shell.qml", statusOK, "Present", shellQml})
|
||||||
|
}
|
||||||
|
|
||||||
|
if doctorVerbose {
|
||||||
|
installType := "Unknown"
|
||||||
|
switch {
|
||||||
|
case strings.Contains(dmsPath, "/nix/store"):
|
||||||
|
installType = "Nix store"
|
||||||
|
case strings.Contains(dmsPath, ".local/share") || strings.Contains(dmsPath, "/usr/share"):
|
||||||
|
installType = "System package"
|
||||||
|
case strings.Contains(dmsPath, ".config"):
|
||||||
|
installType = "User config"
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catInstallation, "Install Type", statusInfo, installType, dmsPath})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWindowManagers() []checkResult {
|
||||||
|
compositors := []struct {
|
||||||
|
name, versionCmd, versionArg string
|
||||||
|
versionRegex *regexp.Regexp
|
||||||
|
commands []string
|
||||||
|
}{
|
||||||
|
{"Hyprland", "hyprctl", "version", hyprlandVersionRegex, []string{"hyprland", "Hyprland"}},
|
||||||
|
{"niri", "niri", "--version", niriVersionRegex, []string{"niri"}},
|
||||||
|
{"Sway", "sway", "--version", swayVersionRegex, []string{"sway"}},
|
||||||
|
{"River", "river", "-version", riverVersionRegex, []string{"river"}},
|
||||||
|
{"Wayfire", "wayfire", "--version", wayfireVersionRegex, []string{"wayfire"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []checkResult
|
||||||
|
foundAny := false
|
||||||
|
|
||||||
|
for _, c := range compositors {
|
||||||
|
if slices.ContainsFunc(c.commands, utils.CommandExists) {
|
||||||
|
foundAny = true
|
||||||
|
var compositorPath string
|
||||||
|
for _, cmd := range c.commands {
|
||||||
|
if path, err := exec.LookPath(cmd); err == nil {
|
||||||
|
compositorPath = path
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
details := ""
|
||||||
|
if doctorVerbose && compositorPath != "" {
|
||||||
|
details = compositorPath
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{
|
||||||
|
catCompositor, c.name, statusOK,
|
||||||
|
getVersionFromCommand(c.versionCmd, c.versionArg, c.versionRegex), details,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundAny {
|
||||||
|
results = append(results, checkResult{
|
||||||
|
catCompositor, "Compositor", statusError,
|
||||||
|
"No supported Wayland compositor found",
|
||||||
|
"Install Hyprland, niri, Sway, River, or Wayfire",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if wm := detectRunningWM(); wm != "" {
|
||||||
|
results = append(results, checkResult{catCompositor, "Active", statusInfo, wm, ""})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVersionFromCommand(cmd, arg string, regex *regexp.Regexp) string {
|
||||||
|
output, err := exec.Command(cmd, arg).Output()
|
||||||
|
if err != nil {
|
||||||
|
return "installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
outStr := string(output)
|
||||||
|
if matches := regex.FindStringSubmatch(outStr); len(matches) > 1 {
|
||||||
|
ver := matches[1]
|
||||||
|
if strings.Contains(outStr, "git") || strings.Contains(outStr, "dirty") {
|
||||||
|
return ver + " (git)"
|
||||||
|
}
|
||||||
|
return ver
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(outStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectRunningWM() string {
|
||||||
|
switch {
|
||||||
|
case os.Getenv("HYPRLAND_INSTANCE_SIGNATURE") != "":
|
||||||
|
return "Hyprland"
|
||||||
|
case os.Getenv("NIRI_SOCKET") != "":
|
||||||
|
return "niri"
|
||||||
|
case os.Getenv("XDG_CURRENT_DESKTOP") != "":
|
||||||
|
return os.Getenv("XDG_CURRENT_DESKTOP")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkQuickshellFeatures() ([]checkResult, bool) {
|
||||||
|
if !utils.CommandExists("qs") {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpDir := os.TempDir()
|
||||||
|
testScript := filepath.Join(tmpDir, "qs-feature-test.qml")
|
||||||
|
defer os.Remove(testScript)
|
||||||
|
|
||||||
|
qmlContent := `
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
ShellRoot {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool polkitAvailable: false
|
||||||
|
property bool idleMonitorAvailable: false
|
||||||
|
property bool idleInhibitorAvailable: false
|
||||||
|
property bool shortcutInhibitorAvailable: false
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 50
|
||||||
|
running: true
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
try {
|
||||||
|
var polkitTest = Qt.createQmlObject(
|
||||||
|
'import Quickshell.Services.Polkit; import QtQuick; Item {}',
|
||||||
|
root
|
||||||
|
)
|
||||||
|
root.polkitAvailable = true
|
||||||
|
polkitTest.destroy()
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var testItem = Qt.createQmlObject(
|
||||||
|
'import Quickshell.Wayland; import QtQuick; QtObject { ' +
|
||||||
|
'readonly property bool hasIdleMonitor: typeof IdleMonitor !== "undefined"; ' +
|
||||||
|
'readonly property bool hasIdleInhibitor: typeof IdleInhibitor !== "undefined"; ' +
|
||||||
|
'readonly property bool hasShortcutInhibitor: typeof ShortcutInhibitor !== "undefined" ' +
|
||||||
|
'}',
|
||||||
|
root
|
||||||
|
)
|
||||||
|
root.idleMonitorAvailable = testItem.hasIdleMonitor
|
||||||
|
root.idleInhibitorAvailable = testItem.hasIdleInhibitor
|
||||||
|
root.shortcutInhibitorAvailable = testItem.hasShortcutInhibitor
|
||||||
|
testItem.destroy()
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
console.warn(root.polkitAvailable ? "FEATURE:Polkit:OK" : "FEATURE:Polkit:UNAVAILABLE")
|
||||||
|
console.warn(root.idleMonitorAvailable ? "FEATURE:IdleMonitor:OK" : "FEATURE:IdleMonitor:UNAVAILABLE")
|
||||||
|
console.warn(root.idleInhibitorAvailable ? "FEATURE:IdleInhibitor:OK" : "FEATURE:IdleInhibitor:UNAVAILABLE")
|
||||||
|
console.warn(root.shortcutInhibitorAvailable ? "FEATURE:ShortcutInhibitor:OK" : "FEATURE:ShortcutInhibitor:UNAVAILABLE")
|
||||||
|
|
||||||
|
Quickshell.execDetached(["kill", "-TERM", String(Quickshell.processId)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
if err := os.WriteFile(testScript, []byte(qmlContent), 0644); err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("qs", "-p", testScript)
|
||||||
|
cmd.Env = append(os.Environ(), "NO_COLOR=1")
|
||||||
|
output, _ := cmd.CombinedOutput()
|
||||||
|
outputStr := string(output)
|
||||||
|
|
||||||
|
features := []struct{ name, desc string }{
|
||||||
|
{"Polkit", "Authentication prompts"},
|
||||||
|
{"IdleMonitor", "Idle detection"},
|
||||||
|
{"IdleInhibitor", "Prevent idle/sleep"},
|
||||||
|
{"ShortcutInhibitor", "Allow shortcut management (niri)"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []checkResult
|
||||||
|
missingFeatures := false
|
||||||
|
|
||||||
|
for _, f := range features {
|
||||||
|
available := strings.Contains(outputStr, fmt.Sprintf("FEATURE:%s:OK", f.name))
|
||||||
|
status, message := statusOK, "Available"
|
||||||
|
if !available {
|
||||||
|
status, message = statusInfo, "Not available"
|
||||||
|
missingFeatures = true
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catQuickshellFeatures, f.name, status, message, f.desc})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, missingFeatures
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkI2CAvailability() checkResult {
|
||||||
|
ddc, err := brightness.NewDDCBackend()
|
||||||
|
if err != nil {
|
||||||
|
return checkResult{catOptionalFeatures, "I2C/DDC", statusInfo, "Not available", "External monitor brightness control"}
|
||||||
|
}
|
||||||
|
defer ddc.Close()
|
||||||
|
|
||||||
|
devices, err := ddc.GetDevices()
|
||||||
|
if err != nil || len(devices) == 0 {
|
||||||
|
return checkResult{catOptionalFeatures, "I2C/DDC", statusInfo, "No monitors detected", "External monitor brightness control"}
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkResult{catOptionalFeatures, "I2C/DDC", statusOK, fmt.Sprintf("%d monitor(s) detected", len(devices)), "External monitor brightness control"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectNetworkBackend() string {
|
||||||
|
result, err := network.DetectNetworkStack()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result.Backend {
|
||||||
|
case network.BackendNetworkManager:
|
||||||
|
return "NetworkManager"
|
||||||
|
case network.BackendIwd:
|
||||||
|
return "iwd"
|
||||||
|
case network.BackendNetworkd:
|
||||||
|
if result.HasIwd {
|
||||||
|
return "iwd + systemd-networkd"
|
||||||
|
}
|
||||||
|
return "systemd-networkd"
|
||||||
|
case network.BackendConnMan:
|
||||||
|
return "ConnMan"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkOptionalDependencies() []checkResult {
|
||||||
|
var results []checkResult
|
||||||
|
|
||||||
|
if utils.IsServiceActive("accounts-daemon", false) {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "accountsservice", statusOK, "Running", "User accounts"})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "accountsservice", statusWarn, "Not running", "User accounts"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if utils.IsServiceActive("power-profiles-daemon", false) {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "power-profiles-daemon", statusOK, "Running", "Power profile management"})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "power-profiles-daemon", statusInfo, "Not running", "Power profile management"})
|
||||||
|
}
|
||||||
|
|
||||||
|
i2cStatus := checkI2CAvailability()
|
||||||
|
results = append(results, i2cStatus)
|
||||||
|
|
||||||
|
terminals := []string{"ghostty", "kitty", "alacritty", "foot", "wezterm"}
|
||||||
|
if idx := slices.IndexFunc(terminals, utils.CommandExists); idx >= 0 {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusOK, terminals[idx], ""})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusWarn, "None found", "Install ghostty, kitty, or alacritty"})
|
||||||
|
}
|
||||||
|
|
||||||
|
deps := []struct {
|
||||||
|
name, cmd, altCmd, desc string
|
||||||
|
important bool
|
||||||
|
}{
|
||||||
|
{"matugen", "matugen", "", "Dynamic theming", true},
|
||||||
|
{"dgop", "dgop", "", "System monitoring", true},
|
||||||
|
{"cava", "cava", "", "Audio waveform", false},
|
||||||
|
{"khal", "khal", "", "Calendar events", false},
|
||||||
|
{"Network", "nmcli", "iwctl", "Network management", false},
|
||||||
|
{"danksearch", "dsearch", "", "File search", false},
|
||||||
|
{"loginctl", "loginctl", "", "Session management", false},
|
||||||
|
{"fprintd", "fprintd-list", "", "Fingerprint auth", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range deps {
|
||||||
|
found, foundCmd := utils.CommandExists(d.cmd), d.cmd
|
||||||
|
if !found && d.altCmd != "" {
|
||||||
|
if utils.CommandExists(d.altCmd) {
|
||||||
|
found, foundCmd = true, d.altCmd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
message := "Installed"
|
||||||
|
details := d.desc
|
||||||
|
if d.name == "Network" {
|
||||||
|
result, err := network.DetectNetworkStack()
|
||||||
|
if err == nil && result.Backend != network.BackendNone {
|
||||||
|
message = detectNetworkBackend() + " (active)"
|
||||||
|
if doctorVerbose {
|
||||||
|
details = result.ChosenReason
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch foundCmd {
|
||||||
|
case "nmcli":
|
||||||
|
message = "NetworkManager (installed)"
|
||||||
|
case "iwctl":
|
||||||
|
message = "iwd (installed)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusOK, message, details})
|
||||||
|
} else if d.important {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusWarn, "Missing", d.desc})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusInfo, "Not installed", d.desc})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkConfigurationFiles() []checkResult {
|
||||||
|
configDir, _ := os.UserConfigDir()
|
||||||
|
cacheDir, _ := os.UserCacheDir()
|
||||||
|
dmsDir := "DankMaterialShell"
|
||||||
|
|
||||||
|
configFiles := []struct{ name, path string }{
|
||||||
|
{"settings.json", filepath.Join(configDir, dmsDir, "settings.json")},
|
||||||
|
{"clsettings.json", filepath.Join(configDir, dmsDir, "clsettings.json")},
|
||||||
|
{"plugin_settings.json", filepath.Join(configDir, dmsDir, "plugin_settings.json")},
|
||||||
|
{"session.json", filepath.Join(utils.XDGStateHome(), dmsDir, "session.json")},
|
||||||
|
{"dms-colors.json", filepath.Join(cacheDir, dmsDir, "dms-colors.json")},
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []checkResult
|
||||||
|
for _, cf := range configFiles {
|
||||||
|
info, err := os.Stat(cf.path)
|
||||||
|
if err == nil {
|
||||||
|
status := statusOK
|
||||||
|
message := "Present"
|
||||||
|
|
||||||
|
if info.Mode().Perm()&0200 == 0 {
|
||||||
|
status = statusWarn
|
||||||
|
message += " (read-only)"
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, checkResult{catConfigFiles, cf.name, status, message, cf.path})
|
||||||
|
} else {
|
||||||
|
results = append(results, checkResult{catConfigFiles, cf.name, statusInfo, "Not yet created", cf.path})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSystemdServices() []checkResult {
|
||||||
|
if !utils.CommandExists("systemctl") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []checkResult
|
||||||
|
|
||||||
|
dmsState := getServiceState("dms", true)
|
||||||
|
if !dmsState.exists {
|
||||||
|
results = append(results, checkResult{catServices, "dms.service", statusInfo, "Not installed", "Optional user service"})
|
||||||
|
} else {
|
||||||
|
status, message := statusOK, dmsState.enabled
|
||||||
|
if dmsState.active != "" {
|
||||||
|
message = fmt.Sprintf("%s, %s", dmsState.enabled, dmsState.active)
|
||||||
|
}
|
||||||
|
if dmsState.enabled == "disabled" {
|
||||||
|
status, message = statusWarn, "Disabled"
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catServices, "dms.service", status, message, ""})
|
||||||
|
}
|
||||||
|
|
||||||
|
greetdState := getServiceState("greetd", false)
|
||||||
|
if greetdState.exists {
|
||||||
|
status := statusOK
|
||||||
|
if greetdState.enabled == "disabled" {
|
||||||
|
status = statusInfo
|
||||||
|
}
|
||||||
|
results = append(results, checkResult{catServices, "greetd", status, greetdState.enabled, ""})
|
||||||
|
} else if doctorVerbose {
|
||||||
|
results = append(results, checkResult{catServices, "greetd", statusInfo, "Not installed", "Optional greeter service"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceState struct {
|
||||||
|
exists bool
|
||||||
|
enabled string
|
||||||
|
active string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServiceState(name string, userService bool) serviceState {
|
||||||
|
args := []string{"is-enabled", name}
|
||||||
|
if userService {
|
||||||
|
args = []string{"--user", "is-enabled", name}
|
||||||
|
}
|
||||||
|
|
||||||
|
output, _ := exec.Command("systemctl", args...).Output()
|
||||||
|
enabled := strings.TrimSpace(string(output))
|
||||||
|
|
||||||
|
if enabled == "" || enabled == "not-found" {
|
||||||
|
return serviceState{}
|
||||||
|
}
|
||||||
|
|
||||||
|
state := serviceState{exists: true, enabled: enabled}
|
||||||
|
|
||||||
|
if userService {
|
||||||
|
output, _ = exec.Command("systemctl", "--user", "is-active", name).Output()
|
||||||
|
if active := strings.TrimSpace(string(output)); active != "" && active != "unknown" {
|
||||||
|
state.active = active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
func printResults(results []checkResult) {
|
||||||
|
theme := tui.TerminalTheme()
|
||||||
|
styles := tui.NewStyles(theme)
|
||||||
|
|
||||||
|
currentCategory := category(-1)
|
||||||
|
for _, r := range results {
|
||||||
|
if r.category != currentCategory {
|
||||||
|
if currentCategory != -1 {
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
fmt.Printf(" %s\n", styles.Bold.Render(r.category.String()))
|
||||||
|
currentCategory = r.category
|
||||||
|
}
|
||||||
|
printResultLine(r, styles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printResultLine(r checkResult, styles tui.Styles) {
|
||||||
|
icon, style := r.status.IconStyle(styles)
|
||||||
|
|
||||||
|
name := r.name
|
||||||
|
nameLen := len(name)
|
||||||
|
|
||||||
|
if nameLen > checkNameMaxLength {
|
||||||
|
name = name[:checkNameMaxLength-1] + "…"
|
||||||
|
nameLen = checkNameMaxLength
|
||||||
|
}
|
||||||
|
dots := strings.Repeat("·", checkNameMaxLength-nameLen)
|
||||||
|
|
||||||
|
fmt.Printf(" %s %s %s %s\n", style.Render(icon), name, styles.Subtle.Render(dots), r.message)
|
||||||
|
|
||||||
|
if doctorVerbose && r.details != "" {
|
||||||
|
fmt.Printf(" %s\n", styles.Subtle.Render("└─ "+r.details))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printSummary(results []checkResult, qsMissingFeatures bool) {
|
||||||
|
theme := tui.TerminalTheme()
|
||||||
|
styles := tui.NewStyles(theme)
|
||||||
|
|
||||||
|
var ds DoctorStatus
|
||||||
|
for _, r := range results {
|
||||||
|
ds.Add(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf(" %s\n", styles.Subtle.Render("──────────────────────────────────────"))
|
||||||
|
|
||||||
|
if !ds.HasIssues() {
|
||||||
|
fmt.Printf(" %s\n", styles.Success.Render("✓ All checks passed!"))
|
||||||
|
} else {
|
||||||
|
var parts []string
|
||||||
|
|
||||||
|
if ds.ErrorCount() > 0 {
|
||||||
|
parts = append(parts, styles.Error.Render(fmt.Sprintf("%d error(s)", ds.ErrorCount())))
|
||||||
|
}
|
||||||
|
if ds.WarningCount() > 0 {
|
||||||
|
parts = append(parts, styles.Warning.Render(fmt.Sprintf("%d warning(s)", ds.WarningCount())))
|
||||||
|
}
|
||||||
|
parts = append(parts, styles.Success.Render(fmt.Sprintf("%d ok", ds.OKCount())))
|
||||||
|
fmt.Printf(" %s\n", strings.Join(parts, ", "))
|
||||||
|
|
||||||
|
if qsMissingFeatures {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf(" %s\n", styles.Subtle.Render("→ Consider using quickshell-git for full feature support"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
@@ -250,61 +250,61 @@ output_path = '%s'
|
|||||||
if !opts.ShouldSkipTemplate("gtk") {
|
if !opts.ShouldSkipTemplate("gtk") {
|
||||||
switch opts.Mode {
|
switch opts.Mode {
|
||||||
case "light":
|
case "light":
|
||||||
appendConfig(opts, cfgFile, nil, "gtk3-light.toml")
|
appendConfig(opts, cfgFile, nil, nil, "gtk3-light.toml")
|
||||||
default:
|
default:
|
||||||
appendConfig(opts, cfgFile, nil, "gtk3-dark.toml")
|
appendConfig(opts, cfgFile, nil, nil, "gtk3-dark.toml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ShouldSkipTemplate("niri") {
|
if !opts.ShouldSkipTemplate("niri") {
|
||||||
appendConfig(opts, cfgFile, []string{"niri"}, "niri.toml")
|
appendConfig(opts, cfgFile, []string{"niri"}, nil, "niri.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("qt5ct") {
|
if !opts.ShouldSkipTemplate("qt5ct") {
|
||||||
appendConfig(opts, cfgFile, []string{"qt5ct"}, "qt5ct.toml")
|
appendConfig(opts, cfgFile, []string{"qt5ct"}, nil, "qt5ct.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("qt6ct") {
|
if !opts.ShouldSkipTemplate("qt6ct") {
|
||||||
appendConfig(opts, cfgFile, []string{"qt6ct"}, "qt6ct.toml")
|
appendConfig(opts, cfgFile, []string{"qt6ct"}, nil, "qt6ct.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("firefox") {
|
if !opts.ShouldSkipTemplate("firefox") {
|
||||||
appendConfig(opts, cfgFile, []string{"firefox"}, "firefox.toml")
|
appendConfig(opts, cfgFile, []string{"firefox"}, nil, "firefox.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("pywalfox") {
|
if !opts.ShouldSkipTemplate("pywalfox") {
|
||||||
appendConfig(opts, cfgFile, []string{"pywalfox"}, "pywalfox.toml")
|
appendConfig(opts, cfgFile, []string{"pywalfox"}, nil, "pywalfox.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("zenbrowser") {
|
if !opts.ShouldSkipTemplate("zenbrowser") {
|
||||||
appendConfig(opts, cfgFile, []string{"zen", "zen-browser"}, "zenbrowser.toml")
|
appendConfig(opts, cfgFile, []string{"zen", "zen-browser"}, []string{"app.zen_browser.zen"}, "zenbrowser.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("vesktop") {
|
if !opts.ShouldSkipTemplate("vesktop") {
|
||||||
appendConfig(opts, cfgFile, []string{"vesktop"}, "vesktop.toml")
|
appendConfig(opts, cfgFile, []string{"vesktop"}, []string{"dev.vencord.Vesktop"}, "vesktop.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("equibop") {
|
if !opts.ShouldSkipTemplate("equibop") {
|
||||||
appendConfig(opts, cfgFile, []string{"equibop"}, "equibop.toml")
|
appendConfig(opts, cfgFile, []string{"equibop"}, nil, "equibop.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("ghostty") {
|
if !opts.ShouldSkipTemplate("ghostty") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"ghostty"}, "ghostty.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"ghostty"}, nil, "ghostty.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("kitty") {
|
if !opts.ShouldSkipTemplate("kitty") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"kitty"}, "kitty.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"kitty"}, nil, "kitty.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("foot") {
|
if !opts.ShouldSkipTemplate("foot") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"foot"}, "foot.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"foot"}, nil, "foot.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("alacritty") {
|
if !opts.ShouldSkipTemplate("alacritty") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"alacritty"}, "alacritty.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"alacritty"}, nil, "alacritty.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("wezterm") {
|
if !opts.ShouldSkipTemplate("wezterm") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"wezterm"}, "wezterm.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"wezterm"}, nil, "wezterm.toml")
|
||||||
}
|
}
|
||||||
if !opts.ShouldSkipTemplate("nvim") {
|
if !opts.ShouldSkipTemplate("nvim") {
|
||||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"nvim"}, "neovim.toml")
|
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"nvim"}, nil, "neovim.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ShouldSkipTemplate("dgop") {
|
if !opts.ShouldSkipTemplate("dgop") {
|
||||||
appendConfig(opts, cfgFile, []string{"dgop"}, "dgop.toml")
|
appendConfig(opts, cfgFile, []string{"dgop"}, nil, "dgop.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ShouldSkipTemplate("kcolorscheme") {
|
if !opts.ShouldSkipTemplate("kcolorscheme") {
|
||||||
appendConfig(opts, cfgFile, nil, "kcolorscheme.toml")
|
appendConfig(opts, cfgFile, nil, nil, "kcolorscheme.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ShouldSkipTemplate("vscode") {
|
if !opts.ShouldSkipTemplate("vscode") {
|
||||||
@@ -342,12 +342,21 @@ output_path = '%s'
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendConfig(opts *Options, cfgFile *os.File, checkCmd []string, fileName string) {
|
func appendConfig(
|
||||||
|
opts *Options,
|
||||||
|
cfgFile *os.File,
|
||||||
|
checkCmd []string,
|
||||||
|
checkFlatpaks []string,
|
||||||
|
fileName string,
|
||||||
|
) {
|
||||||
configPath := filepath.Join(opts.ShellDir, "matugen", "configs", fileName)
|
configPath := filepath.Join(opts.ShellDir, "matugen", "configs", fileName)
|
||||||
if _, err := os.Stat(configPath); err != nil {
|
if _, err := os.Stat(configPath); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(checkCmd) > 0 && !utils.AnyCommandExists(checkCmd...) {
|
cmdExists := checkCmd == nil || utils.AnyCommandExists(checkCmd...)
|
||||||
|
flatpakExists := checkFlatpaks == nil || utils.AnyFlatpakExists(checkFlatpaks...)
|
||||||
|
|
||||||
|
if !cmdExists && !flatpakExists {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err := os.ReadFile(configPath)
|
data, err := os.ReadFile(configPath)
|
||||||
@@ -358,12 +367,15 @@ func appendConfig(opts *Options, cfgFile *os.File, checkCmd []string, fileName s
|
|||||||
cfgFile.WriteString("\n")
|
cfgFile.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkCmd []string, fileName string) {
|
func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkCmd []string, checkFlatpaks []string, fileName string) {
|
||||||
configPath := filepath.Join(opts.ShellDir, "matugen", "configs", fileName)
|
configPath := filepath.Join(opts.ShellDir, "matugen", "configs", fileName)
|
||||||
if _, err := os.Stat(configPath); err != nil {
|
if _, err := os.Stat(configPath); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(checkCmd) > 0 && !utils.AnyCommandExists(checkCmd...) {
|
cmdExists := checkCmd == nil || utils.AnyCommandExists(checkCmd...)
|
||||||
|
flatpakExists := checkFlatpaks == nil || utils.AnyFlatpakExists(checkFlatpaks...)
|
||||||
|
|
||||||
|
if !cmdExists && !flatpakExists {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err := os.ReadFile(configPath)
|
data, err := os.ReadFile(configPath)
|
||||||
|
|||||||
300
core/internal/matugen/matugen_test.go
Normal file
300
core/internal/matugen/matugen_test.go
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
package matugen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAppendConfigBinaryExists(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "test config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, []string{"sh"}, nil, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) == 0 {
|
||||||
|
t.Errorf("expected config to be written when binary exists")
|
||||||
|
}
|
||||||
|
if string(output) != testConfig+"\n" {
|
||||||
|
t.Errorf("expected %q, got %q", testConfig+"\n", string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigBinaryDoesNotExist(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "test config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, []string{"nonexistent-binary-12345"}, []string{}, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) != 0 {
|
||||||
|
t.Errorf("expected no config when binary doesn't exist, got: %q", string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigFlatpakExists(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "zen config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, nil, []string{"app.zen_browser.zen"}, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) == 0 {
|
||||||
|
t.Errorf("expected config to be written when flatpak exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigFlatpakDoesNotExist(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "test config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, []string{}, []string{"com.nonexistent.flatpak"}, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) != 0 {
|
||||||
|
t.Errorf("expected no config when flatpak doesn't exist, got: %q", string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigBothExist(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "zen config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, []string{"sh"}, []string{"app.zen_browser.zen"}, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) == 0 {
|
||||||
|
t.Errorf("expected config to be written when both binary and flatpak exist")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigNeitherExists(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "test config content"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, []string{"nonexistent-binary-12345"}, []string{"com.nonexistent.flatpak"}, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) != 0 {
|
||||||
|
t.Errorf("expected no config when neither exists, got: %q", string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigNoChecks(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig := "always include"
|
||||||
|
configPath := filepath.Join(configsDir, "test.toml")
|
||||||
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, nil, nil, "test.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) == 0 {
|
||||||
|
t.Errorf("expected config to be written when no checks specified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendConfigFileDoesNotExist(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
shellDir := filepath.Join(tempDir, "shell")
|
||||||
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
||||||
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
||||||
|
t.Fatalf("failed to create configs dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile := filepath.Join(tempDir, "output.toml")
|
||||||
|
cfgFile, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create output file: %v", err)
|
||||||
|
}
|
||||||
|
defer cfgFile.Close()
|
||||||
|
|
||||||
|
opts := &Options{ShellDir: shellDir}
|
||||||
|
|
||||||
|
appendConfig(opts, cfgFile, nil, nil, "nonexistent.toml")
|
||||||
|
|
||||||
|
cfgFile.Close()
|
||||||
|
output, err := os.ReadFile(outFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read output: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(output) != 0 {
|
||||||
|
t.Errorf("expected no config when file doesn't exist, got: %q", string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "os/exec"
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func CommandExists(cmd string) bool {
|
func CommandExists(cmd string) bool {
|
||||||
_, err := exec.LookPath(cmd)
|
_, err := exec.LookPath(cmd)
|
||||||
@@ -15,3 +18,16 @@ func AnyCommandExists(cmds ...string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsServiceActive(name string, userService bool) bool {
|
||||||
|
if !CommandExists("systemctl") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{"is-active", name}
|
||||||
|
if userService {
|
||||||
|
args = []string{"--user", "is-active", name}
|
||||||
|
}
|
||||||
|
output, _ := exec.Command("systemctl", args...).Output()
|
||||||
|
return strings.EqualFold(strings.TrimSpace(string(output)), "active")
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,6 +57,10 @@ func FlatpakSearchBySubstring(substring string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AnyFlatpakExists(flatpaks ...string) bool {
|
||||||
|
return slices.ContainsFunc(flatpaks, FlatpakExists)
|
||||||
|
}
|
||||||
|
|
||||||
func FlatpakInstallationDir(name string) (string, error) {
|
func FlatpakInstallationDir(name string) (string, error) {
|
||||||
if !FlatpakInPath() {
|
if !FlatpakInPath() {
|
||||||
return "", errors.New("flatpak not found in PATH")
|
return "", errors.New("flatpak not found in PATH")
|
||||||
|
|||||||
@@ -208,3 +208,42 @@ func TestFlatpakInstallationDirCommandFailure(t *testing.T) {
|
|||||||
t.Errorf("expected 'not installed' error, got: %v", err)
|
t.Errorf("expected 'not installed' error, got: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAnyFlatpakExistsSomeExist(t *testing.T) {
|
||||||
|
if !FlatpakInPath() {
|
||||||
|
t.Skip("flatpak not in PATH")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := AnyFlatpakExists("com.nonexistent.flatpak", "app.zen_browser.zen", "com.another.nonexistent")
|
||||||
|
if !result {
|
||||||
|
t.Errorf("expected true when at least one flatpak exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyFlatpakExistsNoneExist(t *testing.T) {
|
||||||
|
if !FlatpakInPath() {
|
||||||
|
t.Skip("flatpak not in PATH")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := AnyFlatpakExists("com.nonexistent.flatpak1", "com.nonexistent.flatpak2")
|
||||||
|
if result {
|
||||||
|
t.Errorf("expected false when no flatpaks exist")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyFlatpakExistsNoFlatpak(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
t.Setenv("PATH", tempDir)
|
||||||
|
|
||||||
|
result := AnyFlatpakExists("any.package.name", "another.package")
|
||||||
|
if result {
|
||||||
|
t.Errorf("expected false when flatpak not in PATH, got true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyFlatpakExistsEmpty(t *testing.T) {
|
||||||
|
result := AnyFlatpakExists()
|
||||||
|
if result {
|
||||||
|
t.Errorf("expected false when no flatpaks specified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func XDGStateHome() string {
|
||||||
|
if dir := os.Getenv("XDG_STATE_HOME"); dir != "" {
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
home, _ := os.UserHomeDir()
|
||||||
|
return filepath.Join(append([]string{home}, ".local", "state")...)
|
||||||
|
}
|
||||||
|
|
||||||
func ExpandPath(path string) (string, error) {
|
func ExpandPath(path string) (string, error) {
|
||||||
expanded := os.ExpandEnv(path)
|
expanded := os.ExpandEnv(path)
|
||||||
expanded = filepath.Clean(expanded)
|
expanded = filepath.Clean(expanded)
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ Singleton {
|
|||||||
property bool loginctlLockIntegration: true
|
property bool loginctlLockIntegration: true
|
||||||
property bool fadeToLockEnabled: false
|
property bool fadeToLockEnabled: false
|
||||||
property int fadeToLockGracePeriod: 5
|
property int fadeToLockGracePeriod: 5
|
||||||
|
property bool fadeToDpmsEnabled: false
|
||||||
|
property int fadeToDpmsGracePeriod: 5
|
||||||
property string launchPrefix: ""
|
property string launchPrefix: ""
|
||||||
property var brightnessDevicePins: ({})
|
property var brightnessDevicePins: ({})
|
||||||
property var wifiNetworkPins: ({})
|
property var wifiNetworkPins: ({})
|
||||||
@@ -351,6 +353,12 @@ Singleton {
|
|||||||
property int notificationTimeoutNormal: 5000
|
property int notificationTimeoutNormal: 5000
|
||||||
property int notificationTimeoutCritical: 0
|
property int notificationTimeoutCritical: 0
|
||||||
property int notificationPopupPosition: SettingsData.Position.Top
|
property int notificationPopupPosition: SettingsData.Position.Top
|
||||||
|
property bool notificationHistoryEnabled: true
|
||||||
|
property int notificationHistoryMaxCount: 50
|
||||||
|
property int notificationHistoryMaxAgeDays: 7
|
||||||
|
property bool notificationHistorySaveLow: true
|
||||||
|
property bool notificationHistorySaveNormal: true
|
||||||
|
property bool notificationHistorySaveCritical: true
|
||||||
|
|
||||||
property bool osdAlwaysShowValue: false
|
property bool osdAlwaysShowValue: false
|
||||||
property int osdPosition: SettingsData.Position.BottomCenter
|
property int osdPosition: SettingsData.Position.BottomCenter
|
||||||
|
|||||||
@@ -168,6 +168,8 @@ var SPEC = {
|
|||||||
loginctlLockIntegration: { def: true },
|
loginctlLockIntegration: { def: true },
|
||||||
fadeToLockEnabled: { def: false },
|
fadeToLockEnabled: { def: false },
|
||||||
fadeToLockGracePeriod: { def: 5 },
|
fadeToLockGracePeriod: { def: 5 },
|
||||||
|
fadeToDpmsEnabled: { def: false },
|
||||||
|
fadeToDpmsGracePeriod: { def: 5 },
|
||||||
launchPrefix: { def: "" },
|
launchPrefix: { def: "" },
|
||||||
brightnessDevicePins: { def: {} },
|
brightnessDevicePins: { def: {} },
|
||||||
wifiNetworkPins: { def: {} },
|
wifiNetworkPins: { def: {} },
|
||||||
@@ -240,6 +242,12 @@ var SPEC = {
|
|||||||
notificationTimeoutNormal: { def: 5000 },
|
notificationTimeoutNormal: { def: 5000 },
|
||||||
notificationTimeoutCritical: { def: 0 },
|
notificationTimeoutCritical: { def: 0 },
|
||||||
notificationPopupPosition: { def: 0 },
|
notificationPopupPosition: { def: 0 },
|
||||||
|
notificationHistoryEnabled: { def: true },
|
||||||
|
notificationHistoryMaxCount: { def: 50 },
|
||||||
|
notificationHistoryMaxAgeDays: { def: 7 },
|
||||||
|
notificationHistorySaveLow: { def: true },
|
||||||
|
notificationHistorySaveNormal: { def: true },
|
||||||
|
notificationHistorySaveCritical: { def: true },
|
||||||
|
|
||||||
osdAlwaysShowValue: { def: false },
|
osdAlwaysShowValue: { def: false },
|
||||||
osdPosition: { def: 5 },
|
osdPosition: { def: 5 },
|
||||||
|
|||||||
@@ -104,6 +104,46 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
delegate: Loader {
|
||||||
|
id: fadeDpmsWindowLoader
|
||||||
|
required property var modelData
|
||||||
|
active: SettingsData.fadeToDpmsEnabled
|
||||||
|
asynchronous: false
|
||||||
|
|
||||||
|
sourceComponent: FadeToDpmsWindow {
|
||||||
|
screen: fadeDpmsWindowLoader.modelData
|
||||||
|
|
||||||
|
onFadeCompleted: {
|
||||||
|
IdleService.requestMonitorOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
onFadeCancelled: {
|
||||||
|
console.log("Fade to DPMS cancelled by user on screen:", fadeDpmsWindowLoader.modelData.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: IdleService
|
||||||
|
enabled: fadeDpmsWindowLoader.item !== null
|
||||||
|
|
||||||
|
function onFadeToDpmsRequested() {
|
||||||
|
if (fadeDpmsWindowLoader.item) {
|
||||||
|
fadeDpmsWindowLoader.item.startFade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancelFadeToDpms() {
|
||||||
|
if (fadeDpmsWindowLoader.item) {
|
||||||
|
fadeDpmsWindowLoader.item.cancelFade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: dankBarRepeater
|
id: dankBarRepeater
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ DankModal {
|
|||||||
|
|
||||||
property bool notificationModalOpen: false
|
property bool notificationModalOpen: false
|
||||||
property var notificationListRef: null
|
property var notificationListRef: null
|
||||||
|
property var historyListRef: null
|
||||||
|
property int currentTab: 0
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
notificationModalOpen = true;
|
notificationModalOpen = true;
|
||||||
@@ -61,7 +63,7 @@ DankModal {
|
|||||||
NotificationService.clearAllNotifications();
|
NotificationService.clearAllNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
function dismissAllPopups () {
|
function dismissAllPopups() {
|
||||||
NotificationService.dismissAllPopups();
|
NotificationService.dismissAllPopups();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +82,18 @@ DankModal {
|
|||||||
NotificationService.onOverlayClose();
|
NotificationService.onOverlayClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modalFocusScope.Keys.onPressed: event => modalKeyboardController.handleKey(event)
|
modalFocusScope.Keys.onPressed: event => {
|
||||||
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
hide();
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentTab === 1 && historyListRef) {
|
||||||
|
historyListRef.handleKey(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalKeyboardController.handleKey(event);
|
||||||
|
}
|
||||||
|
|
||||||
NotificationKeyboardController {
|
NotificationKeyboardController {
|
||||||
id: modalKeyboardController
|
id: modalKeyboardController
|
||||||
@@ -145,21 +158,20 @@ DankModal {
|
|||||||
|
|
||||||
NotificationHeader {
|
NotificationHeader {
|
||||||
id: notificationHeader
|
id: notificationHeader
|
||||||
|
|
||||||
keyboardController: modalKeyboardController
|
keyboardController: modalKeyboardController
|
||||||
|
onCurrentTabChanged: notificationModal.currentTab = currentTab
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationSettings {
|
NotificationSettings {
|
||||||
id: notificationSettings
|
id: notificationSettings
|
||||||
|
|
||||||
expanded: notificationHeader.showSettings
|
expanded: notificationHeader.showSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardNavigatedNotificationList {
|
KeyboardNavigatedNotificationList {
|
||||||
id: notificationList
|
id: notificationList
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - y
|
height: parent.height - y
|
||||||
|
visible: notificationHeader.currentTab === 0
|
||||||
keyboardController: modalKeyboardController
|
keyboardController: modalKeyboardController
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
notificationModal.notificationListRef = notificationList;
|
notificationModal.notificationListRef = notificationList;
|
||||||
@@ -169,6 +181,14 @@ DankModal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HistoryNotificationList {
|
||||||
|
id: historyList
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - y
|
||||||
|
visible: notificationHeader.currentTab === 1
|
||||||
|
Component.onCompleted: notificationModal.historyListRef = historyList
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationKeyboardHints {
|
NotificationKeyboardHints {
|
||||||
@@ -178,7 +198,7 @@ DankModal {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
showHints: modalKeyboardController.showKeyboardHints
|
showHints: notificationHeader.currentTab === 0 ? modalKeyboardController.showKeyboardHints : historyList.showKeyboardHints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Item {
|
|||||||
if (!toplevel.screens)
|
if (!toplevel.screens)
|
||||||
return false;
|
return false;
|
||||||
for (let i = 0; i < toplevel.screens.length; i++) {
|
for (let i = 0; i < toplevel.screens.length; i++) {
|
||||||
if (toplevel.screens[i].name === screenName)
|
if (toplevel.screens[i]?.name === screenName)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
102
quickshell/Modules/Lock/FadeToDpmsWindow.qml
Normal file
102
quickshell/Modules/Lock/FadeToDpmsWindow.qml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool active: false
|
||||||
|
|
||||||
|
signal fadeCompleted
|
||||||
|
signal fadeCancelled
|
||||||
|
|
||||||
|
visible: active
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
WlrLayershell.namespace: "dms:fade-to-dpms"
|
||||||
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
|
WlrLayershell.exclusiveZone: -1
|
||||||
|
WlrLayershell.keyboardFocus: active ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: fadeOverlay
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
onOpacityChanged: {
|
||||||
|
if (opacity >= 0.99 && root.active) {
|
||||||
|
root.fadeCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: fadeSeq
|
||||||
|
running: false
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: fadeOverlay
|
||||||
|
property: "opacity"
|
||||||
|
from: 0.0
|
||||||
|
to: 1.0
|
||||||
|
duration: SettingsData.fadeToDpmsGracePeriod * 1000
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startFade() {
|
||||||
|
if (!SettingsData.fadeToDpmsEnabled)
|
||||||
|
return;
|
||||||
|
active = true;
|
||||||
|
fadeOverlay.opacity = 0.0;
|
||||||
|
fadeSeq.stop();
|
||||||
|
fadeSeq.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelFade() {
|
||||||
|
fadeSeq.stop();
|
||||||
|
fadeOverlay.opacity = 0.0;
|
||||||
|
active = false;
|
||||||
|
fadeCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.active
|
||||||
|
onClicked: root.cancelFade()
|
||||||
|
onPressed: root.cancelFade()
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: root.active
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
root.cancelFade();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (active) {
|
||||||
|
forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (active) {
|
||||||
|
forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,15 +23,12 @@ Scope {
|
|||||||
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock]);
|
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
shouldLock = true;
|
||||||
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
||||||
DMSService.lockSession(response => {
|
DMSService.lockSession(response => {
|
||||||
if (response.error) {
|
if (response.error)
|
||||||
console.warn("Lock: Failed to call loginctl.lock:", response.error);
|
console.warn("Lock: loginctl.lock failed:", response.error);
|
||||||
shouldLock = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
shouldLock = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +78,11 @@ Scope {
|
|||||||
|
|
||||||
locked: shouldLock
|
locked: shouldLock
|
||||||
|
|
||||||
|
onLockedChanged: {
|
||||||
|
if (locked)
|
||||||
|
dpmsReapplyTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
WlSessionLockSurface {
|
WlSessionLockSurface {
|
||||||
id: lockSurface
|
id: lockSurface
|
||||||
|
|
||||||
@@ -120,15 +122,12 @@ Scope {
|
|||||||
target: "lock"
|
target: "lock"
|
||||||
|
|
||||||
function lock() {
|
function lock() {
|
||||||
if (!root.processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
root.shouldLock = true;
|
||||||
|
if (SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
||||||
DMSService.lockSession(response => {
|
DMSService.lockSession(response => {
|
||||||
if (response.error) {
|
if (response.error)
|
||||||
console.warn("Lock: Failed to call loginctl.lock:", response.error);
|
console.warn("Lock: loginctl.lock failed:", response.error);
|
||||||
root.shouldLock = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
root.shouldLock = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,4 +139,11 @@ Scope {
|
|||||||
return sessionLock.locked;
|
return sessionLock.locked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: dpmsReapplyTimer
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: IdleService.reapplyDpmsIfNeeded()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var historyItem
|
||||||
|
property bool isSelected: false
|
||||||
|
property bool keyboardNavigationActive: false
|
||||||
|
|
||||||
|
width: parent ? parent.width : 400
|
||||||
|
height: 116
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
color: {
|
||||||
|
if (isSelected && keyboardNavigationActive)
|
||||||
|
return Theme.primaryPressed;
|
||||||
|
return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
|
||||||
|
}
|
||||||
|
border.color: {
|
||||||
|
if (isSelected && keyboardNavigationActive)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.5);
|
||||||
|
if (historyItem.urgency === 2)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
|
||||||
|
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05);
|
||||||
|
}
|
||||||
|
border.width: {
|
||||||
|
if (isSelected && keyboardNavigationActive)
|
||||||
|
return 1.5;
|
||||||
|
if (historyItem.urgency === 2)
|
||||||
|
return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
visible: historyItem.urgency === 2
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Horizontal
|
||||||
|
GradientStop {
|
||||||
|
position: 0.0
|
||||||
|
color: Theme.primary
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 0.02
|
||||||
|
color: Theme.primary
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 0.021
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 12
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.rightMargin: 56
|
||||||
|
height: 92
|
||||||
|
|
||||||
|
DankCircularImage {
|
||||||
|
id: iconContainer
|
||||||
|
readonly property bool hasNotificationImage: historyItem.image && historyItem.image !== ""
|
||||||
|
|
||||||
|
width: 63
|
||||||
|
height: 63
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 14
|
||||||
|
|
||||||
|
imageSource: {
|
||||||
|
if (hasNotificationImage)
|
||||||
|
return historyItem.image;
|
||||||
|
if (historyItem.appIcon) {
|
||||||
|
const appIcon = historyItem.appIcon;
|
||||||
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
||||||
|
return appIcon;
|
||||||
|
return Quickshell.iconPath(appIcon, true);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
hasImage: hasNotificationImage
|
||||||
|
fallbackIcon: ""
|
||||||
|
fallbackText: {
|
||||||
|
const appName = historyItem.appName || "?";
|
||||||
|
return appName.charAt(0).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: -2
|
||||||
|
radius: width / 2
|
||||||
|
color: "transparent"
|
||||||
|
border.color: root.color
|
||||||
|
border.width: 5
|
||||||
|
visible: parent.hasImage
|
||||||
|
antialiasing: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: iconContainer.right
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 8
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: -2
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
width: parent.width
|
||||||
|
text: {
|
||||||
|
const timeStr = NotificationService.formatHistoryTime(historyItem.timestamp);
|
||||||
|
const appName = historyItem.appName || "";
|
||||||
|
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||||
|
}
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Medium
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: historyItem.summary || ""
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
visible: text.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: descriptionText
|
||||||
|
text: historyItem.htmlBody || historyItem.body || ""
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
visible: text.length > 0
|
||||||
|
linkColor: Theme.primary
|
||||||
|
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 12
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: 18
|
||||||
|
buttonSize: 28
|
||||||
|
onClicked: NotificationService.removeFromHistory(historyItem.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string selectedFilterKey: "all"
|
||||||
|
property var keyboardController: null
|
||||||
|
property bool keyboardActive: false
|
||||||
|
property int selectedIndex: -1
|
||||||
|
property bool showKeyboardHints: false
|
||||||
|
|
||||||
|
function getStartOfDay(date) {
|
||||||
|
const d = new Date(date);
|
||||||
|
d.setHours(0, 0, 0, 0);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilterRange(key) {
|
||||||
|
const now = new Date();
|
||||||
|
const startOfToday = getStartOfDay(now);
|
||||||
|
const startOfYesterday = new Date(startOfToday.getTime() - 86400000);
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case "all":
|
||||||
|
return {
|
||||||
|
start: null,
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
case "1h":
|
||||||
|
return {
|
||||||
|
start: new Date(now.getTime() - 3600000),
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
case "today":
|
||||||
|
return {
|
||||||
|
start: startOfToday,
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
case "yesterday":
|
||||||
|
return {
|
||||||
|
start: startOfYesterday,
|
||||||
|
end: startOfToday
|
||||||
|
};
|
||||||
|
case "older":
|
||||||
|
return {
|
||||||
|
start: null,
|
||||||
|
end: getOlderCutoff()
|
||||||
|
};
|
||||||
|
case "7d":
|
||||||
|
return {
|
||||||
|
start: new Date(now.getTime() - 7 * 86400000),
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
case "30d":
|
||||||
|
return {
|
||||||
|
start: new Date(now.getTime() - 30 * 86400000),
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
start: null,
|
||||||
|
end: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function countForFilter(key) {
|
||||||
|
const range = getFilterRange(key);
|
||||||
|
if (!range.start && !range.end)
|
||||||
|
return NotificationService.historyList.length;
|
||||||
|
return NotificationService.historyList.filter(n => {
|
||||||
|
const ts = n.timestamp;
|
||||||
|
if (range.start && ts < range.start.getTime())
|
||||||
|
return false;
|
||||||
|
if (range.end && ts >= range.end.getTime())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var allFilters: [
|
||||||
|
{ label: I18n.tr("All", "notification history filter"), key: "all", maxDays: 0 },
|
||||||
|
{ label: I18n.tr("Last hour", "notification history filter"), key: "1h", maxDays: 1 },
|
||||||
|
{ label: I18n.tr("Today", "notification history filter"), key: "today", maxDays: 1 },
|
||||||
|
{ label: I18n.tr("Yesterday", "notification history filter"), key: "yesterday", maxDays: 2 },
|
||||||
|
{ label: I18n.tr("7 days", "notification history filter"), key: "7d", maxDays: 7 },
|
||||||
|
{ label: I18n.tr("30 days", "notification history filter"), key: "30d", maxDays: 30 },
|
||||||
|
{ label: I18n.tr("Older", "notification history filter for content older than other filters"), key: "older", maxDays: 0 }
|
||||||
|
]
|
||||||
|
|
||||||
|
function filterRelevantForRetention(filter) {
|
||||||
|
const retention = SettingsData.notificationHistoryMaxAgeDays;
|
||||||
|
if (filter.key === "older") {
|
||||||
|
if (retention === 0) return true;
|
||||||
|
return retention > 2 && retention < 7 || retention > 30;
|
||||||
|
}
|
||||||
|
if (retention === 0) return true;
|
||||||
|
if (filter.maxDays === 0) return true;
|
||||||
|
return filter.maxDays <= retention;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOlderCutoff() {
|
||||||
|
const retention = SettingsData.notificationHistoryMaxAgeDays;
|
||||||
|
const now = new Date();
|
||||||
|
if (retention === 0 || retention > 30)
|
||||||
|
return new Date(now.getTime() - 30 * 86400000);
|
||||||
|
if (retention >= 7)
|
||||||
|
return new Date(now.getTime() - 7 * 86400000);
|
||||||
|
const startOfToday = getStartOfDay(now);
|
||||||
|
return new Date(startOfToday.getTime() - 86400000);
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var visibleFilters: {
|
||||||
|
const result = [];
|
||||||
|
const retention = SettingsData.notificationHistoryMaxAgeDays;
|
||||||
|
for (let i = 0; i < allFilters.length; i++) {
|
||||||
|
const f = allFilters[i];
|
||||||
|
if (!filterRelevantForRetention(f)) continue;
|
||||||
|
const count = countForFilter(f.key);
|
||||||
|
if (f.key === "all" || count > 0) {
|
||||||
|
result.push({ label: f.label, key: f.key, count: count });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleFiltersChanged: {
|
||||||
|
let found = false;
|
||||||
|
for (let i = 0; i < visibleFilters.length; i++) {
|
||||||
|
if (visibleFilters[i].key === selectedFilterKey) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
selectedFilterKey = "all";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilteredHistory() {
|
||||||
|
const range = getFilterRange(selectedFilterKey);
|
||||||
|
if (!range.start && !range.end)
|
||||||
|
return NotificationService.historyList;
|
||||||
|
return NotificationService.historyList.filter(n => {
|
||||||
|
const ts = n.timestamp;
|
||||||
|
if (range.start && ts < range.start.getTime())
|
||||||
|
return false;
|
||||||
|
if (range.end && ts >= range.end.getTime())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChipIndex() {
|
||||||
|
for (let i = 0; i < visibleFilters.length; i++) {
|
||||||
|
if (visibleFilters[i].key === selectedFilterKey)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableAutoScroll() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankFilterChips {
|
||||||
|
id: filterChips
|
||||||
|
width: parent.width
|
||||||
|
currentIndex: root.getChipIndex()
|
||||||
|
showCounts: true
|
||||||
|
model: root.visibleFilters
|
||||||
|
onSelectionChanged: index => {
|
||||||
|
if (index >= 0 && index < root.visibleFilters.length) {
|
||||||
|
root.selectedFilterKey = root.visibleFilters[index].key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankListView {
|
||||||
|
id: historyListView
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - filterChips.height - Theme.spacingS
|
||||||
|
clip: true
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
model: ScriptModel {
|
||||||
|
id: historyModel
|
||||||
|
values: root.getFilteredHistory()
|
||||||
|
objectProp: "id"
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationEmptyState {
|
||||||
|
visible: historyListView.count === 0
|
||||||
|
y: Theme.spacingL
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: HistoryNotificationCard {
|
||||||
|
required property var modelData
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
historyItem: modelData
|
||||||
|
isSelected: root.keyboardActive && root.selectedIndex === index
|
||||||
|
keyboardNavigationActive: root.keyboardActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectNext() {
|
||||||
|
if (historyModel.values.length === 0)
|
||||||
|
return;
|
||||||
|
keyboardActive = true;
|
||||||
|
selectedIndex = Math.min(selectedIndex + 1, historyModel.values.length - 1);
|
||||||
|
historyListView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectPrevious() {
|
||||||
|
if (historyModel.values.length === 0)
|
||||||
|
return;
|
||||||
|
if (selectedIndex <= 0) {
|
||||||
|
keyboardActive = false;
|
||||||
|
selectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedIndex = Math.max(selectedIndex - 1, 0);
|
||||||
|
historyListView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSelected() {
|
||||||
|
if (selectedIndex < 0 || selectedIndex >= historyModel.values.length)
|
||||||
|
return;
|
||||||
|
const item = historyModel.values[selectedIndex];
|
||||||
|
NotificationService.removeFromHistory(item.id);
|
||||||
|
if (historyModel.values.length === 0) {
|
||||||
|
keyboardActive = false;
|
||||||
|
selectedIndex = -1;
|
||||||
|
} else {
|
||||||
|
selectedIndex = Math.min(selectedIndex, historyModel.values.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKey(event) {
|
||||||
|
if (event.key === Qt.Key_Down || event.key === 16777237) {
|
||||||
|
if (!keyboardActive) {
|
||||||
|
keyboardActive = true;
|
||||||
|
selectedIndex = 0;
|
||||||
|
} else {
|
||||||
|
selectNext();
|
||||||
|
}
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Up || event.key === 16777235) {
|
||||||
|
if (keyboardActive) {
|
||||||
|
selectPrevious();
|
||||||
|
}
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (keyboardActive && (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace)) {
|
||||||
|
clearSelected();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) && (event.modifiers & Qt.ShiftModifier)) {
|
||||||
|
NotificationService.clearHistory();
|
||||||
|
keyboardActive = false;
|
||||||
|
selectedIndex = -1;
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_F10) {
|
||||||
|
showKeyboardHints = !showKeyboardHints;
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ import QtQuick
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modules.Notifications.Center
|
|
||||||
|
|
||||||
DankPopout {
|
DankPopout {
|
||||||
id: root
|
id: root
|
||||||
@@ -112,8 +111,11 @@ DankPopout {
|
|||||||
baseHeight += Theme.spacingM * 2;
|
baseHeight += Theme.spacingM * 2;
|
||||||
|
|
||||||
const settingsHeight = notificationSettings.expanded ? notificationSettings.contentHeight : 0;
|
const settingsHeight = notificationSettings.expanded ? notificationSettings.contentHeight : 0;
|
||||||
let listHeight = notificationList.listContentHeight;
|
let listHeight = notificationHeader.currentTab === 0 ? notificationList.listContentHeight : Math.max(200, NotificationService.historyList.length * 80);
|
||||||
if (NotificationService.groupedNotifications.length === 0) {
|
if (notificationHeader.currentTab === 0 && NotificationService.groupedNotifications.length === 0) {
|
||||||
|
listHeight = 200;
|
||||||
|
}
|
||||||
|
if (notificationHeader.currentTab === 1 && NotificationService.historyList.length === 0) {
|
||||||
listHeight = 200;
|
listHeight = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +145,13 @@ DankPopout {
|
|||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
notificationHistoryVisible = false;
|
notificationHistoryVisible = false;
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
} else if (externalKeyboardController) {
|
return;
|
||||||
|
}
|
||||||
|
if (notificationHeader.currentTab === 1) {
|
||||||
|
historyList.handleKey(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (externalKeyboardController) {
|
||||||
externalKeyboardController.handleKey(event);
|
externalKeyboardController.handleKey(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,7 +195,14 @@ DankPopout {
|
|||||||
KeyboardNavigatedNotificationList {
|
KeyboardNavigatedNotificationList {
|
||||||
id: notificationList
|
id: notificationList
|
||||||
objectName: "notificationList"
|
objectName: "notificationList"
|
||||||
|
visible: notificationHeader.currentTab === 0
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryNotificationList {
|
||||||
|
id: historyList
|
||||||
|
visible: notificationHeader.currentTab === 1
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
|
height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
|
||||||
}
|
}
|
||||||
@@ -200,7 +215,7 @@ DankPopout {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
showHints: (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false
|
showHints: notificationHeader.currentTab === 0 ? (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false : historyList.showKeyboardHints
|
||||||
z: 200
|
z: 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,108 +8,150 @@ Item {
|
|||||||
|
|
||||||
property var keyboardController: null
|
property var keyboardController: null
|
||||||
property bool showSettings: false
|
property bool showSettings: false
|
||||||
|
property int currentTab: 0
|
||||||
|
|
||||||
|
onCurrentTabChanged: {
|
||||||
|
if (currentTab === 1 && !SettingsData.notificationHistoryEnabled)
|
||||||
|
currentTab = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onNotificationHistoryEnabledChanged() {
|
||||||
|
if (!SettingsData.notificationHistoryEnabled)
|
||||||
|
root.currentTab = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 32
|
height: headerColumn.implicitHeight
|
||||||
|
|
||||||
DankTooltipV2 {
|
DankTooltipV2 {
|
||||||
id: sharedTooltip
|
id: sharedTooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Column {
|
||||||
anchors.left: parent.left
|
id: headerColumn
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
width: parent.width
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledText {
|
Item {
|
||||||
text: I18n.tr("Notifications")
|
width: parent.width
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
height: Math.max(titleRow.implicitHeight, actionsRow.implicitHeight)
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: doNotDisturbButton
|
|
||||||
|
|
||||||
iconName: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
|
||||||
iconColor: SessionData.doNotDisturb ? Theme.error : Theme.surfaceText
|
|
||||||
buttonSize: 28
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
|
||||||
onEntered: {
|
|
||||||
sharedTooltip.show(I18n.tr("Do Not Disturb"), doNotDisturbButton, 0, 0, "bottom");
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
sharedTooltip.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: helpButton
|
|
||||||
iconName: "info"
|
|
||||||
iconColor: (keyboardController && keyboardController.showKeyboardHints) ? Theme.primary : Theme.surfaceText
|
|
||||||
buttonSize: 28
|
|
||||||
visible: keyboardController !== null
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: {
|
|
||||||
if (keyboardController) {
|
|
||||||
keyboardController.showKeyboardHints = !keyboardController.showKeyboardHints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: settingsButton
|
|
||||||
iconName: "settings"
|
|
||||||
iconColor: root.showSettings ? Theme.primary : Theme.surfaceText
|
|
||||||
buttonSize: 28
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: root.showSettings = !root.showSettings
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: clearAllButton
|
|
||||||
|
|
||||||
width: 120
|
|
||||||
height: 28
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
visible: NotificationService.notifications.length > 0
|
|
||||||
color: clearArea.containsMouse ? Theme.primaryHoverLight : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
id: titleRow
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "delete_sweep"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: clearArea.containsMouse ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: I18n.tr("Clear")
|
text: I18n.tr("Notifications")
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
color: clearArea.containsMouse ? Theme.primary : Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
id: doNotDisturbButton
|
||||||
|
iconName: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
||||||
|
iconColor: SessionData.doNotDisturb ? Theme.error : Theme.surfaceText
|
||||||
|
buttonSize: Theme.iconSize + Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||||
|
onEntered: sharedTooltip.show(I18n.tr("Do Not Disturb"), doNotDisturbButton, 0, 0, "bottom")
|
||||||
|
onExited: sharedTooltip.hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
Row {
|
||||||
id: clearArea
|
id: actionsRow
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
anchors.fill: parent
|
DankActionButton {
|
||||||
hoverEnabled: true
|
id: helpButton
|
||||||
cursorShape: Qt.PointingHandCursor
|
iconName: "info"
|
||||||
onClicked: NotificationService.clearAllNotifications()
|
iconColor: (keyboardController && keyboardController.showKeyboardHints) ? Theme.primary : Theme.surfaceText
|
||||||
|
buttonSize: Theme.iconSize + Theme.spacingS
|
||||||
|
visible: keyboardController !== null
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: {
|
||||||
|
if (keyboardController)
|
||||||
|
keyboardController.showKeyboardHints = !keyboardController.showKeyboardHints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
id: settingsButton
|
||||||
|
iconName: "settings"
|
||||||
|
iconColor: root.showSettings ? Theme.primary : Theme.surfaceText
|
||||||
|
buttonSize: Theme.iconSize + Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: root.showSettings = !root.showSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: clearAllButton
|
||||||
|
width: clearButtonContent.implicitWidth + Theme.spacingM * 2
|
||||||
|
height: Theme.iconSize + Theme.spacingS
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
visible: root.currentTab === 0 ? NotificationService.notifications.length > 0 : NotificationService.historyList.length > 0
|
||||||
|
color: clearArea.containsMouse ? Theme.primaryHoverLight : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: clearButtonContent
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "delete_sweep"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: clearArea.containsMouse ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Clear")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: clearArea.containsMouse ? Theme.primary : Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: clearArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (root.currentTab === 0) {
|
||||||
|
NotificationService.clearAllNotifications();
|
||||||
|
} else {
|
||||||
|
NotificationService.clearHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankButtonGroup {
|
||||||
|
id: tabGroup
|
||||||
|
width: parent.width
|
||||||
|
currentIndex: root.currentTab
|
||||||
|
buttonHeight: 32
|
||||||
|
buttonPadding: Theme.spacingM
|
||||||
|
checkEnabled: false
|
||||||
|
textSize: Theme.fontSizeSmall
|
||||||
|
visible: SettingsData.notificationHistoryEnabled
|
||||||
|
model: [I18n.tr("Current", "notification center tab") + " (" + NotificationService.notifications.length + ")", I18n.tr("History", "notification center tab") + " (" + NotificationService.historyList.length + ")"]
|
||||||
|
onSelectionChanged: (index, selected) => {
|
||||||
|
if (selected)
|
||||||
|
root.currentTab = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -36,64 +34,77 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property var timeoutOptions: [{
|
readonly property var timeoutOptions: [
|
||||||
|
{
|
||||||
"text": "Never",
|
"text": "Never",
|
||||||
"value": 0
|
"value": 0
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "1 second",
|
"text": "1 second",
|
||||||
"value": 1000
|
"value": 1000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "3 seconds",
|
"text": "3 seconds",
|
||||||
"value": 3000
|
"value": 3000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "5 seconds",
|
"text": "5 seconds",
|
||||||
"value": 5000
|
"value": 5000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "8 seconds",
|
"text": "8 seconds",
|
||||||
"value": 8000
|
"value": 8000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "10 seconds",
|
"text": "10 seconds",
|
||||||
"value": 10000
|
"value": 10000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "15 seconds",
|
"text": "15 seconds",
|
||||||
"value": 15000
|
"value": 15000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "30 seconds",
|
"text": "30 seconds",
|
||||||
"value": 30000
|
"value": 30000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "1 minute",
|
"text": "1 minute",
|
||||||
"value": 60000
|
"value": 60000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "2 minutes",
|
"text": "2 minutes",
|
||||||
"value": 120000
|
"value": 120000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "5 minutes",
|
"text": "5 minutes",
|
||||||
"value": 300000
|
"value": 300000
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"text": "10 minutes",
|
"text": "10 minutes",
|
||||||
"value": 600000
|
"value": 600000
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
|
|
||||||
function getTimeoutText(value) {
|
function getTimeoutText(value) {
|
||||||
if (value === undefined || value === null || isNaN(value)) {
|
if (value === undefined || value === null || isNaN(value)) {
|
||||||
return "5 seconds"
|
return "5 seconds";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||||
if (timeoutOptions[i].value === value) {
|
if (timeoutOptions[i].value === value) {
|
||||||
return timeoutOptions[i].text
|
return timeoutOptions[i].text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value === 0) {
|
if (value === 0) {
|
||||||
return "Never"
|
return "Never";
|
||||||
}
|
}
|
||||||
if (value < 1000) {
|
if (value < 1000) {
|
||||||
return value + "ms"
|
return value + "ms";
|
||||||
}
|
}
|
||||||
if (value < 60000) {
|
if (value < 60000) {
|
||||||
return Math.round(value / 1000) + " seconds"
|
return Math.round(value / 1000) + " seconds";
|
||||||
}
|
}
|
||||||
return Math.round(value / 60000) + " minutes"
|
return Math.round(value / 60000) + " minutes";
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -113,9 +124,10 @@ Rectangle {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 36
|
height: Math.max(dndRow.implicitHeight, dndToggle.implicitHeight) + Theme.spacingS
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
id: dndRow
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
@@ -136,6 +148,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
|
id: dndToggle
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
checked: SessionData.doNotDisturb
|
checked: SessionData.doNotDisturb
|
||||||
@@ -162,13 +175,13 @@ Rectangle {
|
|||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
||||||
options: timeoutOptions.map(opt => opt.text)
|
options: timeoutOptions.map(opt => opt.text)
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||||
if (timeoutOptions[i].text === value) {
|
if (timeoutOptions[i].text === value) {
|
||||||
SettingsData.set("notificationTimeoutLow", timeoutOptions[i].value)
|
SettingsData.set("notificationTimeoutLow", timeoutOptions[i].value);
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
@@ -177,13 +190,13 @@ Rectangle {
|
|||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
||||||
options: timeoutOptions.map(opt => opt.text)
|
options: timeoutOptions.map(opt => opt.text)
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||||
if (timeoutOptions[i].text === value) {
|
if (timeoutOptions[i].text === value) {
|
||||||
SettingsData.set("notificationTimeoutNormal", timeoutOptions[i].value)
|
SettingsData.set("notificationTimeoutNormal", timeoutOptions[i].value);
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
@@ -192,13 +205,13 @@ Rectangle {
|
|||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
||||||
options: timeoutOptions.map(opt => opt.text)
|
options: timeoutOptions.map(opt => opt.text)
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
for (let i = 0; i < timeoutOptions.length; i++) {
|
for (let i = 0; i < timeoutOptions.length; i++) {
|
||||||
if (timeoutOptions[i].text === value) {
|
if (timeoutOptions[i].text === value) {
|
||||||
SettingsData.set("notificationTimeoutCritical", timeoutOptions[i].value)
|
SettingsData.set("notificationTimeoutCritical", timeoutOptions[i].value);
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -209,9 +222,10 @@ Rectangle {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 36
|
height: Math.max(overlayRow.implicitHeight, overlayToggle.implicitHeight) + Theme.spacingS
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
id: overlayRow
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
@@ -242,11 +256,127 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
|
id: overlayToggle
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
checked: SettingsData.notificationOverlayEnabled
|
checked: SettingsData.notificationOverlayEnabled
|
||||||
onToggled: toggled => SettingsData.set("notificationOverlayEnabled", toggled)
|
onToggled: toggled => SettingsData.set("notificationOverlayEnabled", toggled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("History Settings")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: Math.max(lowRow.implicitHeight, lowToggle.implicitHeight) + Theme.spacingS
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: lowRow
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "low_priority"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: SettingsData.notificationHistorySaveLow ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Low Priority")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: lowToggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: SettingsData.notificationHistorySaveLow
|
||||||
|
onToggled: toggled => SettingsData.set("notificationHistorySaveLow", toggled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: Math.max(normalRow.implicitHeight, normalToggle.implicitHeight) + Theme.spacingS
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: normalRow
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "notifications"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: SettingsData.notificationHistorySaveNormal ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Normal Priority")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: normalToggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: SettingsData.notificationHistorySaveNormal
|
||||||
|
onToggled: toggled => SettingsData.set("notificationHistorySaveNormal", toggled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: Math.max(criticalRow.implicitHeight, criticalToggle.implicitHeight) + Theme.spacingS
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: criticalRow
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "priority_high"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: SettingsData.notificationHistorySaveCritical ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Critical Priority")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: criticalToggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: SettingsData.notificationHistorySaveCritical
|
||||||
|
onToggled: toggled => SettingsData.set("notificationHistorySaveCritical", toggled)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -587,16 +587,30 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
|
id: wiredLoadIcon
|
||||||
name: "sync"
|
name: "sync"
|
||||||
size: 16
|
size: 16
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
|
|
||||||
RotationAnimation on rotation {
|
SequentialAnimation {
|
||||||
running: NetworkService.networkWiredInfoLoading
|
running: NetworkService.networkWiredInfoLoading
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
from: 0
|
NumberAnimation {
|
||||||
to: 360
|
target: wiredLoadIcon
|
||||||
duration: 1000
|
property: "opacity"
|
||||||
|
to: 0.3
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
target: wiredLoadIcon
|
||||||
|
property: "opacity"
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
onRunningChanged: if (!running)
|
||||||
|
wiredLoadIcon.opacity = 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,17 +771,8 @@ Item {
|
|||||||
DankActionButton {
|
DankActionButton {
|
||||||
iconName: "refresh"
|
iconName: "refresh"
|
||||||
buttonSize: 32
|
buttonSize: 32
|
||||||
visible: NetworkService.wifiEnabled && !NetworkService.wifiToggling
|
visible: NetworkService.wifiEnabled && !NetworkService.wifiToggling && !NetworkService.isScanning
|
||||||
enabled: !NetworkService.isScanning
|
|
||||||
onClicked: NetworkService.scanWifi()
|
onClicked: NetworkService.scanWifi()
|
||||||
|
|
||||||
RotationAnimation on rotation {
|
|
||||||
running: NetworkService.isScanning
|
|
||||||
loops: Animation.Infinite
|
|
||||||
from: 0
|
|
||||||
to: 360
|
|
||||||
duration: 1000
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -956,17 +961,31 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "refresh"
|
id: scanningIcon
|
||||||
|
name: "wifi_find"
|
||||||
size: 32
|
size: 32
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
RotationAnimation on rotation {
|
SequentialAnimation {
|
||||||
running: true
|
running: NetworkService.isScanning
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
from: 0
|
NumberAnimation {
|
||||||
to: 360
|
target: scanningIcon
|
||||||
duration: 1000
|
property: "opacity"
|
||||||
|
to: 0.3
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
target: scanningIcon
|
||||||
|
property: "opacity"
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
onRunningChanged: if (!running)
|
||||||
|
scanningIcon.opacity = 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,16 +1260,30 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
|
id: wifiInfoLoadIcon
|
||||||
name: "sync"
|
name: "sync"
|
||||||
size: 16
|
size: 16
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
|
|
||||||
RotationAnimation on rotation {
|
SequentialAnimation {
|
||||||
running: NetworkService.networkInfoLoading
|
running: NetworkService.networkInfoLoading
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
from: 0
|
NumberAnimation {
|
||||||
to: 360
|
target: wifiInfoLoadIcon
|
||||||
duration: 1000
|
property: "opacity"
|
||||||
|
to: 0.3
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
target: wifiInfoLoadIcon
|
||||||
|
property: "opacity"
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
onRunningChanged: if (!running)
|
||||||
|
wifiInfoLoadIcon.opacity = 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1707,9 +1740,31 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
|
id: vpnLoadIcon
|
||||||
name: "sync"
|
name: "sync"
|
||||||
size: 16
|
size: 16
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
running: VPNService.configLoading
|
||||||
|
loops: Animation.Infinite
|
||||||
|
NumberAnimation {
|
||||||
|
target: vpnLoadIcon
|
||||||
|
property: "opacity"
|
||||||
|
to: 0.3
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
target: vpnLoadIcon
|
||||||
|
property: "opacity"
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
onRunningChanged: if (!running)
|
||||||
|
vpnLoadIcon.opacity = 1.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -219,6 +219,105 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
width: parent.width
|
||||||
|
iconName: "history"
|
||||||
|
title: I18n.tr("History Settings")
|
||||||
|
settingKey: "notificationHistory"
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "notificationHistoryEnabled"
|
||||||
|
tags: ["notification", "history", "enable", "disable", "save"]
|
||||||
|
text: I18n.tr("Enable History", "notification history toggle label")
|
||||||
|
description: I18n.tr("Save dismissed notifications to history", "notification history toggle description")
|
||||||
|
checked: SettingsData.notificationHistoryEnabled
|
||||||
|
onToggled: checked => SettingsData.set("notificationHistoryEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
settingKey: "notificationHistoryMaxCount"
|
||||||
|
tags: ["notification", "history", "max", "count", "limit"]
|
||||||
|
text: I18n.tr("Maximum History")
|
||||||
|
description: I18n.tr("Maximum number of notifications to keep", "notification history limit")
|
||||||
|
value: SettingsData.notificationHistoryMaxCount
|
||||||
|
minimum: 10
|
||||||
|
maximum: 200
|
||||||
|
step: 10
|
||||||
|
unit: ""
|
||||||
|
defaultValue: 50
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("notificationHistoryMaxCount", newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsDropdownRow {
|
||||||
|
settingKey: "notificationHistoryMaxAgeDays"
|
||||||
|
tags: ["notification", "history", "max", "age", "days", "retention"]
|
||||||
|
text: I18n.tr("History Retention", "notification history retention settings label")
|
||||||
|
description: I18n.tr("Auto-delete notifications older than this", "notification history setting")
|
||||||
|
currentValue: {
|
||||||
|
switch (SettingsData.notificationHistoryMaxAgeDays) {
|
||||||
|
case 0:
|
||||||
|
return I18n.tr("Forever", "notification history retention option");
|
||||||
|
case 1:
|
||||||
|
return I18n.tr("1 day", "notification history retention option");
|
||||||
|
case 3:
|
||||||
|
return I18n.tr("3 days", "notification history retention option");
|
||||||
|
case 7:
|
||||||
|
return I18n.tr("7 days", "notification history retention option");
|
||||||
|
case 14:
|
||||||
|
return I18n.tr("14 days", "notification history retention option");
|
||||||
|
case 30:
|
||||||
|
return I18n.tr("30 days", "notification history retention option");
|
||||||
|
default:
|
||||||
|
return SettingsData.notificationHistoryMaxAgeDays + " " + I18n.tr("days");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options: [I18n.tr("Forever", "notification history retention option"), I18n.tr("1 day", "notification history retention option"), I18n.tr("3 days", "notification history retention option"), I18n.tr("7 days", "notification history retention option"), I18n.tr("14 days", "notification history retention option"), I18n.tr("30 days", "notification history retention option")]
|
||||||
|
onValueChanged: value => {
|
||||||
|
let days = 7;
|
||||||
|
if (value === I18n.tr("Forever", "notification history retention option"))
|
||||||
|
days = 0;
|
||||||
|
else if (value === I18n.tr("1 day", "notification history retention option"))
|
||||||
|
days = 1;
|
||||||
|
else if (value === I18n.tr("3 days", "notification history retention option"))
|
||||||
|
days = 3;
|
||||||
|
else if (value === I18n.tr("7 days", "notification history retention option"))
|
||||||
|
days = 7;
|
||||||
|
else if (value === I18n.tr("14 days", "notification history retention option"))
|
||||||
|
days = 14;
|
||||||
|
else if (value === I18n.tr("30 days", "notification history retention option"))
|
||||||
|
days = 30;
|
||||||
|
SettingsData.set("notificationHistoryMaxAgeDays", days);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "notificationHistorySaveLow"
|
||||||
|
tags: ["notification", "history", "save", "low", "priority"]
|
||||||
|
text: I18n.tr("Low Priority")
|
||||||
|
description: I18n.tr("Save low priority notifications to history", "notification history setting")
|
||||||
|
checked: SettingsData.notificationHistorySaveLow
|
||||||
|
onToggled: checked => SettingsData.set("notificationHistorySaveLow", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "notificationHistorySaveNormal"
|
||||||
|
tags: ["notification", "history", "save", "normal", "priority"]
|
||||||
|
text: I18n.tr("Normal Priority")
|
||||||
|
description: I18n.tr("Save normal priority notifications to history", "notification history setting")
|
||||||
|
checked: SettingsData.notificationHistorySaveNormal
|
||||||
|
onToggled: checked => SettingsData.set("notificationHistorySaveNormal", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "notificationHistorySaveCritical"
|
||||||
|
tags: ["notification", "history", "save", "critical", "priority"]
|
||||||
|
text: I18n.tr("Critical Priority")
|
||||||
|
description: I18n.tr("Save critical priority notifications to history", "notification history setting")
|
||||||
|
checked: SettingsData.notificationHistorySaveCritical
|
||||||
|
onToggled: checked => SettingsData.set("notificationHistorySaveCritical", checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,15 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("fadeToLockEnabled", checked)
|
onToggled: checked => SettingsData.set("fadeToLockEnabled", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "fadeToDpmsEnabled"
|
||||||
|
tags: ["fade", "dpms", "monitor", "screen", "idle", "grace period"]
|
||||||
|
text: I18n.tr("Fade to monitor off")
|
||||||
|
description: I18n.tr("Gradually fade the screen before turning off monitors with a configurable grace period")
|
||||||
|
checked: SettingsData.fadeToDpmsEnabled
|
||||||
|
onToggled: checked => SettingsData.set("fadeToDpmsEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
settingKey: "lockBeforeSuspend"
|
settingKey: "lockBeforeSuspend"
|
||||||
tags: ["lock", "suspend", "sleep", "security"]
|
tags: ["lock", "suspend", "sleep", "security"]
|
||||||
@@ -89,7 +98,7 @@ Item {
|
|||||||
property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"]
|
property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"]
|
||||||
property var periodValues: [1, 2, 3, 4, 5, 10, 15, 20, 30]
|
property var periodValues: [1, 2, 3, 4, 5, 10, 15, 20, 30]
|
||||||
|
|
||||||
text: I18n.tr("Fade grace period")
|
text: I18n.tr("Lock fade grace period")
|
||||||
options: periodOptions
|
options: periodOptions
|
||||||
visible: SettingsData.fadeToLockEnabled
|
visible: SettingsData.fadeToLockEnabled
|
||||||
enabled: SettingsData.fadeToLockEnabled
|
enabled: SettingsData.fadeToLockEnabled
|
||||||
@@ -107,6 +116,32 @@ Item {
|
|||||||
SettingsData.set("fadeToLockGracePeriod", periodValues[index]);
|
SettingsData.set("fadeToLockGracePeriod", periodValues[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsDropdownRow {
|
||||||
|
id: fadeDpmsGracePeriodDropdown
|
||||||
|
settingKey: "fadeToDpmsGracePeriod"
|
||||||
|
tags: ["fade", "grace", "period", "timeout", "dpms", "monitor"]
|
||||||
|
property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"]
|
||||||
|
property var periodValues: [1, 2, 3, 4, 5, 10, 15, 20, 30]
|
||||||
|
|
||||||
|
text: I18n.tr("Monitor fade grace period")
|
||||||
|
options: periodOptions
|
||||||
|
visible: SettingsData.fadeToDpmsEnabled
|
||||||
|
enabled: SettingsData.fadeToDpmsEnabled
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
const currentPeriod = SettingsData.fadeToDpmsGracePeriod;
|
||||||
|
const index = periodValues.indexOf(currentPeriod);
|
||||||
|
currentValue = index >= 0 ? periodOptions[index] : "5 seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueChanged: value => {
|
||||||
|
const index = periodOptions.indexOf(value);
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
SettingsData.set("fadeToDpmsGracePeriod", periodValues[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
id: powerProfileDropdown
|
id: powerProfileDropdown
|
||||||
settingKey: "powerProfile"
|
settingKey: "powerProfile"
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ Singleton {
|
|||||||
signal lockRequested
|
signal lockRequested
|
||||||
signal fadeToLockRequested
|
signal fadeToLockRequested
|
||||||
signal cancelFadeToLock
|
signal cancelFadeToLock
|
||||||
|
signal fadeToDpmsRequested
|
||||||
|
signal cancelFadeToDpms
|
||||||
signal requestMonitorOff
|
signal requestMonitorOff
|
||||||
signal requestMonitorOn
|
signal requestMonitorOn
|
||||||
signal requestSuspend
|
signal requestSuspend
|
||||||
@@ -61,11 +63,17 @@ Singleton {
|
|||||||
property var lockMonitor: null
|
property var lockMonitor: null
|
||||||
property var suspendMonitor: null
|
property var suspendMonitor: null
|
||||||
property var lockComponent: null
|
property var lockComponent: null
|
||||||
|
property bool monitorsOff: false
|
||||||
|
|
||||||
function wake() {
|
function wake() {
|
||||||
requestMonitorOn();
|
requestMonitorOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reapplyDpmsIfNeeded() {
|
||||||
|
if (monitorsOff)
|
||||||
|
CompositorService.powerOffMonitors();
|
||||||
|
}
|
||||||
|
|
||||||
function createIdleMonitors() {
|
function createIdleMonitors() {
|
||||||
if (!idleMonitorAvailable) {
|
if (!idleMonitorAvailable) {
|
||||||
console.info("IdleService: IdleMonitor not available, skipping creation");
|
console.info("IdleService: IdleMonitor not available, skipping creation");
|
||||||
@@ -90,8 +98,15 @@ Singleton {
|
|||||||
monitorOffMonitor.timeout = Qt.binding(() => root.monitorTimeout);
|
monitorOffMonitor.timeout = Qt.binding(() => root.monitorTimeout);
|
||||||
monitorOffMonitor.isIdleChanged.connect(function () {
|
monitorOffMonitor.isIdleChanged.connect(function () {
|
||||||
if (monitorOffMonitor.isIdle) {
|
if (monitorOffMonitor.isIdle) {
|
||||||
root.requestMonitorOff();
|
if (SettingsData.fadeToDpmsEnabled) {
|
||||||
|
root.fadeToDpmsRequested();
|
||||||
|
} else {
|
||||||
|
root.requestMonitorOff();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (SettingsData.fadeToDpmsEnabled) {
|
||||||
|
root.cancelFadeToDpms();
|
||||||
|
}
|
||||||
root.requestMonitorOn();
|
root.requestMonitorOn();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -131,10 +146,12 @@ Singleton {
|
|||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onRequestMonitorOff() {
|
function onRequestMonitorOff() {
|
||||||
|
monitorsOff = true;
|
||||||
CompositorService.powerOffMonitors();
|
CompositorService.powerOffMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRequestMonitorOn() {
|
function onRequestMonitorOn() {
|
||||||
|
monitorsOff = false;
|
||||||
CompositorService.powerOnMonitors();
|
CompositorService.powerOnMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,26 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: ensureOutputsProcess
|
||||||
|
property string outputsPath: ""
|
||||||
|
|
||||||
|
onExited: exitCode => {
|
||||||
|
if (exitCode !== 0)
|
||||||
|
console.warn("NiriService: Failed to ensure outputs.kdl, exit code:", exitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: ensureBindsProcess
|
||||||
|
property string bindsPath: ""
|
||||||
|
|
||||||
|
onExited: exitCode => {
|
||||||
|
if (exitCode !== 0)
|
||||||
|
console.warn("NiriService: Failed to ensure binds.kdl, exit code:", exitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DankSocket {
|
DankSocket {
|
||||||
id: eventStreamSocket
|
id: eventStreamSocket
|
||||||
path: root.socketPath
|
path: root.socketPath
|
||||||
@@ -1042,6 +1062,16 @@ Singleton {
|
|||||||
writeAlttabProcess.command = ["sh", "-c", `mkdir -p "${niriDmsDir}" && cat > "${alttabPath}" << 'EOF'\n${alttabContent}\nEOF`];
|
writeAlttabProcess.command = ["sh", "-c", `mkdir -p "${niriDmsDir}" && cat > "${alttabPath}" << 'EOF'\n${alttabContent}\nEOF`];
|
||||||
writeAlttabProcess.running = true;
|
writeAlttabProcess.running = true;
|
||||||
|
|
||||||
|
const outputsPath = niriDmsDir + "/outputs.kdl";
|
||||||
|
ensureOutputsProcess.outputsPath = outputsPath;
|
||||||
|
ensureOutputsProcess.command = ["sh", "-c", `mkdir -p "${niriDmsDir}" && [ ! -f "${outputsPath}" ] && touch "${outputsPath}" || true`];
|
||||||
|
ensureOutputsProcess.running = true;
|
||||||
|
|
||||||
|
const bindsPath = niriDmsDir + "/binds.kdl";
|
||||||
|
ensureBindsProcess.bindsPath = bindsPath;
|
||||||
|
ensureBindsProcess.command = ["sh", "-c", `mkdir -p "${niriDmsDir}" && [ ! -f "${bindsPath}" ] && touch "${bindsPath}" || true`];
|
||||||
|
ensureBindsProcess.running = true;
|
||||||
|
|
||||||
configGenerationPending = false;
|
configGenerationPending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1147,8 +1177,7 @@ Singleton {
|
|||||||
kdlContent += `output "${identifier}" {\n`;
|
kdlContent += `output "${identifier}" {\n`;
|
||||||
|
|
||||||
if (niriSettings.disabled) {
|
if (niriSettings.disabled) {
|
||||||
kdlContent += ` off\n}\n\n`;
|
kdlContent += ` off\n`;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.current_mode !== undefined && output.modes && output.modes[output.current_mode]) {
|
if (output.current_mode !== undefined && output.modes && output.modes[output.current_mode]) {
|
||||||
@@ -1157,7 +1186,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (output.logical) {
|
if (output.logical) {
|
||||||
kdlContent += ` scale ${output.logical.scale ?? 1.0}\n`;
|
kdlContent += ` scale ${output.logical.scale || 1.0}\n`;
|
||||||
|
|
||||||
if (output.logical.transform && output.logical.transform !== "Normal") {
|
if (output.logical.transform && output.logical.transform !== "Normal") {
|
||||||
const transformMap = {
|
const transformMap = {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import "../Common/markdown2html.js" as Markdown2Html
|
import "../Common/markdown2html.js" as Markdown2Html
|
||||||
@@ -14,6 +15,10 @@ Singleton {
|
|||||||
readonly property list<NotifWrapper> allWrappers: []
|
readonly property list<NotifWrapper> allWrappers: []
|
||||||
readonly property list<NotifWrapper> popups: allWrappers.filter(n => n && n.popup)
|
readonly property list<NotifWrapper> popups: allWrappers.filter(n => n && n.popup)
|
||||||
|
|
||||||
|
property var historyList: []
|
||||||
|
readonly property string historyFile: Paths.strip(Paths.cache) + "/notification_history.json"
|
||||||
|
property bool historyLoaded: false
|
||||||
|
|
||||||
property list<NotifWrapper> notificationQueue: []
|
property list<NotifWrapper> notificationQueue: []
|
||||||
property list<NotifWrapper> visibleNotifications: []
|
property list<NotifWrapper> visibleNotifications: []
|
||||||
property int maxVisibleNotifications: 3
|
property int maxVisibleNotifications: 3
|
||||||
@@ -26,7 +31,7 @@ Singleton {
|
|||||||
property int maxIngressPerSecond: 20
|
property int maxIngressPerSecond: 20
|
||||||
property double _lastIngressSec: 0
|
property double _lastIngressSec: 0
|
||||||
property int _ingressCountThisSec: 0
|
property int _ingressCountThisSec: 0
|
||||||
property int maxStoredNotifications: 50
|
property int maxStoredNotifications: SettingsData.notificationHistoryMaxCount
|
||||||
|
|
||||||
property var _dismissQueue: []
|
property var _dismissQueue: []
|
||||||
property int _dismissBatchSize: 8
|
property int _dismissBatchSize: 8
|
||||||
@@ -40,6 +45,165 @@ Singleton {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
_recomputeGroups();
|
_recomputeGroups();
|
||||||
|
Quickshell.execDetached(["mkdir", "-p", Paths.strip(Paths.cache)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: historyFileView
|
||||||
|
path: root.historyFile
|
||||||
|
printErrors: false
|
||||||
|
onLoaded: root.loadHistory()
|
||||||
|
onLoadFailed: error => {
|
||||||
|
if (error === 2) {
|
||||||
|
root.historyLoaded = true;
|
||||||
|
historyFileView.writeAdapter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonAdapter {
|
||||||
|
id: historyAdapter
|
||||||
|
property var notifications: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: historySaveTimer
|
||||||
|
interval: 200
|
||||||
|
onTriggered: root.performSaveHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToHistory(wrapper) {
|
||||||
|
if (!wrapper)
|
||||||
|
return;
|
||||||
|
const urg = typeof wrapper.urgency === "number" ? wrapper.urgency : 1;
|
||||||
|
const data = {
|
||||||
|
id: wrapper.notification?.id?.toString() || Date.now().toString(),
|
||||||
|
summary: wrapper.summary || "",
|
||||||
|
body: wrapper.body || "",
|
||||||
|
htmlBody: wrapper.htmlBody || wrapper.body || "",
|
||||||
|
appName: wrapper.appName || "",
|
||||||
|
appIcon: wrapper.appIcon || "",
|
||||||
|
image: wrapper.cleanImage || "",
|
||||||
|
urgency: urg,
|
||||||
|
timestamp: wrapper.time.getTime(),
|
||||||
|
desktopEntry: wrapper.desktopEntry || ""
|
||||||
|
};
|
||||||
|
let newList = [data, ...historyList];
|
||||||
|
if (newList.length > SettingsData.notificationHistoryMaxCount) {
|
||||||
|
newList = newList.slice(0, SettingsData.notificationHistoryMaxCount);
|
||||||
|
}
|
||||||
|
historyList = newList;
|
||||||
|
saveHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveHistory() {
|
||||||
|
historySaveTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function performSaveHistory() {
|
||||||
|
try {
|
||||||
|
historyAdapter.notifications = historyList;
|
||||||
|
historyFileView.writeAdapter();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("NotificationService: save history failed:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadHistory() {
|
||||||
|
try {
|
||||||
|
const maxAgeDays = SettingsData.notificationHistoryMaxAgeDays;
|
||||||
|
const now = Date.now();
|
||||||
|
const maxAgeMs = maxAgeDays > 0 ? maxAgeDays * 24 * 60 * 60 * 1000 : 0;
|
||||||
|
const loaded = [];
|
||||||
|
|
||||||
|
for (const item of historyAdapter.notifications || []) {
|
||||||
|
if (maxAgeMs > 0 && (now - item.timestamp) > maxAgeMs)
|
||||||
|
continue;
|
||||||
|
const urg = typeof item.urgency === "number" ? item.urgency : 1;
|
||||||
|
const body = item.body || "";
|
||||||
|
let htmlBody = item.htmlBody || "";
|
||||||
|
if (!htmlBody && body) {
|
||||||
|
htmlBody = (body.includes('<') && body.includes('>')) ? body : Markdown2Html.markdownToHtml(body);
|
||||||
|
}
|
||||||
|
loaded.push({
|
||||||
|
id: item.id || "",
|
||||||
|
summary: item.summary || "",
|
||||||
|
body: body,
|
||||||
|
htmlBody: htmlBody,
|
||||||
|
appName: item.appName || "",
|
||||||
|
appIcon: item.appIcon || "",
|
||||||
|
image: item.image || "",
|
||||||
|
urgency: urg,
|
||||||
|
timestamp: item.timestamp || 0,
|
||||||
|
desktopEntry: item.desktopEntry || ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
historyList = loaded;
|
||||||
|
historyLoaded = true;
|
||||||
|
if (maxAgeMs > 0 && loaded.length !== (historyAdapter.notifications || []).length)
|
||||||
|
saveHistory();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("NotificationService: load history failed:", e);
|
||||||
|
historyLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromHistory(notificationId) {
|
||||||
|
const idx = historyList.findIndex(n => n.id === notificationId);
|
||||||
|
if (idx >= 0) {
|
||||||
|
historyList = historyList.filter((_, i) => i !== idx);
|
||||||
|
saveHistory();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearHistory() {
|
||||||
|
historyList = [];
|
||||||
|
saveHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHistoryTimeRange(timestamp) {
|
||||||
|
const now = new Date();
|
||||||
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||||
|
const itemDate = new Date(timestamp);
|
||||||
|
const itemDay = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate());
|
||||||
|
const diffDays = Math.floor((today - itemDay) / (1000 * 60 * 60 * 24));
|
||||||
|
if (diffDays === 0)
|
||||||
|
return 0;
|
||||||
|
if (diffDays === 1)
|
||||||
|
return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHistoryCountForRange(range) {
|
||||||
|
if (range === -1)
|
||||||
|
return historyList.length;
|
||||||
|
return historyList.filter(n => getHistoryTimeRange(n.timestamp) === range).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatHistoryTime(timestamp) {
|
||||||
|
root.timeUpdateTick;
|
||||||
|
root.clockFormatChanged;
|
||||||
|
const now = new Date();
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const diff = now.getTime() - timestamp;
|
||||||
|
const minutes = Math.floor(diff / 60000);
|
||||||
|
const hours = Math.floor(minutes / 60);
|
||||||
|
if (hours < 1) {
|
||||||
|
if (minutes < 1)
|
||||||
|
return I18n.tr("now");
|
||||||
|
return I18n.tr("%1m ago").arg(minutes);
|
||||||
|
}
|
||||||
|
const nowDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||||
|
const itemDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||||
|
const daysDiff = Math.floor((nowDate - itemDate) / (1000 * 60 * 60 * 24));
|
||||||
|
const timeStr = SettingsData.use24HourClock ? date.toLocaleTimeString(Qt.locale(), "HH:mm") : date.toLocaleTimeString(Qt.locale(), "h:mm AP");
|
||||||
|
if (daysDiff === 0)
|
||||||
|
return timeStr;
|
||||||
|
if (daysDiff === 1)
|
||||||
|
return I18n.tr("yesterday") + ", " + timeStr;
|
||||||
|
return I18n.tr("%1 days ago").arg(daysDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _nowSec() {
|
function _nowSec() {
|
||||||
@@ -84,6 +248,40 @@ Singleton {
|
|||||||
wrapper.isPersistent = isCritical || (timeoutMs === 0);
|
wrapper.isPersistent = isCritical || (timeoutMs === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _shouldSaveToHistory(urgency) {
|
||||||
|
if (!SettingsData.notificationHistoryEnabled)
|
||||||
|
return false;
|
||||||
|
switch (urgency) {
|
||||||
|
case NotificationUrgency.Low:
|
||||||
|
return SettingsData.notificationHistorySaveLow;
|
||||||
|
case NotificationUrgency.Critical:
|
||||||
|
return SettingsData.notificationHistorySaveCritical;
|
||||||
|
default:
|
||||||
|
return SettingsData.notificationHistorySaveNormal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pruneHistory() {
|
||||||
|
const maxAgeDays = SettingsData.notificationHistoryMaxAgeDays;
|
||||||
|
if (maxAgeDays <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
|
||||||
|
const pruned = historyList.filter(item => (now - item.timestamp) <= maxAgeMs);
|
||||||
|
|
||||||
|
if (pruned.length !== historyList.length) {
|
||||||
|
historyList = pruned;
|
||||||
|
saveHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteHistory() {
|
||||||
|
historyList = [];
|
||||||
|
historyAdapter.notifications = [];
|
||||||
|
historyFileView.writeAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
function _trimStored() {
|
function _trimStored() {
|
||||||
if (notifications.length > maxStoredNotifications) {
|
if (notifications.length > maxStoredNotifications) {
|
||||||
const overflow = notifications.length - maxStoredNotifications;
|
const overflow = notifications.length - maxStoredNotifications;
|
||||||
@@ -121,6 +319,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
visibleNotifications = [];
|
visibleNotifications = [];
|
||||||
_recomputeGroupsLater();
|
_recomputeGroupsLater();
|
||||||
|
pruneHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOverlayClose() {
|
function onOverlayClose() {
|
||||||
@@ -234,9 +433,11 @@ Singleton {
|
|||||||
|
|
||||||
if (wrapper) {
|
if (wrapper) {
|
||||||
root.allWrappers.push(wrapper);
|
root.allWrappers.push(wrapper);
|
||||||
if (!isTransient) {
|
const shouldSave = !isTransient && _shouldSaveToHistory(notif.urgency);
|
||||||
|
if (shouldSave) {
|
||||||
root.notifications.push(wrapper);
|
root.notifications.push(wrapper);
|
||||||
_trimStored();
|
_trimStored();
|
||||||
|
root.addToHistory(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
@@ -703,5 +904,13 @@ Singleton {
|
|||||||
function onUse24HourClockChanged() {
|
function onUse24HourClockChanged() {
|
||||||
root.clockFormatChanged = !root.clockFormatChanged;
|
root.clockFormatChanged = !root.clockFormatChanged;
|
||||||
}
|
}
|
||||||
|
function onNotificationHistoryMaxAgeDaysChanged() {
|
||||||
|
root.pruneHistory();
|
||||||
|
}
|
||||||
|
function onNotificationHistoryEnabledChanged() {
|
||||||
|
if (!SettingsData.notificationHistoryEnabled) {
|
||||||
|
root.deleteHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Item {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.left: parent.left
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -79,7 +79,7 @@ Item {
|
|||||||
visible: description.length > 0
|
visible: description.length > 0
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.left: parent.left
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +146,7 @@ Item {
|
|||||||
width: contentRow.width - (contentRow.children[0].visible ? contentRow.children[0].width + contentRow.spacing : 0)
|
width: contentRow.width - (contentRow.children[0].visible ? contentRow.children[0].width + contentRow.spacing : 0)
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +232,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Rectangle {
|
contentItem: Rectangle {
|
||||||
|
LayoutMirroring.enabled: I18n.isRtl
|
||||||
|
LayoutMirroring.childrenInherit: true
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
border.width: 2
|
border.width: 2
|
||||||
@@ -313,11 +316,14 @@ Item {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: Theme.spacingS
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.rightMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: root.emptyText
|
text: root.emptyText
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +363,9 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: Theme.spacingS
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.rightMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
@@ -374,9 +382,10 @@ Item {
|
|||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: delegateRoot.isCurrentValue ? Theme.primary : Theme.surfaceText
|
color: delegateRoot.isCurrentValue ? Theme.primary : Theme.surfaceText
|
||||||
font.weight: delegateRoot.isCurrentValue ? Font.Medium : Font.Normal
|
font.weight: delegateRoot.isCurrentValue ? Font.Medium : Font.Normal
|
||||||
width: root.popupWidth > 0 ? undefined : (delegateRoot.width - parent.x - Theme.spacingS)
|
width: root.popupWidth > 0 ? undefined : (delegateRoot.width - parent.x - Theme.spacingS * 2)
|
||||||
elide: root.popupWidth > 0 ? Text.ElideNone : Text.ElideRight
|
elide: root.popupWidth > 0 ? Text.ElideNone : Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
101
quickshell/Widgets/DankFilterChips.qml
Normal file
101
quickshell/Widgets/DankFilterChips.qml
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var model: []
|
||||||
|
property int currentIndex: 0
|
||||||
|
property int chipHeight: 32
|
||||||
|
property int chipPadding: Theme.spacingM
|
||||||
|
property bool showCheck: true
|
||||||
|
property bool showCounts: true
|
||||||
|
|
||||||
|
signal selectionChanged(int index)
|
||||||
|
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
width: parent ? parent.width : 400
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.model
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: chip
|
||||||
|
required property var modelData
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
property bool selected: index === root.currentIndex
|
||||||
|
property bool hovered: mouseArea.containsMouse
|
||||||
|
property bool pressed: mouseArea.pressed
|
||||||
|
property string label: typeof modelData === "string" ? modelData : (modelData.label || "")
|
||||||
|
property int count: typeof modelData === "object" ? (modelData.count || 0) : 0
|
||||||
|
property bool showCount: root.showCounts && count > 0
|
||||||
|
|
||||||
|
width: contentRow.implicitWidth + root.chipPadding * 2
|
||||||
|
height: root.chipHeight
|
||||||
|
radius: height / 2
|
||||||
|
|
||||||
|
color: selected ? Theme.primary : Theme.surfaceVariant
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
color: {
|
||||||
|
if (pressed)
|
||||||
|
return chip.selected ? Theme.primaryPressed : Theme.surfaceTextHover;
|
||||||
|
if (hovered)
|
||||||
|
return chip.selected ? Theme.primaryHover : Theme.surfaceTextHover;
|
||||||
|
return "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shorterDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: contentRow
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "check"
|
||||||
|
size: 16
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: root.showCheck && chip.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: chip.label + (chip.showCount ? " (" + chip.count + ")" : "")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: chip.selected ? Font.Medium : Font.Normal
|
||||||
|
color: chip.selected ? Theme.primaryText : Theme.surfaceVariantText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
root.currentIndex = chip.index;
|
||||||
|
root.selectionChanged(chip.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,7 +73,7 @@ Item {
|
|||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
opacity: toggle.enabled ? 1 : 0.4
|
opacity: toggle.enabled ? 1 : 0.4
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.left: parent.left
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -83,7 +83,7 @@ Item {
|
|||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: Math.min(implicitWidth, toggle.width - 120)
|
width: Math.min(implicitWidth, toggle.width - 120)
|
||||||
visible: toggle.description.length > 0
|
visible: toggle.description.length > 0
|
||||||
anchors.left: parent.left
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
"list.focusOutline": "{{colors.primary.dark.hex}}",
|
"list.focusOutline": "{{colors.primary.dark.hex}}",
|
||||||
"list.focusBackground": "{{colors.surface_container_high.dark.hex}}",
|
"list.focusBackground": "{{colors.surface_container_high.dark.hex}}",
|
||||||
"list.highlightForeground": "{{colors.primary.dark.hex}}",
|
"list.highlightForeground": "{{colors.primary.dark.hex}}",
|
||||||
|
"list.focusHighlightForeground": "{{colors.on_primary.dark.hex}}",
|
||||||
"list.errorForeground": "{{colors.error.dark.hex}}",
|
"list.errorForeground": "{{colors.error.dark.hex}}",
|
||||||
"list.warningForeground": "{{colors.secondary.dark.hex}}",
|
"list.warningForeground": "{{colors.secondary.dark.hex}}",
|
||||||
//
|
//
|
||||||
@@ -162,9 +163,9 @@
|
|||||||
//
|
//
|
||||||
// Scrollbar
|
// Scrollbar
|
||||||
//
|
//
|
||||||
"scrollbarSlider.background": "{{colors.outline.dark.hex}}40",
|
"scrollbarSlider.background": "{{colors.on_surface_variant.dark.hex}}50",
|
||||||
"scrollbarSlider.hoverBackground": "{{colors.outline.dark.hex}}60",
|
"scrollbarSlider.hoverBackground": "{{colors.on_surface_variant.dark.hex}}80",
|
||||||
"scrollbarSlider.activeBackground": "{{colors.outline.dark.hex}}80",
|
"scrollbarSlider.activeBackground": "{{colors.on_surface_variant.dark.hex}}AA",
|
||||||
//
|
//
|
||||||
// Terminal (Dank16)
|
// Terminal (Dank16)
|
||||||
//
|
//
|
||||||
@@ -192,79 +193,107 @@
|
|||||||
//
|
//
|
||||||
"tokenColors": [
|
"tokenColors": [
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["comment"],
|
||||||
"comment"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color8.dark.hex}}"
|
"foreground": "{{dank16.color8.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["keyword"],
|
||||||
"keyword"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color5.dark.hex}}"
|
"foreground": "{{dank16.color5.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["string"],
|
||||||
"string"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color3.dark.hex}}"
|
"foreground": "{{dank16.color3.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["constant", "constant.language", "constant.numeric"],
|
||||||
"constant",
|
|
||||||
"number"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color12.dark.hex}}"
|
"foreground": "{{dank16.color12.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["variable"],
|
||||||
"variable"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color15.dark.hex}}"
|
"foreground": "{{dank16.color15.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["entity.name.function"],
|
||||||
"entity.name.function"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color2.dark.hex}}"
|
"foreground": "{{dank16.color2.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["entity.name.class", "support.type"],
|
||||||
"entity.name.class",
|
|
||||||
"support.type"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color12.dark.hex}}"
|
"foreground": "{{dank16.color12.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["invalid"],
|
||||||
"invalid"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.error.dark.hex}}"
|
"foreground": "{{colors.error.dark.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["markup.heading"],
|
||||||
"markup.heading"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.primary.dark.hex}}",
|
"foreground": "{{colors.primary.dark.hex}}",
|
||||||
"fontStyle": "bold"
|
"fontStyle": "bold"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.yaml", "punctuation.definition.block.sequence.item.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["source.yaml string.unquoted", "source.yaml string.quoted"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color3.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.yaml", "constant.language.null.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color12.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["punctuation.separator.key-value.mapping.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.toml", "support.type.property-name.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["string.quoted.single.basic.line.toml", "string.quoted.double.basic.line.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color3.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.toml", "constant.numeric.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color12.dark.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["meta.object-literal.key", "support.type.property-name.json"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.dark.hex}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
"list.focusOutline": "{{colors.primary.default.hex}}",
|
"list.focusOutline": "{{colors.primary.default.hex}}",
|
||||||
"list.focusBackground": "{{colors.surface_container_high.default.hex}}",
|
"list.focusBackground": "{{colors.surface_container_high.default.hex}}",
|
||||||
"list.highlightForeground": "{{colors.primary.default.hex}}",
|
"list.highlightForeground": "{{colors.primary.default.hex}}",
|
||||||
|
"list.focusHighlightForeground": "{{colors.on_primary.default.hex}}",
|
||||||
"list.errorForeground": "{{colors.error.default.hex}}",
|
"list.errorForeground": "{{colors.error.default.hex}}",
|
||||||
"list.warningForeground": "{{colors.secondary.default.hex}}",
|
"list.warningForeground": "{{colors.secondary.default.hex}}",
|
||||||
"input.background": "{{colors.surface_container_low.default.hex}}",
|
"input.background": "{{colors.surface_container_low.default.hex}}",
|
||||||
@@ -114,9 +115,9 @@
|
|||||||
"editorSuggestWidget.foreground": "{{colors.on_surface.default.hex}}",
|
"editorSuggestWidget.foreground": "{{colors.on_surface.default.hex}}",
|
||||||
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.default.hex}}",
|
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.default.hex}}",
|
||||||
"editorSuggestWidget.highlightForeground": "{{colors.primary.default.hex}}",
|
"editorSuggestWidget.highlightForeground": "{{colors.primary.default.hex}}",
|
||||||
"scrollbarSlider.background": "{{colors.outline.default.hex}}40",
|
"scrollbarSlider.background": "{{colors.on_surface_variant.default.hex}}50",
|
||||||
"scrollbarSlider.hoverBackground": "{{colors.outline.default.hex}}60",
|
"scrollbarSlider.hoverBackground": "{{colors.on_surface_variant.default.hex}}80",
|
||||||
"scrollbarSlider.activeBackground": "{{colors.outline.default.hex}}80",
|
"scrollbarSlider.activeBackground": "{{colors.on_surface_variant.default.hex}}AA",
|
||||||
"terminal.background": "{{colors.background.default.hex}}",
|
"terminal.background": "{{colors.background.default.hex}}",
|
||||||
"terminal.foreground": "{{colors.on_surface.default.hex}}",
|
"terminal.foreground": "{{colors.on_surface.default.hex}}",
|
||||||
"terminal.ansiBlack": "{{dank16.color0.default.hex}}",
|
"terminal.ansiBlack": "{{dank16.color0.default.hex}}",
|
||||||
@@ -138,79 +139,107 @@
|
|||||||
},
|
},
|
||||||
"tokenColors": [
|
"tokenColors": [
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["comment"],
|
||||||
"comment"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.outline.default.hex}}"
|
"foreground": "{{colors.outline.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["keyword"],
|
||||||
"keyword"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color5.default.hex}}"
|
"foreground": "{{dank16.color5.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["string"],
|
||||||
"string"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color2.default.hex}}"
|
"foreground": "{{dank16.color2.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["constant", "constant.language", "constant.numeric"],
|
||||||
"constant",
|
|
||||||
"number"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color12.default.hex}}"
|
"foreground": "{{dank16.color12.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["variable"],
|
||||||
"variable"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.on_surface.default.hex}}"
|
"foreground": "{{colors.on_surface.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["entity.name.function"],
|
||||||
"entity.name.function"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color4.default.hex}}"
|
"foreground": "{{dank16.color4.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["entity.name.class", "support.type"],
|
||||||
"entity.name.class",
|
|
||||||
"support.type"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.secondary.default.hex}}"
|
"foreground": "{{colors.secondary.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["invalid"],
|
||||||
"invalid"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.error.default.hex}}"
|
"foreground": "{{colors.error.default.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scope": [
|
"scope": ["markup.heading"],
|
||||||
"markup.heading"
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{colors.primary.default.hex}}",
|
"foreground": "{{colors.primary.default.hex}}",
|
||||||
"fontStyle": "bold"
|
"fontStyle": "bold"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.yaml", "punctuation.definition.block.sequence.item.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["source.yaml string.unquoted", "source.yaml string.quoted"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color3.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.yaml", "constant.language.null.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color12.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["punctuation.separator.key-value.mapping.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.toml", "support.type.property-name.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["string.quoted.single.basic.line.toml", "string.quoted.double.basic.line.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color2.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.toml", "constant.numeric.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color12.default.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["meta.object-literal.key", "support.type.property-name.json"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.default.hex}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"semanticTokenColors": {
|
"semanticTokenColors": {
|
||||||
|
|||||||
@@ -78,6 +78,7 @@
|
|||||||
"list.focusBackground": "{{colors.surface_container_high.light.hex}}",
|
"list.focusBackground": "{{colors.surface_container_high.light.hex}}",
|
||||||
"list.focusForeground": "{{colors.on_surface.light.hex}}",
|
"list.focusForeground": "{{colors.on_surface.light.hex}}",
|
||||||
"list.highlightForeground": "{{colors.primary.light.hex}}",
|
"list.highlightForeground": "{{colors.primary.light.hex}}",
|
||||||
|
"list.focusHighlightForeground": "{{colors.on_primary.light.hex}}",
|
||||||
"list.errorForeground": "{{colors.error.light.hex}}",
|
"list.errorForeground": "{{colors.error.light.hex}}",
|
||||||
"list.warningForeground": "{{colors.tertiary.light.hex}}",
|
"list.warningForeground": "{{colors.tertiary.light.hex}}",
|
||||||
"statusBar.background": "{{colors.surface_container.light.hex}}",
|
"statusBar.background": "{{colors.surface_container.light.hex}}",
|
||||||
@@ -154,9 +155,9 @@
|
|||||||
"breadcrumb.foreground": "{{colors.outline.light.hex}}",
|
"breadcrumb.foreground": "{{colors.outline.light.hex}}",
|
||||||
"breadcrumb.focusForeground": "{{colors.on_surface.light.hex}}",
|
"breadcrumb.focusForeground": "{{colors.on_surface.light.hex}}",
|
||||||
"breadcrumb.activeSelectionForeground": "{{colors.primary.light.hex}}",
|
"breadcrumb.activeSelectionForeground": "{{colors.primary.light.hex}}",
|
||||||
"scrollbarSlider.background": "{{colors.outline.light.hex}}40",
|
"scrollbarSlider.background": "{{colors.on_surface_variant.light.hex}}50",
|
||||||
"scrollbarSlider.hoverBackground": "{{colors.outline.light.hex}}60",
|
"scrollbarSlider.hoverBackground": "{{colors.on_surface_variant.light.hex}}80",
|
||||||
"scrollbarSlider.activeBackground": "{{colors.outline.light.hex}}80",
|
"scrollbarSlider.activeBackground": "{{colors.on_surface_variant.light.hex}}AA",
|
||||||
"menubar.selectionBackground": "{{colors.primary_container.light.hex}}",
|
"menubar.selectionBackground": "{{colors.primary_container.light.hex}}",
|
||||||
"menubar.selectionForeground": "{{colors.on_primary_container.light.hex}}",
|
"menubar.selectionForeground": "{{colors.on_primary_container.light.hex}}",
|
||||||
"menu.background": "{{colors.surface_container.light.hex}}",
|
"menu.background": "{{colors.surface_container.light.hex}}",
|
||||||
@@ -239,10 +240,46 @@
|
|||||||
"meta.object-literal.key",
|
"meta.object-literal.key",
|
||||||
"meta.property.object",
|
"meta.property.object",
|
||||||
"variable.other.property",
|
"variable.other.property",
|
||||||
"entity.name.tag.yaml"
|
"support.type.property-name.json"
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"foreground": "{{dank16.color4.light.hex}}"
|
"foreground": "{{colors.on_surface.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.yaml", "punctuation.definition.block.sequence.item.yaml", "punctuation.separator.key-value.mapping.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["source.yaml string.unquoted", "source.yaml string.quoted"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color3.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.yaml", "constant.language.null.yaml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color0.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["entity.name.tag.toml", "support.type.property-name.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{colors.on_surface.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["string.quoted.single.basic.line.toml", "string.quoted.double.basic.line.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color2.light.hex}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": ["constant.language.boolean.toml", "constant.numeric.toml"],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "{{dank16.color0.light.hex}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 متصل"
|
"%1 connected": "%1 متصل"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 نمایشگر"
|
"%1 display(s)": "%1 نمایشگر"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 ابزارک"
|
"%1 widgets": "%1 ابزارک"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(بدون نام)"
|
"(Unnamed)": "(بدون نام)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "محو شدن برای قفل صفحه"
|
"Fade to lock screen": "محو شدن برای قفل صفحه"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "فعالسازی پیکربندی ناموفق بود"
|
"Failed to activate configuration": "فعالسازی پیکربندی ناموفق بود"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "قبل از قفل شدن صفحه نمایش را با یک دوره زمانی قابل تنظیم به تدریج محو کن"
|
"Gradually fade the screen before locking with a configurable grace period": "قبل از قفل شدن صفحه نمایش را با یک دوره زمانی قابل تنظیم به تدریج محو کن"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "بازه زمانی نمودار"
|
"Graph Time Range": "بازه زمانی نمودار"
|
||||||
},
|
},
|
||||||
@@ -1677,7 +1689,7 @@
|
|||||||
"Grid Columns": "ستونهای جدول"
|
"Grid Columns": "ستونهای جدول"
|
||||||
},
|
},
|
||||||
"Group Workspace Apps": {
|
"Group Workspace Apps": {
|
||||||
"Group Workspace Apps": ""
|
"Group Workspace Apps": "گروهبندی برنامههای workspace"
|
||||||
},
|
},
|
||||||
"Group by App": {
|
"Group by App": {
|
||||||
"Group by App": "گروهبندی بر اساس برنامه"
|
"Group by App": "گروهبندی بر اساس برنامه"
|
||||||
@@ -1686,7 +1698,7 @@
|
|||||||
"Group multiple windows of the same app together with a window count indicator": "گروهبندی چندین پنجره از برنامه یکسان با نشانگر تعداد پنجرهها"
|
"Group multiple windows of the same app together with a window count indicator": "گروهبندی چندین پنجره از برنامه یکسان با نشانگر تعداد پنجرهها"
|
||||||
},
|
},
|
||||||
"Group repeated application icons in unfocused workspaces": {
|
"Group repeated application icons in unfocused workspaces": {
|
||||||
"Group repeated application icons in unfocused workspaces": ""
|
"Group repeated application icons in unfocused workspaces": "برنامههای تکرارشده در workspaceهای فوکوس نشده را گروهبندی کن"
|
||||||
},
|
},
|
||||||
"HDR (EDID)": {
|
"HDR (EDID)": {
|
||||||
"HDR (EDID)": "HDR (EDID)"
|
"HDR (EDID)": "HDR (EDID)"
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "قفلکردن قبل از تعلیق"
|
"Lock before suspend": "قفلکردن قبل از تعلیق"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "خروج"
|
"Log Out": "خروج"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "پیکربندی مانیتور"
|
"Monitor Configuration": "پیکربندی مانیتور"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "مانیتوری که تصویر پسزمینه آن رنگهای تم پویا را تعیین میکند"
|
"Monitor whose wallpaper drives dynamic theming colors": "مانیتوری که تصویر پسزمینه آن رنگهای تم پویا را تعیین میکند"
|
||||||
},
|
},
|
||||||
@@ -2946,7 +2964,7 @@
|
|||||||
"Scroll title if it doesn't fit in widget": "اگر عنوان در ابزارک جا نشد آن را حرکت بده"
|
"Scroll title if it doesn't fit in widget": "اگر عنوان در ابزارک جا نشد آن را حرکت بده"
|
||||||
},
|
},
|
||||||
"Scroll wheel behavior on media widget": {
|
"Scroll wheel behavior on media widget": {
|
||||||
"Scroll wheel behavior on media widget": ""
|
"Scroll wheel behavior on media widget": "رفتار چرخ اسکرول در ابزارک رسانه"
|
||||||
},
|
},
|
||||||
"Scrolling": {
|
"Scrolling": {
|
||||||
"Scrolling": "اسکرولینگ"
|
"Scrolling": "اسکرولینگ"
|
||||||
@@ -3219,7 +3237,7 @@
|
|||||||
"Show workspace index numbers in the top bar workspace switcher": "نمایش شماره شاخص workspace در تغییردهنده workspace نوار بالا"
|
"Show workspace index numbers in the top bar workspace switcher": "نمایش شماره شاخص workspace در تغییردهنده workspace نوار بالا"
|
||||||
},
|
},
|
||||||
"Show workspace name on horizontal bars, and first letter on vertical bars": {
|
"Show workspace name on horizontal bars, and first letter on vertical bars": {
|
||||||
"Show workspace name on horizontal bars, and first letter on vertical bars": ""
|
"Show workspace name on horizontal bars, and first letter on vertical bars": "نام workspace را در نوارهای افقی و اولین حرف را در نوارهای عمودی نمایش بده"
|
||||||
},
|
},
|
||||||
"Shows all running applications with focus indication": {
|
"Shows all running applications with focus indication": {
|
||||||
"Shows all running applications with focus indication": "همه برنامههای درحال اجرا را با نشانگر متمرکز نمایش میدهد"
|
"Shows all running applications with focus indication": "همه برنامههای درحال اجرا را با نشانگر متمرکز نمایش میدهد"
|
||||||
@@ -3252,10 +3270,10 @@
|
|||||||
"Sizing": "اندازهدهی"
|
"Sizing": "اندازهدهی"
|
||||||
},
|
},
|
||||||
"Smartcard Authentication": {
|
"Smartcard Authentication": {
|
||||||
"Smartcard Authentication": ""
|
"Smartcard Authentication": "احراز هویت با کارت هوشمند"
|
||||||
},
|
},
|
||||||
"Smartcard PIN": {
|
"Smartcard PIN": {
|
||||||
"Smartcard PIN": ""
|
"Smartcard PIN": "PIN کارت هوشمند"
|
||||||
},
|
},
|
||||||
"Some plugins require a newer version of DMS:": {
|
"Some plugins require a newer version of DMS:": {
|
||||||
"Some plugins require a newer version of DMS:": "برخی افزونهها نیازمند نسخه جدیدتر DMS هستند:"
|
"Some plugins require a newer version of DMS:": "برخی افزونهها نیازمند نسخه جدیدتر DMS هستند:"
|
||||||
@@ -3869,7 +3887,7 @@
|
|||||||
"Workspace Index Numbers": "شماره شاخص workspace"
|
"Workspace Index Numbers": "شماره شاخص workspace"
|
||||||
},
|
},
|
||||||
"Workspace Names": {
|
"Workspace Names": {
|
||||||
"Workspace Names": ""
|
"Workspace Names": "نام workspaceها"
|
||||||
},
|
},
|
||||||
"Workspace Padding": {
|
"Workspace Padding": {
|
||||||
"Workspace Padding": "فاصله درونی workspace"
|
"Workspace Padding": "فاصله درونی workspace"
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "هیچ تصویر پسزمینهای انتخاب نشده"
|
"No wallpaper selected": "هیچ تصویر پسزمینهای انتخاب نشده"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "رسمی"
|
"official": "رسمی"
|
||||||
},
|
},
|
||||||
@@ -4052,7 +4114,7 @@
|
|||||||
"Select Profile Image": "انتخاب تصویر نمایه"
|
"Select Profile Image": "انتخاب تصویر نمایه"
|
||||||
},
|
},
|
||||||
"read-only settings warning for NixOS home-manager users": {
|
"read-only settings warning for NixOS home-manager users": {
|
||||||
"Settings are read-only. Changes will not persist.": ""
|
"Settings are read-only. Changes will not persist.": "تنظیمات تنها قابل خواندن هستند. تغییرات حفظ نخواهند شد."
|
||||||
},
|
},
|
||||||
"registry theme description": {
|
"registry theme description": {
|
||||||
"Color theme from DMS registry": "رنگ تم از مخزن DMS"
|
"Color theme from DMS registry": "رنگ تم از مخزن DMS"
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype در دسترس نیست - wtype را برای پشتیبانی از الصاق نصب کنید"
|
"wtype not available - install wtype for paste support": "wtype در دسترس نیست - wtype را برای پشتیبانی از الصاق نصب کنید"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "نصب تنها از منابع معتبر"
|
"• Install only from trusted sources": "نصب تنها از منابع معتبر"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 מחובר/ים"
|
"%1 connected": "%1 מחובר/ים"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 מסך/מסכים"
|
"%1 display(s)": "%1 מסך/מסכים"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 ווידג׳טים"
|
"%1 widgets": "%1 ווידג׳טים"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(ללא שם)"
|
"(Unnamed)": "(ללא שם)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "דהייה למסך הנעילה"
|
"Fade to lock screen": "דהייה למסך הנעילה"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "הפעלת התצורה נכשלה"
|
"Failed to activate configuration": "הפעלת התצורה נכשלה"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "הפעל/י דהייה הדרגתית של המסך לפני הנעילה עם תקופת חסד הניתנת להגדרה"
|
"Gradually fade the screen before locking with a configurable grace period": "הפעל/י דהייה הדרגתית של המסך לפני הנעילה עם תקופת חסד הניתנת להגדרה"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": ""
|
"Graph Time Range": ""
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "נעל/י לפני השהיה"
|
"Lock before suspend": "נעל/י לפני השהיה"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "התנתק/י"
|
"Log Out": "התנתק/י"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": ""
|
"Monitor Configuration": ""
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "המסך שהרקע שלו קובע את צבעי ערכת הנושא הדינמית"
|
"Monitor whose wallpaper drives dynamic theming colors": "המסך שהרקע שלו קובע את צבעי ערכת הנושא הדינמית"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": ""
|
"No wallpaper selected": ""
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "רשמי"
|
"official": "רשמי"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": ""
|
"wtype not available - install wtype for paste support": ""
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• התקן/י רק ממקורות מהימנים"
|
"• Install only from trusted sources": "• התקן/י רק ממקורות מהימנים"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 csatlakoztatva"
|
"%1 connected": "%1 csatlakoztatva"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 kijelző"
|
"%1 display(s)": "%1 kijelző"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 widget"
|
"%1 widgets": "%1 widget"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(Névtelen)"
|
"(Unnamed)": "(Névtelen)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "Halványítás a zárolási képernyőre"
|
"Fade to lock screen": "Halványítás a zárolási képernyőre"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "A konfiguráció aktiválása sikertelen"
|
"Failed to activate configuration": "A konfiguráció aktiválása sikertelen"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "Fokozatosan halványítsa el a képernyőt a zárolás előtt egy konfigurálható türelmi idővel"
|
"Gradually fade the screen before locking with a configurable grace period": "Fokozatosan halványítsa el a képernyőt a zárolás előtt egy konfigurálható türelmi idővel"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "Grafikon időtartománya"
|
"Graph Time Range": "Grafikon időtartománya"
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "Zárolás felfüggesztés előtt"
|
"Lock before suspend": "Zárolás felfüggesztés előtt"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "Kijelentkezés"
|
"Log Out": "Kijelentkezés"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "Monitorkonfiguráció"
|
"Monitor Configuration": "Monitorkonfiguráció"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "Az a monitor, amelynek háttérképe meghatározza a dinamikus témaszíneket"
|
"Monitor whose wallpaper drives dynamic theming colors": "Az a monitor, amelynek háttérképe meghatározza a dinamikus témaszíneket"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "Nincs háttérkép kiválasztva"
|
"No wallpaper selected": "Nincs háttérkép kiválasztva"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "hivatalos"
|
"official": "hivatalos"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "A wtype nem elérhető - telepítsd a wtype csomagot a beillesztés támogatásához"
|
"wtype not available - install wtype for paste support": "A wtype nem elérhető - telepítsd a wtype csomagot a beillesztés támogatásához"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "Csak hivatalos forrásokból telepítsen"
|
"• Install only from trusted sources": "Csak hivatalos forrásokból telepítsen"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 connesso"
|
"%1 connected": "%1 connesso"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 schermo(i)"
|
"%1 display(s)": "%1 schermo(i)"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 widget"
|
"%1 widgets": "%1 widget"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(Senza nome)"
|
"(Unnamed)": "(Senza nome)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "Dissolvenza verso la schermata di blocco"
|
"Fade to lock screen": "Dissolvenza verso la schermata di blocco"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "Impossibile attivare configurazione"
|
"Failed to activate configuration": "Impossibile attivare configurazione"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "Dissolvi gradualmente lo schermo prima del blocco, con un periodo di tolleranza configurabile"
|
"Gradually fade the screen before locking with a configurable grace period": "Dissolvi gradualmente lo schermo prima del blocco, con un periodo di tolleranza configurabile"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "Intervallo Temporale del Grafico"
|
"Graph Time Range": "Intervallo Temporale del Grafico"
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "Blocca prima di sospendere"
|
"Lock before suspend": "Blocca prima di sospendere"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "Termina Sessione"
|
"Log Out": "Termina Sessione"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "Configurazione Monitor"
|
"Monitor Configuration": "Configurazione Monitor"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "Monitor il cui sfondo determina i colori del tema dinamico"
|
"Monitor whose wallpaper drives dynamic theming colors": "Monitor il cui sfondo determina i colori del tema dinamico"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "Nessuno sfondo selezionato"
|
"No wallpaper selected": "Nessuno sfondo selezionato"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "ufficiale"
|
"official": "ufficiale"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype non disponibile – installa wtype per il supporto all’incolla"
|
"wtype not available - install wtype for paste support": "wtype non disponibile – installa wtype per il supporto all’incolla"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• Installa solo da sorgenti fidate"
|
"• Install only from trusted sources": "• Installa solo da sorgenti fidate"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": ""
|
"%1 connected": ""
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 表示"
|
"%1 display(s)": "%1 表示"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 ウィジェット"
|
"%1 widgets": "%1 ウィジェット"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(名前なし)"
|
"(Unnamed)": "(名前なし)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": ""
|
"Fade to lock screen": ""
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "設定が適用できませんでした"
|
"Failed to activate configuration": "設定が適用できませんでした"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": ""
|
"Gradually fade the screen before locking with a configurable grace period": ""
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": ""
|
"Graph Time Range": ""
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "一時停止前にロック"
|
"Lock before suspend": "一時停止前にロック"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "ログアウト"
|
"Log Out": "ログアウト"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": ""
|
"Monitor Configuration": ""
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "ダイナミックテーマの色を駆動する壁紙をモニター"
|
"Monitor whose wallpaper drives dynamic theming colors": "ダイナミックテーマの色を駆動する壁紙をモニター"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": ""
|
"No wallpaper selected": ""
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "公式"
|
"official": "公式"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": ""
|
"wtype not available - install wtype for paste support": ""
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• 信頼できるソースからのみインストールする"
|
"• Install only from trusted sources": "• 信頼できるソースからのみインストールする"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 połączono"
|
"%1 connected": "%1 połączono"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 wyświetlaczy"
|
"%1 display(s)": "%1 wyświetlaczy"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 widżetów"
|
"%1 widgets": "%1 widżetów"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(Bez nazwy)"
|
"(Unnamed)": "(Bez nazwy)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "Wygaszanie do ekranu blokady"
|
"Fade to lock screen": "Wygaszanie do ekranu blokady"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "Nie udało się aktywować konfiguracji"
|
"Failed to activate configuration": "Nie udało się aktywować konfiguracji"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "Stopniowe wygaszanie ekranu przed zablokowaniem z konfigurowalnym czasem opóźnienia"
|
"Gradually fade the screen before locking with a configurable grace period": "Stopniowe wygaszanie ekranu przed zablokowaniem z konfigurowalnym czasem opóźnienia"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "Zakres czasowy wykresu"
|
"Graph Time Range": "Zakres czasowy wykresu"
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "Zablokuj przed wstrzymaniem"
|
"Lock before suspend": "Zablokuj przed wstrzymaniem"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "Wyloguj"
|
"Log Out": "Wyloguj"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "Konfiguracja monitora"
|
"Monitor Configuration": "Konfiguracja monitora"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "Monitor, którego tapeta steruje dynamicznymi kolorami motywu"
|
"Monitor whose wallpaper drives dynamic theming colors": "Monitor, którego tapeta steruje dynamicznymi kolorami motywu"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "Nie wybrano tapety"
|
"No wallpaper selected": "Nie wybrano tapety"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "oficjalny"
|
"official": "oficjalny"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype niedostępny - zainstaluj wtype dla wsparcia wklejania"
|
"wtype not available - install wtype for paste support": "wtype niedostępny - zainstaluj wtype dla wsparcia wklejania"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• Instaluj tylko z zaufanych źródeł"
|
"• Install only from trusted sources": "• Instaluj tylko z zaufanych źródeł"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 conectado(s)"
|
"%1 connected": "%1 conectado(s)"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 monitor(es)"
|
"%1 display(s)": "%1 monitor(es)"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 widgets"
|
"%1 widgets": "%1 widgets"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(Sem nome)"
|
"(Unnamed)": "(Sem nome)"
|
||||||
},
|
},
|
||||||
@@ -36,7 +42,7 @@
|
|||||||
"0 = square corners": "0 = cantos quadrados"
|
"0 = square corners": "0 = cantos quadrados"
|
||||||
},
|
},
|
||||||
"1 day": {
|
"1 day": {
|
||||||
"1 day": ""
|
"1 day": "1 dia"
|
||||||
},
|
},
|
||||||
"1 event": {
|
"1 event": {
|
||||||
"1 event": "1 evento"
|
"1 event": "1 evento"
|
||||||
@@ -57,7 +63,7 @@
|
|||||||
"10-bit Color": ""
|
"10-bit Color": ""
|
||||||
},
|
},
|
||||||
"14 days": {
|
"14 days": {
|
||||||
"14 days": ""
|
"14 days": "14 dias"
|
||||||
},
|
},
|
||||||
"15 seconds": {
|
"15 seconds": {
|
||||||
"15 seconds": "15 segundos"
|
"15 seconds": "15 segundos"
|
||||||
@@ -78,13 +84,13 @@
|
|||||||
"270°": ""
|
"270°": ""
|
||||||
},
|
},
|
||||||
"3 days": {
|
"3 days": {
|
||||||
"3 days": ""
|
"3 days": "3 dias"
|
||||||
},
|
},
|
||||||
"3 seconds": {
|
"3 seconds": {
|
||||||
"3 seconds": "3 segundos"
|
"3 seconds": "3 segundos"
|
||||||
},
|
},
|
||||||
"30 days": {
|
"30 days": {
|
||||||
"30 days": ""
|
"30 days": "30 dias"
|
||||||
},
|
},
|
||||||
"30 seconds": {
|
"30 seconds": {
|
||||||
"30 seconds": "30 segundos"
|
"30 seconds": "30 segundos"
|
||||||
@@ -93,19 +99,19 @@
|
|||||||
"3rd party": "Terceiros"
|
"3rd party": "Terceiros"
|
||||||
},
|
},
|
||||||
"5 minutes": {
|
"5 minutes": {
|
||||||
"5 minutes": ""
|
"5 minutes": "5 minutos"
|
||||||
},
|
},
|
||||||
"5 seconds": {
|
"5 seconds": {
|
||||||
"5 seconds": ""
|
"5 seconds": "5 segundos"
|
||||||
},
|
},
|
||||||
"7 days": {
|
"7 days": {
|
||||||
"7 days": ""
|
"7 days": "7 dias"
|
||||||
},
|
},
|
||||||
"8 seconds": {
|
"8 seconds": {
|
||||||
"8 seconds": ""
|
"8 seconds": "8 segundos"
|
||||||
},
|
},
|
||||||
"90 days": {
|
"90 days": {
|
||||||
"90 days": ""
|
"90 days": "90 dias"
|
||||||
},
|
},
|
||||||
"90°": {
|
"90°": {
|
||||||
"90°": ""
|
"90°": ""
|
||||||
@@ -195,7 +201,7 @@
|
|||||||
"Adjust the number of columns in grid view mode.": "Ajusta o número de colunas no modo de visualização em grade"
|
"Adjust the number of columns in grid view mode.": "Ajusta o número de colunas no modo de visualização em grade"
|
||||||
},
|
},
|
||||||
"Advanced": {
|
"Advanced": {
|
||||||
"Advanced": ""
|
"Advanced": "Avançado"
|
||||||
},
|
},
|
||||||
"Afternoon": {
|
"Afternoon": {
|
||||||
"Afternoon": "Tarde"
|
"Afternoon": "Tarde"
|
||||||
@@ -216,7 +222,7 @@
|
|||||||
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Voltar • F1/I: Informações de Arquivo • F10: Ajuda • Esc: Fechar"
|
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Voltar • F1/I: Informações de Arquivo • F10: Ajuda • Esc: Fechar"
|
||||||
},
|
},
|
||||||
"Always Show Percentage": {
|
"Always Show Percentage": {
|
||||||
"Always Show Percentage": ""
|
"Always Show Percentage": "Sempre Mostrar Porcentagem"
|
||||||
},
|
},
|
||||||
"Always on icons": {
|
"Always on icons": {
|
||||||
"Always on icons": "Ícones sempre ligados"
|
"Always on icons": "Ícones sempre ligados"
|
||||||
@@ -231,7 +237,7 @@
|
|||||||
"Always show when there's only one connected display": ""
|
"Always show when there's only one connected display": ""
|
||||||
},
|
},
|
||||||
"Amount": {
|
"Amount": {
|
||||||
"Amount": ""
|
"Amount": "Quantidade"
|
||||||
},
|
},
|
||||||
"Analog": {
|
"Analog": {
|
||||||
"Analog": ""
|
"Analog": ""
|
||||||
@@ -300,7 +306,7 @@
|
|||||||
"Audio Output Switch": ""
|
"Audio Output Switch": ""
|
||||||
},
|
},
|
||||||
"Audio Visualizer": {
|
"Audio Visualizer": {
|
||||||
"Audio Visualizer": ""
|
"Audio Visualizer": "Visualizador de Áudio"
|
||||||
},
|
},
|
||||||
"Audio volume control": {
|
"Audio volume control": {
|
||||||
"Audio volume control": ""
|
"Audio volume control": ""
|
||||||
@@ -348,7 +354,7 @@
|
|||||||
"Auto-Clear After": ""
|
"Auto-Clear After": ""
|
||||||
},
|
},
|
||||||
"Auto-close Niri overview when launching apps.": {
|
"Auto-close Niri overview when launching apps.": {
|
||||||
"Auto-close Niri overview when launching apps.": ""
|
"Auto-close Niri overview when launching apps.": "Fechar automaticamente overview do niri ao lançar aplicativos."
|
||||||
},
|
},
|
||||||
"Auto-hide": {
|
"Auto-hide": {
|
||||||
"Auto-hide": "Esconder Automaticamente"
|
"Auto-hide": "Esconder Automaticamente"
|
||||||
@@ -444,7 +450,7 @@
|
|||||||
"Battery level and power management": "Nível de bateria e manejamento de energia"
|
"Battery level and power management": "Nível de bateria e manejamento de energia"
|
||||||
},
|
},
|
||||||
"Behavior": {
|
"Behavior": {
|
||||||
"Behavior": ""
|
"Behavior": "Comportamento"
|
||||||
},
|
},
|
||||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Vincular o bloqueio de tela aos sinais do DBus do loginctl. Desative se estiver usando um bloqueio de tela externo"
|
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Vincular o bloqueio de tela aos sinais do DBus do loginctl. Desative se estiver usando um bloqueio de tela externo"
|
||||||
@@ -579,7 +585,7 @@
|
|||||||
"Capacity": "Capacidade"
|
"Capacity": "Capacidade"
|
||||||
},
|
},
|
||||||
"Caps Lock": {
|
"Caps Lock": {
|
||||||
"Caps Lock": ""
|
"Caps Lock": "Caps Lock"
|
||||||
},
|
},
|
||||||
"Caps Lock Indicator": {
|
"Caps Lock Indicator": {
|
||||||
"Caps Lock Indicator": "Indicador de Caps Lock"
|
"Caps Lock Indicator": "Indicador de Caps Lock"
|
||||||
@@ -660,10 +666,10 @@
|
|||||||
"Clear All Jobs": "Limpar Todos os Trabalhos"
|
"Clear All Jobs": "Limpar Todos os Trabalhos"
|
||||||
},
|
},
|
||||||
"Clear all history when server starts": {
|
"Clear all history when server starts": {
|
||||||
"Clear all history when server starts": ""
|
"Clear all history when server starts": "Limpar todo o histórico quando o servidor iniciar"
|
||||||
},
|
},
|
||||||
"Clear at Startup": {
|
"Clear at Startup": {
|
||||||
"Clear at Startup": ""
|
"Clear at Startup": "Limpar ao Iniciar"
|
||||||
},
|
},
|
||||||
"Click 'Setup' to create dms/binds.kdl and add include to config.kdl.": {
|
"Click 'Setup' to create dms/binds.kdl and add include to config.kdl.": {
|
||||||
"Click 'Setup' to create dms/binds.kdl and add include to config.kdl.": ""
|
"Click 'Setup' to create dms/binds.kdl and add include to config.kdl.": ""
|
||||||
@@ -681,7 +687,7 @@
|
|||||||
"Click to capture": "Clique para capturar"
|
"Click to capture": "Clique para capturar"
|
||||||
},
|
},
|
||||||
"Clipboard": {
|
"Clipboard": {
|
||||||
"Clipboard": ""
|
"Clipboard": "Área de transferência"
|
||||||
},
|
},
|
||||||
"Clipboard History": {
|
"Clipboard History": {
|
||||||
"Clipboard History": "Histórico da Área de Transferência"
|
"Clipboard History": "Histórico da Área de Transferência"
|
||||||
@@ -690,10 +696,10 @@
|
|||||||
"Clipboard Manager": "Gerenciador da Área de Transferência"
|
"Clipboard Manager": "Gerenciador da Área de Transferência"
|
||||||
},
|
},
|
||||||
"Clipboard service not available": {
|
"Clipboard service not available": {
|
||||||
"Clipboard service not available": ""
|
"Clipboard service not available": "Serviço de área de transferência não disponível"
|
||||||
},
|
},
|
||||||
"Clipboard works but nothing saved to disk": {
|
"Clipboard works but nothing saved to disk": {
|
||||||
"Clipboard works but nothing saved to disk": ""
|
"Clipboard works but nothing saved to disk": "A área de transferência funciona mas nada é salvo no disco"
|
||||||
},
|
},
|
||||||
"Clock": {
|
"Clock": {
|
||||||
"Clock": "Relógio"
|
"Clock": "Relógio"
|
||||||
@@ -708,7 +714,7 @@
|
|||||||
"Close Overview on Launch": "Fechar Overview ao Lançar Aplicativos"
|
"Close Overview on Launch": "Fechar Overview ao Lançar Aplicativos"
|
||||||
},
|
},
|
||||||
"Color": {
|
"Color": {
|
||||||
"Color": ""
|
"Color": "Cor"
|
||||||
},
|
},
|
||||||
"Color Gamut": {
|
"Color Gamut": {
|
||||||
"Color Gamut": ""
|
"Color Gamut": ""
|
||||||
@@ -717,7 +723,7 @@
|
|||||||
"Color Management": ""
|
"Color Management": ""
|
||||||
},
|
},
|
||||||
"Color Mode": {
|
"Color Mode": {
|
||||||
"Color Mode": ""
|
"Color Mode": "Modo de Cor"
|
||||||
},
|
},
|
||||||
"Color Override": {
|
"Color Override": {
|
||||||
"Color Override": "Sobrescrever Cor"
|
"Color Override": "Sobrescrever Cor"
|
||||||
@@ -726,7 +732,7 @@
|
|||||||
"Color Picker": "Seletor de Cores"
|
"Color Picker": "Seletor de Cores"
|
||||||
},
|
},
|
||||||
"Color Temperature": {
|
"Color Temperature": {
|
||||||
"Color Temperature": ""
|
"Color Temperature": "Temperatura da Cor"
|
||||||
},
|
},
|
||||||
"Color displayed on monitors without the lock screen": {
|
"Color displayed on monitors without the lock screen": {
|
||||||
"Color displayed on monitors without the lock screen": ""
|
"Color displayed on monitors without the lock screen": ""
|
||||||
@@ -840,7 +846,7 @@
|
|||||||
"Controls opacity of all popouts, modals, and their content layers": ""
|
"Controls opacity of all popouts, modals, and their content layers": ""
|
||||||
},
|
},
|
||||||
"Cooldown": {
|
"Cooldown": {
|
||||||
"Cooldown": ""
|
"Cooldown": "Tempo de espera"
|
||||||
},
|
},
|
||||||
"Copied to clipboard": {
|
"Copied to clipboard": {
|
||||||
"Copied to clipboard": "Copiado para a área de transferência"
|
"Copied to clipboard": "Copiado para a área de transferência"
|
||||||
@@ -855,7 +861,7 @@
|
|||||||
"Copy Process Name": "Copiar Nome do Processo"
|
"Copy Process Name": "Copiar Nome do Processo"
|
||||||
},
|
},
|
||||||
"Corner Radius": {
|
"Corner Radius": {
|
||||||
"Corner Radius": ""
|
"Corner Radius": "Arredondamento"
|
||||||
},
|
},
|
||||||
"Corner Radius Override": {
|
"Corner Radius Override": {
|
||||||
"Corner Radius Override": "Sobrescrever Arredondamento"
|
"Corner Radius Override": "Sobrescrever Arredondamento"
|
||||||
@@ -882,13 +888,13 @@
|
|||||||
"Current Items": "Itens Atuais"
|
"Current Items": "Itens Atuais"
|
||||||
},
|
},
|
||||||
"Current Period": {
|
"Current Period": {
|
||||||
"Current Period": ""
|
"Current Period": "Período Atual"
|
||||||
},
|
},
|
||||||
"Current Status": {
|
"Current Status": {
|
||||||
"Current Status": ""
|
"Current Status": "Status Atual"
|
||||||
},
|
},
|
||||||
"Current Temp": {
|
"Current Temp": {
|
||||||
"Current Temp": ""
|
"Current Temp": "Temperatura Atual"
|
||||||
},
|
},
|
||||||
"Current Weather": {
|
"Current Weather": {
|
||||||
"Current Weather": "Clima Atual"
|
"Current Weather": "Clima Atual"
|
||||||
@@ -960,7 +966,7 @@
|
|||||||
"DMS out of date": "DMS desatualizado"
|
"DMS out of date": "DMS desatualizado"
|
||||||
},
|
},
|
||||||
"DMS service is not connected. Clipboard settings are unavailable.": {
|
"DMS service is not connected. Clipboard settings are unavailable.": {
|
||||||
"DMS service is not connected. Clipboard settings are unavailable.": ""
|
"DMS service is not connected. Clipboard settings are unavailable.": "Serviço do DMS não está conectado. Configurações de área de transferência não estão disponíveis."
|
||||||
},
|
},
|
||||||
"DMS shell actions (launcher, clipboard, etc.)": {
|
"DMS shell actions (launcher, clipboard, etc.)": {
|
||||||
"DMS shell actions (launcher, clipboard, etc.)": "Ações do shell do DMS (lançador, área de transferência, etc.)"
|
"DMS shell actions (launcher, clipboard, etc.)": "Ações do shell do DMS (lançador, área de transferência, etc.)"
|
||||||
@@ -1086,16 +1092,16 @@
|
|||||||
"Disable Autoconnect": "Desativar conexão automática"
|
"Disable Autoconnect": "Desativar conexão automática"
|
||||||
},
|
},
|
||||||
"Disable Clipboard Manager": {
|
"Disable Clipboard Manager": {
|
||||||
"Disable Clipboard Manager": ""
|
"Disable Clipboard Manager": "Desativar Gerenciador de Área de Transferência"
|
||||||
},
|
},
|
||||||
"Disable History Persistence": {
|
"Disable History Persistence": {
|
||||||
"Disable History Persistence": ""
|
"Disable History Persistence": "Desativar Persistência de Histórico"
|
||||||
},
|
},
|
||||||
"Disable Output": {
|
"Disable Output": {
|
||||||
"Disable Output": ""
|
"Disable Output": ""
|
||||||
},
|
},
|
||||||
"Disable clipboard manager entirely (requires restart)": {
|
"Disable clipboard manager entirely (requires restart)": {
|
||||||
"Disable clipboard manager entirely (requires restart)": ""
|
"Disable clipboard manager entirely (requires restart)": "Desativa o gerenciador de área de transferência inteiramente (requer reinício)"
|
||||||
},
|
},
|
||||||
"Disabled": {
|
"Disabled": {
|
||||||
"Disabled": "Desativado"
|
"Disabled": "Desativado"
|
||||||
@@ -1164,7 +1170,7 @@
|
|||||||
"Display seconds in the clock": ""
|
"Display seconds in the clock": ""
|
||||||
},
|
},
|
||||||
"Display the power system menu": {
|
"Display the power system menu": {
|
||||||
"Display the power system menu": ""
|
"Display the power system menu": "Mostra o menu de energia do sistema"
|
||||||
},
|
},
|
||||||
"Display volume and brightness percentage values in OSD popups": {
|
"Display volume and brightness percentage values in OSD popups": {
|
||||||
"Display volume and brightness percentage values in OSD popups": ""
|
"Display volume and brightness percentage values in OSD popups": ""
|
||||||
@@ -1284,16 +1290,16 @@
|
|||||||
"Enable loginctl lock integration": "Ativar integração de bloqueio do loginctl"
|
"Enable loginctl lock integration": "Ativar integração de bloqueio do loginctl"
|
||||||
},
|
},
|
||||||
"Enable password field display on the lock screen window": {
|
"Enable password field display on the lock screen window": {
|
||||||
"Show Password Field": ""
|
"Show Password Field": "Mostrar Campo de Senha"
|
||||||
},
|
},
|
||||||
"Enable power action icon on the lock screen window": {
|
"Enable power action icon on the lock screen window": {
|
||||||
"Show Power Actions": ""
|
"Show Power Actions": "Mostrar Ações de Energia"
|
||||||
},
|
},
|
||||||
"Enable profile image display on the lock screen window": {
|
"Enable profile image display on the lock screen window": {
|
||||||
"Show Profile Image": ""
|
"Show Profile Image": "Mostrar Imagem de Perfil"
|
||||||
},
|
},
|
||||||
"Enable system date display on the lock screen window": {
|
"Enable system date display on the lock screen window": {
|
||||||
"Show System Date": ""
|
"Show System Date": "Mostrar Data do Sistema"
|
||||||
},
|
},
|
||||||
"Enable system status icons on the lock screen window": {
|
"Enable system status icons on the lock screen window": {
|
||||||
"Show System Icons": ""
|
"Show System Icons": ""
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "Esmaecer para a tela de bloqueio"
|
"Fade to lock screen": "Esmaecer para a tela de bloqueio"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "Erro ao ativar configuração"
|
"Failed to activate configuration": "Erro ao ativar configuração"
|
||||||
},
|
},
|
||||||
@@ -1395,7 +1404,7 @@
|
|||||||
"Failed to connect to %1": ""
|
"Failed to connect to %1": ""
|
||||||
},
|
},
|
||||||
"Failed to copy entry": {
|
"Failed to copy entry": {
|
||||||
"Failed to copy entry": ""
|
"Failed to copy entry": "Falha ao copiar entrada"
|
||||||
},
|
},
|
||||||
"Failed to create printer": {
|
"Failed to create printer": {
|
||||||
"Failed to create printer": "Falha ao criar impressora"
|
"Failed to create printer": "Falha ao criar impressora"
|
||||||
@@ -1446,7 +1455,7 @@
|
|||||||
"Failed to load VPN config": "Falha ao carregar configuração da VPN"
|
"Failed to load VPN config": "Falha ao carregar configuração da VPN"
|
||||||
},
|
},
|
||||||
"Failed to load clipboard configuration.": {
|
"Failed to load clipboard configuration.": {
|
||||||
"Failed to load clipboard configuration.": ""
|
"Failed to load clipboard configuration.": "Falha ao carregar configuração de área de transferência."
|
||||||
},
|
},
|
||||||
"Failed to move job": {
|
"Failed to move job": {
|
||||||
"Failed to move job": "Falha ao mover trabalho"
|
"Failed to move job": "Falha ao mover trabalho"
|
||||||
@@ -1482,7 +1491,7 @@
|
|||||||
"Failed to resume printer": "Falha ao resumir impressora"
|
"Failed to resume printer": "Falha ao resumir impressora"
|
||||||
},
|
},
|
||||||
"Failed to save clipboard setting": {
|
"Failed to save clipboard setting": {
|
||||||
"Failed to save clipboard setting": ""
|
"Failed to save clipboard setting": "Falha ao salvar configuração de área de transferência"
|
||||||
},
|
},
|
||||||
"Failed to save keybind": {
|
"Failed to save keybind": {
|
||||||
"Failed to save keybind": "Falha ao salvar atalho"
|
"Failed to save keybind": "Falha ao salvar atalho"
|
||||||
@@ -1581,7 +1590,7 @@
|
|||||||
"Focused Window": "Janela Focada"
|
"Focused Window": "Janela Focada"
|
||||||
},
|
},
|
||||||
"Follow focus": {
|
"Follow focus": {
|
||||||
"Follow focus": ""
|
"Follow focus": "Seguir foco"
|
||||||
},
|
},
|
||||||
"Font Family": {
|
"Font Family": {
|
||||||
"Font Family": "Família da Fonte"
|
"Font Family": "Família da Fonte"
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "Gradualmente esmaecer a tela antes de bloquear com um período de tolerância configurável"
|
"Gradually fade the screen before locking with a configurable grace period": "Gradualmente esmaecer a tela antes de bloquear com um período de tolerância configurável"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": ""
|
"Graph Time Range": ""
|
||||||
},
|
},
|
||||||
@@ -1728,7 +1740,7 @@
|
|||||||
"High-fidelity palette that preserves source hues.": "Paleta de alta fidelidade que preserva tons da fonte."
|
"High-fidelity palette that preserves source hues.": "Paleta de alta fidelidade que preserva tons da fonte."
|
||||||
},
|
},
|
||||||
"History Settings": {
|
"History Settings": {
|
||||||
"History Settings": ""
|
"History Settings": "Configurações do Histórico"
|
||||||
},
|
},
|
||||||
"Hold Duration": {
|
"Hold Duration": {
|
||||||
"Hold Duration": "Duração do Pressionamento"
|
"Hold Duration": "Duração do Pressionamento"
|
||||||
@@ -1740,7 +1752,7 @@
|
|||||||
"Hold to Confirm Power Actions": "Manter Pressionado para Confirmar Ações de Energia"
|
"Hold to Confirm Power Actions": "Manter Pressionado para Confirmar Ações de Energia"
|
||||||
},
|
},
|
||||||
"Hold to confirm (%1 ms)": {
|
"Hold to confirm (%1 ms)": {
|
||||||
"Hold to confirm (%1 ms)": ""
|
"Hold to confirm (%1 ms)": "Segure para confirmar (%1 ms)"
|
||||||
},
|
},
|
||||||
"Hold to confirm (%1s)": {
|
"Hold to confirm (%1s)": {
|
||||||
"Hold to confirm (%1s)": "Manter pressionado para confirmar (%1s)"
|
"Hold to confirm (%1s)": "Manter pressionado para confirmar (%1s)"
|
||||||
@@ -1791,13 +1803,13 @@
|
|||||||
"Idle monitoring not supported - requires newer Quickshell version": "Monitoramento de inatividade não disponível – requer versão mais recente do Quickshell"
|
"Idle monitoring not supported - requires newer Quickshell version": "Monitoramento de inatividade não disponível – requer versão mais recente do Quickshell"
|
||||||
},
|
},
|
||||||
"If the field is hidden, it will appear as soon as a key is pressed.": {
|
"If the field is hidden, it will appear as soon as a key is pressed.": {
|
||||||
"If the field is hidden, it will appear as soon as a key is pressed.": ""
|
"If the field is hidden, it will appear as soon as a key is pressed.": "Se o campo está escondido, ele aparecerá no momento que uma tecla e pressionada."
|
||||||
},
|
},
|
||||||
"Image": {
|
"Image": {
|
||||||
"Image": "Imagem"
|
"Image": "Imagem"
|
||||||
},
|
},
|
||||||
"Image copied to clipboard": {
|
"Image copied to clipboard": {
|
||||||
"Image copied to clipboard": ""
|
"Image copied to clipboard": "Imagem copiada para a área de trabalho"
|
||||||
},
|
},
|
||||||
"Import": {
|
"Import": {
|
||||||
"Import": "Importar"
|
"Import": "Importar"
|
||||||
@@ -1989,14 +2001,17 @@
|
|||||||
"Lock Screen Format": "Formato da Tela de Bloqueio"
|
"Lock Screen Format": "Formato da Tela de Bloqueio"
|
||||||
},
|
},
|
||||||
"Lock Screen behaviour": {
|
"Lock Screen behaviour": {
|
||||||
"Lock Screen behaviour": ""
|
"Lock Screen behaviour": "Comportamento da Tela de Bloqueio"
|
||||||
},
|
},
|
||||||
"Lock Screen layout": {
|
"Lock Screen layout": {
|
||||||
"Lock Screen layout": ""
|
"Lock Screen layout": "Layout da Tela de Bloqueio"
|
||||||
},
|
},
|
||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "Bloquear antes de suspender"
|
"Lock before suspend": "Bloquear antes de suspender"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "Sair"
|
"Log Out": "Sair"
|
||||||
},
|
},
|
||||||
@@ -2061,25 +2076,25 @@
|
|||||||
"Matugen Target Monitor": "Monitor-alvo do Matugen"
|
"Matugen Target Monitor": "Monitor-alvo do Matugen"
|
||||||
},
|
},
|
||||||
"Matugen Templates": {
|
"Matugen Templates": {
|
||||||
"Matugen Templates": ""
|
"Matugen Templates": "Templates do Matugen"
|
||||||
},
|
},
|
||||||
"Max apps to show": {
|
"Max apps to show": {
|
||||||
"Max apps to show": "Máximo de apps para mostrar"
|
"Max apps to show": "Máximo de apps para mostrar"
|
||||||
},
|
},
|
||||||
"Maximize Detection": {
|
"Maximize Detection": {
|
||||||
"Maximize Detection": ""
|
"Maximize Detection": "Detecção de Maximizado"
|
||||||
},
|
},
|
||||||
"Maximum Entry Size": {
|
"Maximum Entry Size": {
|
||||||
"Maximum Entry Size": ""
|
"Maximum Entry Size": "Tamanho Máximo de Entrada"
|
||||||
},
|
},
|
||||||
"Maximum History": {
|
"Maximum History": {
|
||||||
"Maximum History": ""
|
"Maximum History": "Histórico Máximo"
|
||||||
},
|
},
|
||||||
"Maximum number of clipboard entries to keep": {
|
"Maximum number of clipboard entries to keep": {
|
||||||
"Maximum number of clipboard entries to keep": ""
|
"Maximum number of clipboard entries to keep": "Número máximo de entradas da área de transferência para guardar"
|
||||||
},
|
},
|
||||||
"Maximum size per clipboard entry": {
|
"Maximum size per clipboard entry": {
|
||||||
"Maximum size per clipboard entry": ""
|
"Maximum size per clipboard entry": "Tamanho máximo por entrada da área de transferência"
|
||||||
},
|
},
|
||||||
"Media": {
|
"Media": {
|
||||||
"Media": "Mídia"
|
"Media": "Mídia"
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": ""
|
"Monitor Configuration": ""
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "Monitor o qual papel de parede controla cores de tema dinâmicas"
|
"Monitor whose wallpaper drives dynamic theming colors": "Monitor o qual papel de parede controla cores de tema dinâmicas"
|
||||||
},
|
},
|
||||||
@@ -2229,7 +2247,7 @@
|
|||||||
"Network download and upload speed display": "Monitor de velocidades de download e upload da rede"
|
"Network download and upload speed display": "Monitor de velocidades de download e upload da rede"
|
||||||
},
|
},
|
||||||
"Never": {
|
"Never": {
|
||||||
"Never": ""
|
"Never": "Nunca"
|
||||||
},
|
},
|
||||||
"New": {
|
"New": {
|
||||||
"New": "Novo"
|
"New": "Novo"
|
||||||
@@ -2247,7 +2265,7 @@
|
|||||||
"New York, NY": "Nova York, NY"
|
"New York, NY": "Nova York, NY"
|
||||||
},
|
},
|
||||||
"Next Transition": {
|
"Next Transition": {
|
||||||
"Next Transition": ""
|
"Next Transition": "Próxima Transição"
|
||||||
},
|
},
|
||||||
"Night": {
|
"Night": {
|
||||||
"Night": "Noite"
|
"Night": "Noite"
|
||||||
@@ -2259,7 +2277,7 @@
|
|||||||
"Night Temperature": "Temperatura Noturna"
|
"Night Temperature": "Temperatura Noturna"
|
||||||
},
|
},
|
||||||
"Niri Integration": {
|
"Niri Integration": {
|
||||||
"Niri Integration": ""
|
"Niri Integration": "Integração com niri"
|
||||||
},
|
},
|
||||||
"Niri Layout Overrides": {
|
"Niri Layout Overrides": {
|
||||||
"Niri Layout Overrides": ""
|
"Niri Layout Overrides": ""
|
||||||
@@ -2280,7 +2298,7 @@
|
|||||||
"No Bluetooth adapter found": "Adaptador Bluetooth não encontrado"
|
"No Bluetooth adapter found": "Adaptador Bluetooth não encontrado"
|
||||||
},
|
},
|
||||||
"No GPU detected": {
|
"No GPU detected": {
|
||||||
"No GPU detected": ""
|
"No GPU detected": "Nenhuma GPU detectada"
|
||||||
},
|
},
|
||||||
"No Media": {
|
"No Media": {
|
||||||
"No Media": "Sem Mídia"
|
"No Media": "Sem Mídia"
|
||||||
@@ -2367,7 +2385,7 @@
|
|||||||
"Normal": ""
|
"Normal": ""
|
||||||
},
|
},
|
||||||
"Normal Font": {
|
"Normal Font": {
|
||||||
"Normal Font": ""
|
"Normal Font": "Fonte Normal"
|
||||||
},
|
},
|
||||||
"Normal Priority": {
|
"Normal Priority": {
|
||||||
"Normal Priority": "Prioridade Normal"
|
"Normal Priority": "Prioridade Normal"
|
||||||
@@ -2469,7 +2487,7 @@
|
|||||||
"Optional location": "Localização opcional"
|
"Optional location": "Localização opcional"
|
||||||
},
|
},
|
||||||
"Options": {
|
"Options": {
|
||||||
"Options": ""
|
"Options": "Opções"
|
||||||
},
|
},
|
||||||
"Other": {
|
"Other": {
|
||||||
"Other": "Outro"
|
"Other": "Outro"
|
||||||
@@ -2493,7 +2511,7 @@
|
|||||||
"Override": "Sobrescrever"
|
"Override": "Sobrescrever"
|
||||||
},
|
},
|
||||||
"Override Corner Radius": {
|
"Override Corner Radius": {
|
||||||
"Override Corner Radius": ""
|
"Override Corner Radius": "Sobrescrever Arredondamento"
|
||||||
},
|
},
|
||||||
"Override Gaps": {
|
"Override Gaps": {
|
||||||
"Override Gaps": ""
|
"Override Gaps": ""
|
||||||
@@ -2619,7 +2637,7 @@
|
|||||||
"Plugins": "Plugins"
|
"Plugins": "Plugins"
|
||||||
},
|
},
|
||||||
"Pointer": {
|
"Pointer": {
|
||||||
"Pointer": ""
|
"Pointer": "Ponteiro"
|
||||||
},
|
},
|
||||||
"Popup Position": {
|
"Popup Position": {
|
||||||
"Popup Position": "Posição do Popup"
|
"Popup Position": "Posição do Popup"
|
||||||
@@ -2634,7 +2652,7 @@
|
|||||||
"Possible Override Conflicts": ""
|
"Possible Override Conflicts": ""
|
||||||
},
|
},
|
||||||
"Power": {
|
"Power": {
|
||||||
"Power": ""
|
"Power": "Energia"
|
||||||
},
|
},
|
||||||
"Power & Security": {
|
"Power & Security": {
|
||||||
"Power & Security": "Energia & Segurança"
|
"Power & Security": "Energia & Segurança"
|
||||||
@@ -2655,7 +2673,7 @@
|
|||||||
"Power Options": "Opções de Energia"
|
"Power Options": "Opções de Energia"
|
||||||
},
|
},
|
||||||
"Power Profile": {
|
"Power Profile": {
|
||||||
"Power Profile": ""
|
"Power Profile": "Perfil de Energia"
|
||||||
},
|
},
|
||||||
"Power Profile Degradation": {
|
"Power Profile Degradation": {
|
||||||
"Power Profile Degradation": "Degradação do Perfil de Energia"
|
"Power Profile Degradation": "Degradação do Perfil de Energia"
|
||||||
@@ -2664,7 +2682,7 @@
|
|||||||
"Power profile management available": ""
|
"Power profile management available": ""
|
||||||
},
|
},
|
||||||
"Power source": {
|
"Power source": {
|
||||||
"Power source": ""
|
"Power source": "Fonte de energia"
|
||||||
},
|
},
|
||||||
"Precipitation Chance": {
|
"Precipitation Chance": {
|
||||||
"Precipitation Chance": "Chance de Precipitação"
|
"Precipitation Chance": "Chance de Precipitação"
|
||||||
@@ -2790,7 +2808,7 @@
|
|||||||
"Remove": "Remover"
|
"Remove": "Remover"
|
||||||
},
|
},
|
||||||
"Remove gaps and border when windows are maximized": {
|
"Remove gaps and border when windows are maximized": {
|
||||||
"Remove gaps and border when windows are maximized": ""
|
"Remove gaps and border when windows are maximized": "Remover espaçámentos e borda quando janelas estão maximizadas"
|
||||||
},
|
},
|
||||||
"Report": {
|
"Report": {
|
||||||
"Report": "Relatório"
|
"Report": "Relatório"
|
||||||
@@ -2868,7 +2886,7 @@
|
|||||||
"Rounded corners for windows": ""
|
"Rounded corners for windows": ""
|
||||||
},
|
},
|
||||||
"Run DMS Templates": {
|
"Run DMS Templates": {
|
||||||
"Run DMS Templates": ""
|
"Run DMS Templates": "Rodar templates do DMS"
|
||||||
},
|
},
|
||||||
"Run User Templates": {
|
"Run User Templates": {
|
||||||
"Run User Templates": "Executar Templates do Usuário"
|
"Run User Templates": "Executar Templates do Usuário"
|
||||||
@@ -3273,7 +3291,7 @@
|
|||||||
"Sound Theme": "Tema do Som"
|
"Sound Theme": "Tema do Som"
|
||||||
},
|
},
|
||||||
"Sounds": {
|
"Sounds": {
|
||||||
"Sounds": ""
|
"Sounds": "Sons"
|
||||||
},
|
},
|
||||||
"Space between windows": {
|
"Space between windows": {
|
||||||
"Space between windows": ""
|
"Space between windows": ""
|
||||||
@@ -3369,7 +3387,7 @@
|
|||||||
"System Monitor Unavailable": "Monitor do Sistema Indisponível"
|
"System Monitor Unavailable": "Monitor do Sistema Indisponível"
|
||||||
},
|
},
|
||||||
"System Sounds": {
|
"System Sounds": {
|
||||||
"System Sounds": ""
|
"System Sounds": "Sons do Sistema"
|
||||||
},
|
},
|
||||||
"System Tray": {
|
"System Tray": {
|
||||||
"System Tray": "Bandeja do Sistema"
|
"System Tray": "Bandeja do Sistema"
|
||||||
@@ -3468,7 +3486,7 @@
|
|||||||
"Time & Weather": "Hora & Clima"
|
"Time & Weather": "Hora & Clima"
|
||||||
},
|
},
|
||||||
"Time Format": {
|
"Time Format": {
|
||||||
"Time Format": ""
|
"Time Format": "Formato de Tempo"
|
||||||
},
|
},
|
||||||
"Time remaining: %1": {
|
"Time remaining: %1": {
|
||||||
"Time remaining: %1": ""
|
"Time remaining: %1": ""
|
||||||
@@ -3549,7 +3567,7 @@
|
|||||||
"Transition Effect": "Efeito de Transição"
|
"Transition Effect": "Efeito de Transição"
|
||||||
},
|
},
|
||||||
"Transparency": {
|
"Transparency": {
|
||||||
"Transparency": ""
|
"Transparency": "Transparência"
|
||||||
},
|
},
|
||||||
"Turn off monitors after": {
|
"Turn off monitors after": {
|
||||||
"Turn off monitors after": "Desligar monitores depois de"
|
"Turn off monitors after": "Desligar monitores depois de"
|
||||||
@@ -3558,10 +3576,10 @@
|
|||||||
"Type": "Tipo"
|
"Type": "Tipo"
|
||||||
},
|
},
|
||||||
"Typography": {
|
"Typography": {
|
||||||
"Typography": ""
|
"Typography": "Tipografia"
|
||||||
},
|
},
|
||||||
"Typography & Motion": {
|
"Typography & Motion": {
|
||||||
"Typography & Motion": ""
|
"Typography & Motion": "Tipografia & Movimento"
|
||||||
},
|
},
|
||||||
"Unavailable": {
|
"Unavailable": {
|
||||||
"Unavailable": "Indisponível"
|
"Unavailable": "Indisponível"
|
||||||
@@ -3741,7 +3759,7 @@
|
|||||||
"Visual effect used when wallpaper changes": "Efeito visual usado na mudança do papel de parede"
|
"Visual effect used when wallpaper changes": "Efeito visual usado na mudança do papel de parede"
|
||||||
},
|
},
|
||||||
"Volume": {
|
"Volume": {
|
||||||
"Volume": ""
|
"Volume": "Volume"
|
||||||
},
|
},
|
||||||
"Volume Changed": {
|
"Volume Changed": {
|
||||||
"Volume Changed": "Volume Alterado"
|
"Volume Changed": "Volume Alterado"
|
||||||
@@ -3854,7 +3872,7 @@
|
|||||||
"Wind Speed": "Velocidade do Vento"
|
"Wind Speed": "Velocidade do Vento"
|
||||||
},
|
},
|
||||||
"Window Corner Radius": {
|
"Window Corner Radius": {
|
||||||
"Window Corner Radius": ""
|
"Window Corner Radius": "Arredondamento de Janelas"
|
||||||
},
|
},
|
||||||
"Window Gaps": {
|
"Window Gaps": {
|
||||||
"Window Gaps": ""
|
"Window Gaps": ""
|
||||||
@@ -3977,7 +3995,7 @@
|
|||||||
"events": "eventos"
|
"events": "eventos"
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"files": ""
|
"files": "arquivos"
|
||||||
},
|
},
|
||||||
"generic theme description": {
|
"generic theme description": {
|
||||||
"Material Design inspired color themes": ""
|
"Material Design inspired color themes": ""
|
||||||
@@ -4016,7 +4034,7 @@
|
|||||||
"Matugen Missing": ""
|
"Matugen Missing": ""
|
||||||
},
|
},
|
||||||
"minutes": {
|
"minutes": {
|
||||||
"minutes": ""
|
"minutes": "minutos"
|
||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"ms": ""
|
"ms": ""
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": ""
|
"No wallpaper selected": ""
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "oficial"
|
"official": "oficial"
|
||||||
},
|
},
|
||||||
@@ -4058,7 +4120,7 @@
|
|||||||
"Color theme from DMS registry": ""
|
"Color theme from DMS registry": ""
|
||||||
},
|
},
|
||||||
"seconds": {
|
"seconds": {
|
||||||
"seconds": ""
|
"seconds": "segundos"
|
||||||
},
|
},
|
||||||
"settings window title": {
|
"settings window title": {
|
||||||
"Settings": "Configurações"
|
"Settings": "Configurações"
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": ""
|
"wtype not available - install wtype for paste support": ""
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "Instale apenas de fontes confiáveis"
|
"• Install only from trusted sources": "Instale apenas de fontes confiáveis"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 bağlı"
|
"%1 connected": "%1 bağlı"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 ekran"
|
"%1 display(s)": "%1 ekran"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 widget"
|
"%1 widgets": "%1 widget"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(İsimsiz)"
|
"(Unnamed)": "(İsimsiz)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "Kilit Ekranı Solması"
|
"Fade to lock screen": "Kilit Ekranı Solması"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "Yapılandırma etkinleştirilemedi"
|
"Failed to activate configuration": "Yapılandırma etkinleştirilemedi"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "Yapılandırılabilir bir bekleme süresi ile kilitlemeden önce ekranı kademeli olarak karartın"
|
"Gradually fade the screen before locking with a configurable grace period": "Yapılandırılabilir bir bekleme süresi ile kilitlemeden önce ekranı kademeli olarak karartın"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "Grafik Zaman Aralığı"
|
"Graph Time Range": "Grafik Zaman Aralığı"
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "Askıya almadan önce kilitle"
|
"Lock before suspend": "Askıya almadan önce kilitle"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "Çıkış"
|
"Log Out": "Çıkış"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "Monitör Yapılandırması"
|
"Monitor Configuration": "Monitör Yapılandırması"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "Duvar kağıdı dinamik tema renklerini yönlendiren monitör"
|
"Monitor whose wallpaper drives dynamic theming colors": "Duvar kağıdı dinamik tema renklerini yönlendiren monitör"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "Duvar kağıdı seçilmedi"
|
"No wallpaper selected": "Duvar kağıdı seçilmedi"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "resmi"
|
"official": "resmi"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype mevcut değil - yapıştırma desteği için wtype'ı yükleyin"
|
"wtype not available - install wtype for paste support": "wtype mevcut değil - yapıştırma desteği için wtype'ı yükleyin"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• Yalnızca güvenilir kaynaklardan yükle"
|
"• Install only from trusted sources": "• Yalnızca güvenilir kaynaklardan yükle"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "已连接 %1"
|
"%1 connected": "已连接 %1"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 显示"
|
"%1 display(s)": "%1 显示"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 部件"
|
"%1 widgets": "%1 部件"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(未命名)"
|
"(Unnamed)": "(未命名)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "淡出至锁定屏幕"
|
"Fade to lock screen": "淡出至锁定屏幕"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "无法应用配置"
|
"Failed to activate configuration": "无法应用配置"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "在锁定前通过可配置的宽限期逐渐淡出屏幕"
|
"Gradually fade the screen before locking with a configurable grace period": "在锁定前通过可配置的宽限期逐渐淡出屏幕"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "图表时间范围"
|
"Graph Time Range": "图表时间范围"
|
||||||
},
|
},
|
||||||
@@ -1677,7 +1689,7 @@
|
|||||||
"Grid Columns": "网格列"
|
"Grid Columns": "网格列"
|
||||||
},
|
},
|
||||||
"Group Workspace Apps": {
|
"Group Workspace Apps": {
|
||||||
"Group Workspace Apps": ""
|
"Group Workspace Apps": "分组工作区应用"
|
||||||
},
|
},
|
||||||
"Group by App": {
|
"Group by App": {
|
||||||
"Group by App": "按应用分组"
|
"Group by App": "按应用分组"
|
||||||
@@ -1686,7 +1698,7 @@
|
|||||||
"Group multiple windows of the same app together with a window count indicator": "将同一应用的多个窗口合并显示,并标注窗口数量"
|
"Group multiple windows of the same app together with a window count indicator": "将同一应用的多个窗口合并显示,并标注窗口数量"
|
||||||
},
|
},
|
||||||
"Group repeated application icons in unfocused workspaces": {
|
"Group repeated application icons in unfocused workspaces": {
|
||||||
"Group repeated application icons in unfocused workspaces": ""
|
"Group repeated application icons in unfocused workspaces": "在不聚焦的工作区中将重复应用图标分组"
|
||||||
},
|
},
|
||||||
"HDR (EDID)": {
|
"HDR (EDID)": {
|
||||||
"HDR (EDID)": "HDR(EDID)"
|
"HDR (EDID)": "HDR(EDID)"
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "挂起前锁屏"
|
"Lock before suspend": "挂起前锁屏"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "注销"
|
"Log Out": "注销"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "监视器配置"
|
"Monitor Configuration": "监视器配置"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "监视使用动态主题色的壁纸"
|
"Monitor whose wallpaper drives dynamic theming colors": "监视使用动态主题色的壁纸"
|
||||||
},
|
},
|
||||||
@@ -2946,7 +2964,7 @@
|
|||||||
"Scroll title if it doesn't fit in widget": "如果在部件中标题不适配,则可以滚动标题"
|
"Scroll title if it doesn't fit in widget": "如果在部件中标题不适配,则可以滚动标题"
|
||||||
},
|
},
|
||||||
"Scroll wheel behavior on media widget": {
|
"Scroll wheel behavior on media widget": {
|
||||||
"Scroll wheel behavior on media widget": ""
|
"Scroll wheel behavior on media widget": "媒体部件上的滚轮行为"
|
||||||
},
|
},
|
||||||
"Scrolling": {
|
"Scrolling": {
|
||||||
"Scrolling": "滚动"
|
"Scrolling": "滚动"
|
||||||
@@ -3219,7 +3237,7 @@
|
|||||||
"Show workspace index numbers in the top bar workspace switcher": "在顶栏工作区切换器中显示工作区索引号"
|
"Show workspace index numbers in the top bar workspace switcher": "在顶栏工作区切换器中显示工作区索引号"
|
||||||
},
|
},
|
||||||
"Show workspace name on horizontal bars, and first letter on vertical bars": {
|
"Show workspace name on horizontal bars, and first letter on vertical bars": {
|
||||||
"Show workspace name on horizontal bars, and first letter on vertical bars": ""
|
"Show workspace name on horizontal bars, and first letter on vertical bars": "在水平状态栏上显示工作区名称,而在垂直状态栏上显示首字母。"
|
||||||
},
|
},
|
||||||
"Shows all running applications with focus indication": {
|
"Shows all running applications with focus indication": {
|
||||||
"Shows all running applications with focus indication": "显示所有正在运行应用程序,并标记焦点所在"
|
"Shows all running applications with focus indication": "显示所有正在运行应用程序,并标记焦点所在"
|
||||||
@@ -3252,10 +3270,10 @@
|
|||||||
"Sizing": "大小调整"
|
"Sizing": "大小调整"
|
||||||
},
|
},
|
||||||
"Smartcard Authentication": {
|
"Smartcard Authentication": {
|
||||||
"Smartcard Authentication": ""
|
"Smartcard Authentication": "智能卡认证"
|
||||||
},
|
},
|
||||||
"Smartcard PIN": {
|
"Smartcard PIN": {
|
||||||
"Smartcard PIN": ""
|
"Smartcard PIN": "智能卡PIN"
|
||||||
},
|
},
|
||||||
"Some plugins require a newer version of DMS:": {
|
"Some plugins require a newer version of DMS:": {
|
||||||
"Some plugins require a newer version of DMS:": "有些插件需要更新版的 DMS:"
|
"Some plugins require a newer version of DMS:": "有些插件需要更新版的 DMS:"
|
||||||
@@ -3869,7 +3887,7 @@
|
|||||||
"Workspace Index Numbers": "工作区序号"
|
"Workspace Index Numbers": "工作区序号"
|
||||||
},
|
},
|
||||||
"Workspace Names": {
|
"Workspace Names": {
|
||||||
"Workspace Names": ""
|
"Workspace Names": "工作区名称"
|
||||||
},
|
},
|
||||||
"Workspace Padding": {
|
"Workspace Padding": {
|
||||||
"Workspace Padding": "工作区内边距"
|
"Workspace Padding": "工作区内边距"
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "未选择壁纸"
|
"No wallpaper selected": "未选择壁纸"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "官方"
|
"official": "官方"
|
||||||
},
|
},
|
||||||
@@ -4052,7 +4114,7 @@
|
|||||||
"Select Profile Image": "选择个人信息图像"
|
"Select Profile Image": "选择个人信息图像"
|
||||||
},
|
},
|
||||||
"read-only settings warning for NixOS home-manager users": {
|
"read-only settings warning for NixOS home-manager users": {
|
||||||
"Settings are read-only. Changes will not persist.": ""
|
"Settings are read-only. Changes will not persist.": "设置处于只读状态。更改将不会保存。"
|
||||||
},
|
},
|
||||||
"registry theme description": {
|
"registry theme description": {
|
||||||
"Color theme from DMS registry": "DMS注册表的颜色主题"
|
"Color theme from DMS registry": "DMS注册表的颜色主题"
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype不可用,为支持粘贴,请安装wtype"
|
"wtype not available - install wtype for paste support": "wtype不可用,为支持粘贴,请安装wtype"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• 仅从可信来源安装"
|
"• Install only from trusted sources": "• 仅从可信来源安装"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"%1 connected": {
|
"%1 connected": {
|
||||||
"%1 connected": "%1 已連接"
|
"%1 connected": "%1 已連接"
|
||||||
},
|
},
|
||||||
|
"%1 days ago": {
|
||||||
|
"%1 days ago": ""
|
||||||
|
},
|
||||||
"%1 display(s)": {
|
"%1 display(s)": {
|
||||||
"%1 display(s)": "%1 個螢幕"
|
"%1 display(s)": "%1 個螢幕"
|
||||||
},
|
},
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
"%1 widgets": {
|
"%1 widgets": {
|
||||||
"%1 widgets": "%1 個部件"
|
"%1 widgets": "%1 個部件"
|
||||||
},
|
},
|
||||||
|
"%1m ago": {
|
||||||
|
"%1m ago": ""
|
||||||
|
},
|
||||||
"(Unnamed)": {
|
"(Unnamed)": {
|
||||||
"(Unnamed)": "(未命名)"
|
"(Unnamed)": "(未命名)"
|
||||||
},
|
},
|
||||||
@@ -1373,6 +1379,9 @@
|
|||||||
"Fade to lock screen": {
|
"Fade to lock screen": {
|
||||||
"Fade to lock screen": "淡出至鎖定螢幕"
|
"Fade to lock screen": "淡出至鎖定螢幕"
|
||||||
},
|
},
|
||||||
|
"Fade to monitor off": {
|
||||||
|
"Fade to monitor off": ""
|
||||||
|
},
|
||||||
"Failed to activate configuration": {
|
"Failed to activate configuration": {
|
||||||
"Failed to activate configuration": "無法啟動配置"
|
"Failed to activate configuration": "無法啟動配置"
|
||||||
},
|
},
|
||||||
@@ -1664,6 +1673,9 @@
|
|||||||
"Gradually fade the screen before locking with a configurable grace period": {
|
"Gradually fade the screen before locking with a configurable grace period": {
|
||||||
"Gradually fade the screen before locking with a configurable grace period": "在鎖定前逐漸淡出螢幕,並帶有可設定的緩衝期"
|
"Gradually fade the screen before locking with a configurable grace period": "在鎖定前逐漸淡出螢幕,並帶有可設定的緩衝期"
|
||||||
},
|
},
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": {
|
||||||
|
"Gradually fade the screen before turning off monitors with a configurable grace period": ""
|
||||||
|
},
|
||||||
"Graph Time Range": {
|
"Graph Time Range": {
|
||||||
"Graph Time Range": "圖表時間範圍"
|
"Graph Time Range": "圖表時間範圍"
|
||||||
},
|
},
|
||||||
@@ -1997,6 +2009,9 @@
|
|||||||
"Lock before suspend": {
|
"Lock before suspend": {
|
||||||
"Lock before suspend": "鎖定後暫停"
|
"Lock before suspend": "鎖定後暫停"
|
||||||
},
|
},
|
||||||
|
"Lock fade grace period": {
|
||||||
|
"Lock fade grace period": ""
|
||||||
|
},
|
||||||
"Log Out": {
|
"Log Out": {
|
||||||
"Log Out": "登出"
|
"Log Out": "登出"
|
||||||
},
|
},
|
||||||
@@ -2171,6 +2186,9 @@
|
|||||||
"Monitor Configuration": {
|
"Monitor Configuration": {
|
||||||
"Monitor Configuration": "顯示器配置"
|
"Monitor Configuration": "顯示器配置"
|
||||||
},
|
},
|
||||||
|
"Monitor fade grace period": {
|
||||||
|
"Monitor fade grace period": ""
|
||||||
|
},
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": {
|
"Monitor whose wallpaper drives dynamic theming colors": {
|
||||||
"Monitor whose wallpaper drives dynamic theming colors": "系統介面顏色依據哪一個螢幕上的桌布來決定"
|
"Monitor whose wallpaper drives dynamic theming colors": "系統介面顏色依據哪一個螢幕上的桌布來決定"
|
||||||
},
|
},
|
||||||
@@ -4030,6 +4048,50 @@
|
|||||||
"no wallpaper status": {
|
"no wallpaper status": {
|
||||||
"No wallpaper selected": "未選擇任何桌布"
|
"No wallpaper selected": "未選擇任何桌布"
|
||||||
},
|
},
|
||||||
|
"notification center tab": {
|
||||||
|
"Current": "",
|
||||||
|
"History": ""
|
||||||
|
},
|
||||||
|
"notification history filter": {
|
||||||
|
"All": "",
|
||||||
|
"Last hour": "",
|
||||||
|
"Today": "",
|
||||||
|
"Yesterday": ""
|
||||||
|
},
|
||||||
|
"notification history filter for content older than other filters": {
|
||||||
|
"Older": ""
|
||||||
|
},
|
||||||
|
"notification history filter | notification history retention option": {
|
||||||
|
"30 days": "",
|
||||||
|
"7 days": ""
|
||||||
|
},
|
||||||
|
"notification history limit": {
|
||||||
|
"Maximum number of notifications to keep": ""
|
||||||
|
},
|
||||||
|
"notification history retention option": {
|
||||||
|
"1 day": "",
|
||||||
|
"14 days": "",
|
||||||
|
"3 days": "",
|
||||||
|
"Forever": ""
|
||||||
|
},
|
||||||
|
"notification history retention settings label": {
|
||||||
|
"History Retention": ""
|
||||||
|
},
|
||||||
|
"notification history setting": {
|
||||||
|
"Auto-delete notifications older than this": "",
|
||||||
|
"Save critical priority notifications to history": "",
|
||||||
|
"Save low priority notifications to history": "",
|
||||||
|
"Save normal priority notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle description": {
|
||||||
|
"Save dismissed notifications to history": ""
|
||||||
|
},
|
||||||
|
"notification history toggle label": {
|
||||||
|
"Enable History": ""
|
||||||
|
},
|
||||||
|
"now": {
|
||||||
|
"now": ""
|
||||||
|
},
|
||||||
"official": {
|
"official": {
|
||||||
"official": "官方"
|
"official": "官方"
|
||||||
},
|
},
|
||||||
@@ -4126,6 +4188,9 @@
|
|||||||
"wtype not available - install wtype for paste support": {
|
"wtype not available - install wtype for paste support": {
|
||||||
"wtype not available - install wtype for paste support": "wtype 未可用 - 請安裝 wtype 以支援貼上功能"
|
"wtype not available - install wtype for paste support": "wtype 未可用 - 請安裝 wtype 以支援貼上功能"
|
||||||
},
|
},
|
||||||
|
"yesterday": {
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
"• Install only from trusted sources": {
|
"• Install only from trusted sources": {
|
||||||
"• Install only from trusted sources": "• 僅從受信任的來源安裝"
|
"• Install only from trusted sources": "• 僅從受信任的來源安裝"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -34,6 +34,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "%1 days ago",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "%1 display(s)",
|
"term": "%1 display(s)",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -69,6 +76,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "%1m ago",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "(Unnamed)",
|
"term": "(Unnamed)",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -86,7 +100,7 @@
|
|||||||
{
|
{
|
||||||
"term": "1 day",
|
"term": "1 day",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history retention option",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -135,7 +149,7 @@
|
|||||||
{
|
{
|
||||||
"term": "14 days",
|
"term": "14 days",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history retention option",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -184,7 +198,7 @@
|
|||||||
{
|
{
|
||||||
"term": "3 days",
|
"term": "3 days",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history retention option",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -198,7 +212,7 @@
|
|||||||
{
|
{
|
||||||
"term": "30 days",
|
"term": "30 days",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history filter | notification history retention option",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -233,7 +247,7 @@
|
|||||||
{
|
{
|
||||||
"term": "7 days",
|
"term": "7 days",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history filter | notification history retention option",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -471,7 +485,7 @@
|
|||||||
{
|
{
|
||||||
"term": "All",
|
"term": "All",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history filter",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -825,6 +839,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Auto-delete notifications older than this",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history setting",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Auto-hide",
|
"term": "Auto-hide",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -2085,6 +2106,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Current",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification center tab",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Current Items",
|
"term": "Current Items",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -2974,6 +3002,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Enable History",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history toggle label",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Enable Overview Overlay",
|
"term": "Enable Overview Overlay",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -3185,14 +3220,14 @@
|
|||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"term": "Fade grace period",
|
"term": "Fade to lock screen",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"term": "Fade to lock screen",
|
"term": "Fade to monitor off",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
@@ -3751,6 +3786,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Forever",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history retention option",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Forget",
|
"term": "Forget",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -3884,6 +3926,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Gradually fade the screen before turning off monitors with a configurable grace period",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Graph Time Range",
|
"term": "Graph Time Range",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -4052,6 +4101,20 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "History",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification center tab",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "History Retention",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history retention settings label",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "History Settings",
|
"term": "History Settings",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -4521,6 +4584,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Last hour",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history filter",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Last launched %1",
|
"term": "Last launched %1",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -4752,6 +4822,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Lock fade grace period",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Log Out",
|
"term": "Log Out",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -4962,6 +5039,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Maximum number of notifications to keep",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history limit",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Maximum size per clipboard entry",
|
"term": "Maximum size per clipboard entry",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -5179,6 +5263,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Monitor fade grace period",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Monitor whose wallpaper drives dynamic theming colors",
|
"term": "Monitor whose wallpaper drives dynamic theming colors",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -5809,6 +5900,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Older",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history filter for content older than other filters",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "On-Screen Displays",
|
"term": "On-Screen Displays",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -6901,6 +6999,34 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Save critical priority notifications to history",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history setting",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Save dismissed notifications to history",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history toggle description",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Save low priority notifications to history",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history setting",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Save normal priority notifications to history",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history setting",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Save password",
|
"term": "Save password",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -8388,7 +8514,7 @@
|
|||||||
{
|
{
|
||||||
"term": "Today",
|
"term": "Today",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
"context": "",
|
"context": "notification history filter",
|
||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
@@ -9323,6 +9449,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Yesterday",
|
||||||
|
"translation": "",
|
||||||
|
"context": "notification history filter",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "You have unsaved changes. Save before closing this tab?",
|
"term": "You have unsaved changes. Save before closing this tab?",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -9470,6 +9603,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "now",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "official",
|
"term": "official",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -9505,6 +9645,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "yesterday",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "• Install only from trusted sources",
|
"term": "• Install only from trusted sources",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user