feat(hm-module): pins declaration (#132)
This commit is contained in:
196
hm-module.nix
196
hm-module.nix
@@ -196,6 +196,81 @@ in {
|
||||
);
|
||||
default = {};
|
||||
};
|
||||
pinsForce = mkOption {
|
||||
type = bool;
|
||||
description = "Whether to delete existing pins not declared in the configuration.";
|
||||
default = false;
|
||||
};
|
||||
pins = mkOption {
|
||||
type = attrsOf (
|
||||
submodule (
|
||||
{ name, ... }: {
|
||||
options = {
|
||||
title = mkOption {
|
||||
type = str;
|
||||
description = "title of the pin.";
|
||||
default = name;
|
||||
};
|
||||
id = mkOption {
|
||||
type = str;
|
||||
description = "REQUIRED. Unique Version 4 UUID for pin.";
|
||||
};
|
||||
url = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "Optional URL text field";
|
||||
};
|
||||
container = mkOption {
|
||||
type = nullOr ints.unsigned;
|
||||
default = null;
|
||||
description = "Container ID to be used in pin";
|
||||
};
|
||||
workspace = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "Workspace ID to be used in pin";
|
||||
};
|
||||
position = mkOption {
|
||||
type = ints.unsigned;
|
||||
default = 1000;
|
||||
description = "Position of the pin.";
|
||||
};
|
||||
isEssential = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Required boolean flag for essential items, defaults to false";
|
||||
};
|
||||
isGroup = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Required boolean flag for group items, defaults to false";
|
||||
};
|
||||
editedTitle = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Required boolean flag for edited title, defaults to false";
|
||||
};
|
||||
isFolderCollapsed = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Required boolean flag for folder collapse state, defaults to false";
|
||||
};
|
||||
folderIcon = mkOption {
|
||||
type = nullOr str;
|
||||
description = "Emoji or icon URI to be used as pin folder icon.";
|
||||
default = null;
|
||||
};
|
||||
folderParentId = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "Optional folder parent UUID text field";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
@@ -390,6 +465,119 @@ in {
|
||||
else ""
|
||||
}${concatMapAttrsStringSep " AND " (_: s: "NOT uuid = '{${s.id}}'") profile.spaces}" || exit 1
|
||||
'';
|
||||
|
||||
insertPins = ''
|
||||
#Reference https://github.com/zen-browser/desktop/blob/28bf0458e43e2bb741cd67834d2b50ce2b5587c6/src/zen/tabs/ZenPinnedTabsStorage.mjs#L12-L26
|
||||
# Create the pins table if it doesn't exist
|
||||
${sqlite3} "${placesFile}" "${
|
||||
concatStringsSep " " [
|
||||
"CREATE TABLE IF NOT EXISTS zen_pins ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"uuid TEXT UNIQUE NOT NULL,"
|
||||
"title TEXT NOT NULL,"
|
||||
"url TEXT,"
|
||||
"container_id INTEGER,"
|
||||
"workspace_uuid TEXT,"
|
||||
"position INTEGER NOT NULL DEFAULT 0,"
|
||||
"is_essential BOOLEAN NOT NULL DEFAULT 0,"
|
||||
"is_group BOOLEAN NOT NULL DEFAULT 0,"
|
||||
"created_at INTEGER NOT NULL,"
|
||||
"updated_at INTEGER NOT NULL"
|
||||
");"
|
||||
]
|
||||
}" || exit 1
|
||||
|
||||
columns=($(${sqlite3} "${placesFile}" "SELECT name FROM pragma_table_info('zen_pins');"))
|
||||
|
||||
if [[ ! "''${columns[@]}" =~ "edited_title" ]]; then
|
||||
${sqlite3} "${placesFile}" "ALTER TABLE zen_pins ADD COLUMN edited_title BOOLEAN NOT NULL DEFAULT 0;" || exit 1
|
||||
fi
|
||||
if [[ ! "''${columns[@]}" =~ "is_folder_collapsed" ]]; then
|
||||
${sqlite3} "${placesFile}" "ALTER TABLE zen_pins ADD COLUMN is_folder_collapsed BOOLEAN NOT NULL DEFAULT 0;" || exit 1
|
||||
fi
|
||||
if [[ ! "''${columns[@]}" =~ "folder_icon" ]]; then
|
||||
${sqlite3} "${placesFile}" "ALTER TABLE zen_pins ADD COLUMN folder_icon TEXT DEFAULT NULL;" || exit 1
|
||||
fi
|
||||
if [[ ! "''${columns[@]}" =~ "folder_parent_uuid" ]]; then
|
||||
${sqlite3} "${placesFile}" "ALTER TABLE zen_pins ADD COLUMN folder_parent_uuid TEXT DEFAULT NULL;" || exit 1
|
||||
fi
|
||||
|
||||
# Reference https://github.com/zen-browser/desktop/blob/28bf0458e43e2bb741cd67834d2b50ce2b5587c6/src/zen/tabs/ZenPinnedTabsStorage.mjs#L103-L112
|
||||
# Insert or replace the pin
|
||||
${sqlite3} "${placesFile}" <<-'SQL' || exit 1
|
||||
${
|
||||
(concatStringsSep " " [
|
||||
"INSERT OR REPLACE INTO zen_pins ("
|
||||
"uuid,"
|
||||
"title,"
|
||||
"url,"
|
||||
"container_id,"
|
||||
"workspace_uuid,"
|
||||
"position,"
|
||||
"is_essential,"
|
||||
"is_group,"
|
||||
"folder_parent_uuid,"
|
||||
"edited_title,"
|
||||
"created_at,"
|
||||
"updated_at,"
|
||||
"is_folder_collapsed,"
|
||||
"folder_icon"
|
||||
") VALUES "
|
||||
])
|
||||
+
|
||||
(pipe profile.pins [
|
||||
(mapAttrsToList (
|
||||
_: p: [
|
||||
"'{${p.id}}'"
|
||||
"'${p.title}'"
|
||||
(
|
||||
if isNull p.url
|
||||
then "NULL"
|
||||
else "'${p.url}'"
|
||||
)
|
||||
(
|
||||
if isNull p.container
|
||||
then "NULL"
|
||||
else toString p.container
|
||||
)
|
||||
(
|
||||
if isNull p.workspace
|
||||
then "NULL"
|
||||
else "'{${p.workspace}}'"
|
||||
)
|
||||
(toString p.position)
|
||||
(if p.isEssential then "1" else "0")
|
||||
(if p.isGroup then "1" else "0")
|
||||
(
|
||||
if isNull p.folderParentId
|
||||
then "NULL"
|
||||
else "'{${p.folderParentId}}'"
|
||||
)
|
||||
(if p.editedTitle then "1" else "0")
|
||||
"COALESCE((SELECT created_at FROM zen_pins WHERE uuid = '{${p.id}}'), strftime('%s', 'now'))"
|
||||
"strftime('%s', 'now')"
|
||||
(if p.isFolderCollapsed then "1" else "0")
|
||||
(
|
||||
if isNull p.folderIcon
|
||||
then "NULL"
|
||||
else "'${p.folderIcon}'"
|
||||
)
|
||||
]
|
||||
))
|
||||
(map (row: concatStringsSep "," row))
|
||||
(concatMapStringsSep "," (row: "(${row})"))
|
||||
])
|
||||
}
|
||||
SQL
|
||||
'';
|
||||
|
||||
deletePins = ''
|
||||
${sqlite3} "${placesFile}" "DELETE FROM zen_pins ${
|
||||
if profile.pins != {}
|
||||
then "WHERE "
|
||||
else ""
|
||||
}${concatMapAttrsStringSep " AND " (_: p: "NOT uuid = '{${p.id}}'") profile.pins}" || exit 1
|
||||
'';
|
||||
in
|
||||
nameValuePair scriptFile {
|
||||
source = getExe (
|
||||
@@ -397,12 +585,14 @@ in {
|
||||
# This file is generated by Zen browser Home Manager module, please to not change it since it
|
||||
# will be overridden and executed on every rebuild of the home environment.
|
||||
|
||||
function update_spaces() {
|
||||
function update_places() {
|
||||
${optionalString (profile.spaces != {}) insertSpaces}
|
||||
${optionalString (profile.spacesForce) deleteSpaces}
|
||||
${optionalString (profile.pins != {}) insertPins}
|
||||
${optionalString (profile.pinsForce) deletePins}
|
||||
}
|
||||
|
||||
error="$(update_spaces 2>&1 1>/dev/null)"
|
||||
error="$(update_places 2>&1 1>/dev/null)"
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
if [[ "$error" == *"database is locked"* ]]; then
|
||||
echo "$error"
|
||||
@@ -432,6 +622,6 @@ in {
|
||||
executable = true;
|
||||
force = true;
|
||||
}
|
||||
) (filterAttrs (_: profile: profile.spaces != {} || profile.spacesForce) cfg.profiles));
|
||||
) (filterAttrs (_: profile: profile.spaces != {} || profile.spacesForce || profile.pins != { } || profile.pinsForce) cfg.profiles));
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user