cleanup and keyboard and more

This commit is contained in:
Matt Nish-Lapidus 2025-05-23 17:59:49 -04:00
parent 8171a43920
commit c9feefeb1f
31 changed files with 36 additions and 5212 deletions

6
flake.lock generated
View file

@ -88,11 +88,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1748017501, "lastModified": 1748020806,
"narHash": "sha256-9kCYqXpjaQkXpOrc1b/hac2Wzx8b/3zzajpO1ei7N00=", "narHash": "sha256-g14/YAdrO5KkWvXoltBgqNHt24jUxRraB79See08nhM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "emacs-overlay", "repo": "emacs-overlay",
"rev": "d7ab9d00bc840fec8a76375634ae36d406ab0513", "rev": "d818fd9717043b794d0012fbc9f6422e12915eaf",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,6 +1,6 @@
{ nix-config, config, lib, pkgs, inputs, ... }: { nix-config, config, lib, pkgs, inputs, ... }:
let let
scpath = "/home/emenel/.config/sops-nix/secrets"; # scpath = "/home/emenel/.config/sops-nix/secrets";
in in
{ {
@ -54,8 +54,8 @@ in
WINEFSYNC = 1; WINEFSYNC = 1;
PKG_CONFIG_PATH = "/home/emenel/.nix-profile/lib/pkgconfig:/home/emenel/.nix-profile/lib64/pkgconfig:/home/emenal/.nix-profile/share/pkgconfig"; PKG_CONFIG_PATH = "/home/emenel/.nix-profile/lib/pkgconfig:/home/emenel/.nix-profile/lib64/pkgconfig:/home/emenal/.nix-profile/share/pkgconfig";
GI_TYPELIB_PATH = "/run/current-system/sw/lib/girepository-1.0"; GI_TYPELIB_PATH = "/run/current-system/sw/lib/girepository-1.0";
BW_CLIENTID = "$(cat ${config.sops.secrets.bw_client_id.path}/bw_client_id)"; # BW_CLIENTID = "$(cat ${config.sops.secrets.bw_client_id.path}/bw_client_id)";
BW_CLIENTSECRET = "$(cat ${config.sops.secrets.bw_api_key.path}/bw_api_key)"; # BW_CLIENTSECRET = "$(cat ${config.sops.secrets.bw_api_key.path}/bw_api_key)";
NIXOS_OZONE_WL = "1"; NIXOS_OZONE_WL = "1";
GSK_RENDERER = "ngl"; GSK_RENDERER = "ngl";
MOZ_ENABLE_WAYLAND = 1; MOZ_ENABLE_WAYLAND = 1;
@ -68,19 +68,19 @@ in
stateVersion = "24.11"; stateVersion = "24.11";
}; };
sops = { # sops = {
age.keyFile = "/home/emenel/.config/sops/age/keys.txt"; # must have no password! # age.keyFile = "/home/emenel/.config/sops/age/keys.txt"; # must have no password!
defaultSopsFile = ./secrets.yaml; # defaultSopsFile = ./secrets.yaml;
secrets = { # secrets = {
bw_client_id = {}; # bw_client_id = {};
bw_api_key = {}; # bw_api_key = {};
ssh_key = {}; # ssh_key = {};
borg_url = {}; # borg_url = {};
icloud = {}; # icloud = {};
}; # };
}; # };
programs = { programs = {
home-manager.enable = true; home-manager.enable = true;

View file

@ -289,6 +289,7 @@
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /mnt 0770 root users" "d /mnt 0770 root users"
"L /mnt/removable - - - - /run/media/emenel" "L /mnt/removable - - - - /run/media/emenel"
"L+ /var/lib/qemu/firmware - - - - ${pkgs.qemu}/share/qemu/firmware"
]; ];
services.hardware.openrgb = { services.hardware.openrgb = {
@ -536,23 +537,22 @@
services.accounts-daemon.enable = true; services.accounts-daemon.enable = true;
# programs.virt-manager.enable = true; programs.virt-manager.enable = true;
# systemd.tmpfiles.rules = [ "L+ /var/lib/qemu/firmware - - - - ${pkgs.qemu}/share/qemu/firmware" ]; virtualisation = {
# virtualisation = { libvirtd = {
# libvirtd = { enable = true;
# enable = true; qemu = {
# qemu = { package = pkgs.qemu_kvm;
# package = pkgs.qemu_kvm; swtpm.enable = true;
# swtpm.enable = true; ovmf.enable = true;
# ovmf.enable = true; ovmf.packages = [ pkgs.OVMFFull.fd ];
# ovmf.packages = [ pkgs.OVMFFull.fd ]; };
# }; };
# }; spiceUSBRedirection.enable = true;
# spiceUSBRedirection.enable = true; };
# };
# services.qemuGuest.enable = true; services.qemuGuest.enable = true;
# services.spice-vdagentd.enable = true; services.spice-vdagentd.enable = true;
programs.appimage = { programs.appimage = {
enable = true; enable = true;

View file

@ -3,13 +3,9 @@
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
mpc mpc
ncmpcpp
termusic
nix-config.packages.x86_64-linux.rmpc-latest nix-config.packages.x86_64-linux.rmpc-latest
]; ];
programs.fish.shellAliases = { "ncm" = "ncmpcpp"; };
services = { services = {
mpd = { mpd = {
enable = true; enable = true;
@ -35,10 +31,4 @@
source = ./rmpc; source = ./rmpc;
recursive = true; recursive = true;
}; };
xdg.configFile."ncmpcpp/" = {
source = ./ncmpcpp;
recursive = true;
};
} }

View file

@ -13,7 +13,6 @@
the-usual-suspects.xenia the-usual-suspects.xenia
the-usual-suspects.ostirus the-usual-suspects.ostirus
the-usual-suspects.osirus the-usual-suspects.osirus
paulxstretch
]) ])
(with pkgs; [ (with pkgs; [

View file

@ -1,629 +0,0 @@
##############################################################
## This is an example configuration file. Copy it to ##
## $XDG_CONFIG_HOME/ncmpcpp/config or $HOME/.ncmpcpp/config ##
## and set up your preferences. ##
##############################################################
#
##### directories ######
##
## Directory for storing ncmpcpp related files. Changing it is useful if you
## want to store everything somewhere else and provide command line setting for
## alternative location to config file which defines that while launching
## ncmpcpp.
##
#
#ncmpcpp_directory = ~/.config/ncmpcpp
#
##
## Directory for storing downloaded lyrics. It defaults to ~/.lyrics since other
## MPD clients (eg. ncmpc) also use that location.
##
#
#lyrics_directory = ~/.lyrics
#
##### connection settings #####
#
#mpd_host = localhost
#
#mpd_port = 6600
#
#mpd_password = ""
#
#mpd_connection_timeout = 5
#
## Needed for tag editor and file operations to work.
##
#mpd_music_dir = ~/music
#
#mpd_crossfade_time = 5
#
# Exclude pattern for random song action
# http://www.boost.org/doc/libs/1_46_1/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
#random_exclude_pattern = "^(temp|midi_songs).*"
#
##### music visualizer #####
##
## In order to make music visualizer work with MPD you need to use the fifo
## output. Its format parameter has to be set to 44100:16:1 for mono
## visualization or 44100:16:2 for stereo visualization. As an example here is
## the relevant section for mpd.conf:
##
## audio_output {
## type "fifo"
## name "Visualizer feed"
## path "/tmp/mpd.fifo"
## format "44100:16:2"
## }
##
## If the visualization on occasion diverges from the audio output, please set
## 'buffer_time' parameter of your audio output in mpd.conf to '100000' (100ms)
## or less to prevent that from happening.
##
## Note: If you're using Mopidy, an address of a udpsink gstreamer's output is
## also accepted. For example, the following section in mopidy.conf:
##
## [audio]
## output = tee name=t ! queue ! autoaudiosink t.
## ! queue ! audio/x-raw,rate=44100,channels=2,format=S16LE
## ! udpsink host=localhost port=5555
##
## will make localhost:5555 available as a source of data for the stereo
## visualizer.
##
#
#visualizer_data_source = /tmp/mpd.fifo
#
##
## Note: Below parameter is needed for ncmpcpp to determine which output
## provides data for visualizer and reset it at the beginning of visualization
## to synchronize with audio.
##
#
#visualizer_output_name = Visualizer feed
#
##
## If you set format to 44100:16:2, make it 'yes'.
##
#visualizer_in_stereo = yes
#
##
## Note: set below to >=10 only if you have synchronization issues with
## visualization and audio.
##
#
#visualizer_sync_interval = 0
#
##
## Note: To enable spectrum frequency visualization you need to compile ncmpcpp
## with fftw3 support.
##
#
## Available values: spectrum, wave, wave_filled, ellipse.
##
#visualizer_type = spectrum
#
#visualizer_fps = 60
#
#visualizer_autoscale = no
#
#visualizer_look = ●▮
#
#visualizer_color = blue, cyan, green, yellow, magenta, red
#
## Alternative subset of 256 colors for terminals that support it.
##
#visualizer_color = 47, 83, 119, 155, 191, 227, 221, 215, 209, 203, 197, 161
#
##
## Note: The next few visualization options apply to the spectrum visualizer.
##
#
## Use unicode block characters for a smoother, more continuous look.
## This will override the visualizer_look option. With transparent terminals
## and visualizer_in_stereo set, artifacts may be visible on the bottom half of
## the visualization.
#
#visualizer_spectrum_smooth_look = yes
#
## Use unicode block characters from "symbols for legacy computing". This
## improves the smooth look on transparent terminals by using special unicode
## chars instead of reversing the background and foreground color on the bottom
## edge of the spectrum. If it leads to a garbled output on the bottom edge of
## the spectrum, you can either change the font or disable this option.
#
#visualizer_spectrum_smooth_look_legacy_chars = yes
#
## A value between 1 and 5 inclusive. Specifying a larger value makes the
## visualizer look at a larger slice of time, which results in less jumpy
## visualizer output.
#
#visualizer_spectrum_dft_size = 2
#
#visualizer_spectrum_gain = 10
#
## Left-most frequency of visualizer in Hz, must be less than HZ MAX
#
#visualizer_spectrum_hz_min = 20
#
## Right-most frequency of visualizer in Hz, must be greater than HZ MIN
#
#visualizer_spectrum_hz_max = 20000
#
## Use log scaling for the frequency spectrum axes
#
#visualizer_spectrum_log_scale_x = yes
#visualizer_spectrum_log_scale_y = yes
#
##### system encoding #####
##
## ncmpcpp should detect your charset encoding but if it failed to do so, you
## can specify charset encoding you are using here.
##
## Note: You can see whether your ncmpcpp build supports charset detection by
## checking output of `ncmpcpp --version`.
##
## Note: Since MPD uses UTF-8 by default, setting this option makes sense only
## if your encoding is different.
##
#
#system_encoding = ""
#
##### delays #####
#
## Time of inactivity (in seconds) after playlist highlighting will be disabled
## (0 = always on).
##
#playlist_disable_highlight_delay = 5
#
## Defines how long messages are supposed to be visible.
##
#message_delay_time = 5
#
##### song format #####
##
## For a song format you can use:
##
## %l - length
## %f - filename
## %F - full filepath
## %D - directory
## %a - artist
## %A - album artist
## %t - title
## %b - album
## %y - date
## %n - track number (01/12 -> 01)
## %N - full track info (01/12 -> 01/12)
## %g - genre
## %c - composer
## %p - performer
## %d - disc
## %C - comment
## %P - priority
## $R - begin right alignment
##
## If you want to make sure that a part of the format is displayed only when
## certain tags are present, you can archieve it by grouping them with brackets,
## e.g. '{%a - %t}' will be evaluated to 'ARTIST - TITLE' if both tags are
## present or '' otherwise. It is also possible to define a list of
## alternatives by providing several groups and separating them with '|',
## e.g. '{%t}|{%f}' will be evaluated to 'TITLE' or 'FILENAME' if the former is
## not present.
##
## Note: If you want to set limit on maximal length of a tag, just put the
## appropriate number between % and character that defines tag type, e.g. to
## make album take max. 20 terminal cells, use '%20b'.
##
## In addition, formats support markers used for text attributes. They are
## followed by character '$'. After that you can put:
##
## - 0 - default window color (discards all other colors)
## - 1 - black
## - 2 - red
## - 3 - green
## - 4 - yellow
## - 5 - blue
## - 6 - magenta
## - 7 - cyan
## - 8 - white
## - 9 - end of current color
## - b - bold text
## - u - underline text
## - i - italic text
## - r - reverse colors
## - a - use alternative character set
##
## If you don't want to use a non-color attribute anymore, just put it again,
## but this time insert character '/' between '$' and attribute character,
## e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag or filename with
## reversed colors.
##
## If you want to use 256 colors and/or background colors in formats (the naming
## scheme is described below in section about color definitions), it can be done
## with the syntax $(COLOR), e.g. to set the artist tag to one of the
## non-standard colors and make it have yellow background, you need to write
## $(197_yellow)%a$(end). Note that for standard colors this is interchangable
## with attributes listed above.
##
## Note: colors can be nested.
##
#
#song_list_format = {%a - }{%t}|{$8%f$9}$R{$3%l$9}
#
#song_status_format = {{%a{ "%b"{ (%y)}} - }{%t}}|{%f}
#
#song_library_format = {%n - }{%t}|{%f}
#
#alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b
#
#alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}
#
#current_item_prefix = $(yellow)$r
#
#current_item_suffix = $/r$(end)
#
#current_item_inactive_column_prefix = $(white)$r
#
#current_item_inactive_column_suffix = $/r$(end)
#
#now_playing_prefix = $b
#
#now_playing_suffix = $/b
#
#browser_playlist_prefix = "$2playlist$9 "
#
#selected_item_prefix = $6
#
#selected_item_suffix = $9
#
#modified_item_prefix = $3> $9
#
##
## Note: attributes are not supported for the following variables.
##
#song_window_title_format = {%a - }{%t}|{%f}
##
## Note: Below variables are used for sorting songs in browser. The sort mode
## determines how songs are sorted, and can be used in combination with a sort
## format to specify a custom sorting format. Available values for
## browser_sort_mode are "type", "name", "mtime", "format" and "none".
##
#
#browser_sort_mode = type
#
#browser_sort_format = {%a - }{%t}|{%f} {%l}
#
##### columns settings #####
##
## syntax of song columns list format is "column column etc."
##
## - syntax for each column is:
##
## (width of the column)[color of the column]{displayed tag}
##
## Note: Width is by default in %, if you want a column to have fixed size, add
## 'f' after the value, e.g. (10)[white]{a} will be the column that take 10% of
## screen (so the real width will depend on actual screen size), whereas
## (10f)[white]{a} will take 10 terminal cells, no matter how wide the screen
## is.
##
## - color is optional (if you want the default one, leave the field empty).
##
## Note: You can give a column additional attributes by putting appropriate
## character after displayed tag character. Available attributes are:
##
## - r - column will be right aligned
## - E - if tag is empty, empty tag marker won't be displayed
##
## You can also:
##
## - give a column custom name by putting it after attributes, separated with
## character ':', e.g. {lr:Length} gives you right aligned column of lengths
## named "Length".
##
## - define sequence of tags, that have to be displayed in case predecessor is
## empty in a way similar to the one in classic song format, i.e. using '|'
## character, e.g. {a|c|p:Owner} creates column named "Owner" that tries to
## display artist tag and then composer and performer if previous ones are not
## available.
##
#
#song_columns_list_format = (20)[]{a} (6f)[green]{NE} (50)[white]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l}
#
##### various settings #####
#
##
## Note: Custom command that will be executed each time song changes. Useful for
## notifications etc.
##
#execute_on_song_change = ""
#
##
## Note: Custom command that will be executed each time player state
## changes. The environment variable MPD_PLAYER_STATE is set to the current
## state (either unknown, play, pause, or stop) for its duration.
##
#
#execute_on_player_state_change = ""
#
#playlist_show_mpd_host = no
#
#playlist_show_remaining_time = no
#
#playlist_shorten_total_times = no
#
#playlist_separate_albums = no
#
##
## Note: Possible display modes: classic, columns.
##
#playlist_display_mode = columns
#
#browser_display_mode = classic
#
#search_engine_display_mode = classic
#
#playlist_editor_display_mode = classic
#
#discard_colors_if_item_is_selected = yes
#
#show_duplicate_tags = yes
#
#incremental_seeking = yes
#
#seek_time = 1
#
#volume_change_step = 2
#
#autocenter_mode = no
#
#centered_cursor = no
#
##
## Note: You can specify third character which will be used to build 'empty'
## part of progressbar.
##
#progressbar_look = =>
#
## Available values: database, playlist.
##
#default_place_to_search_in = database
#
## Available values: classic, alternative.
##
user_interface = alternative
#
#data_fetching_delay = yes
#
## Available values: artist, album_artist, date, genre, composer, performer.
##
#media_library_primary_tag = artist
#
#media_library_albums_split_by_date = yes
#
#media_library_hide_album_dates = no
#
## Available values: wrapped, normal.
##
default_find_mode = wrapped
#
#default_tag_editor_pattern = %n - %t
#
#header_visibility = yes
#
#statusbar_visibility = yes
#
## Show the "Connected to ..." message on startup
#connected_message_on_startup = yes
#
#titles_visibility = yes
#
#header_text_scrolling = yes
#
#cyclic_scrolling = no
#
#lyrics_fetchers = tags, genius, tekstowo, plyrics, justsomelyrics, jahlyrics, zeneszoveg, internet
#
#follow_now_playing_lyrics = no
#
#fetch_lyrics_for_current_song_in_background = no
#
#store_lyrics_in_song_dir = no
#
#generate_win32_compatible_filenames = yes
#
#allow_for_physical_item_deletion = no
#
##
## Note: If you set this variable, ncmpcpp will try to get info from last.fm in
## language you set and if it fails, it will fall back to english. Otherwise it
## will use english the first time.
##
## Note: Language has to be expressed as an ISO 639 alpha-2 code.
##
#lastfm_preferred_language = en
#
#space_add_mode = add_remove
#
#show_hidden_files_in_local_browser = no
#
##
## How shall screen switcher work?
##
## - "previous" - switch between the current and previous screen.
## - "screen1,...,screenN" - switch between given sequence of screens.
##
## Screens available for use: help, playlist, browser, search_engine,
## media_library, playlist_editor, tag_editor, outputs, visualizer, clock,
## lyrics, last_fm.
##
#screen_switcher_mode = playlist, browser
#
##
## Note: You can define startup screen by choosing screen from the list above.
##
#startup_screen = playlist
#
##
## Note: You can define startup slave screen by choosing screen from the list
## above or an empty value for no slave screen.
##
#startup_slave_screen = ""
#
#startup_slave_screen_focus = no
#
##
## Default width of locked screen (in %). Acceptable values are from 20 to 80.
##
#
#locked_screen_width_part = 50
#
#ask_for_locked_screen_width_part = yes
#
##
## Width of media_library screen columns
##
#
#media_library_column_width_ratio_two = 1:1
#
#media_library_column_width_ratio_three = 1:1:1
#
##
## Width of playlist_editor screen columns
##
#
#playlist_editor_column_width_ratio = 1:2
#
#jump_to_now_playing_song_at_start = yes
#
#ask_before_clearing_playlists = yes
#
#clock_display_seconds = no
#
#display_volume_level = yes
#
#display_bitrate = no
#
#display_remaining_time = no
#
## Available values: none, basic, extended, perl.
##
#regular_expressions = perl
#
##
## Note: if below is enabled, ncmpcpp will ignore leading "The" word while
## sorting items in browser, tags in media library, etc.
##
ignore_leading_the = yes
#
##
## Note: if below is enabled, ncmpcpp will ignore diacritics while searching and
## filtering lists. This takes an effect only if boost was compiled with ICU
## support.
##
#ignore_diacritics = no
#
#block_search_constraints_change_if_items_found = yes
#
#mouse_support = yes
#
#mouse_list_scroll_whole_page = no
#
#lines_scrolled = 5
#
#empty_tag_marker = <empty>
#
#tags_separator = " | "
#
#tag_editor_extended_numeration = no
#
media_library_sort_by_mtime = no
#
#enable_window_title = yes
#
##
## Note: You can choose default search mode for search engine. Available modes
## are:
##
## - 1 - use mpd built-in searching (no regexes, pattern matching)
##
## - 2 - use ncmpcpp searching (pattern matching with support for regexes, but
## if your mpd is on a remote machine, downloading big database to process
## it can take a while
##
## - 3 - match only exact values (this mode uses mpd function for searching in
## database and local one for searching in current playlist)
##
#
#search_engine_default_search_mode = 1
#
#external_editor = nano
#
## Note: set to yes if external editor is a console application.
##
#use_console_editor = yes
#
##### colors definitions #####
##
## It is possible to set a background color by setting a color value
## "<foreground>_<background>", e.g. red_black will set foregound color to red
## and background color to black.
##
## In addition, for terminals that support 256 colors it is possible to set one
## of them by using a number in range [1, 256] instead of color name,
## e.g. numerical value corresponding to red_black is 2_1. To find out if the
## terminal supports 256 colors, run ncmpcpp and check out the bottom of the
## help screen for list of available colors and their numerical values.
##
## What is more, there are two special values for the background color:
## "transparent" and "current". The first one explicitly sets the background to
## be transparent, while the second one allows you to preserve current
## background color and change only the foreground one. It's used implicitly
## when background color is not specified.
##
## Moreover, it is possible to attach format information to selected color
## variables by appending to their end a colon followed by one or more format
## flags, e.g. black:b or red:ur. The following variables support this syntax:
## visualizer_color, color1, color2, empty_tag_color, volume_color,
## state_line_color, state_flags_color, progressbar_color,
## progressbar_elapsed_color, player_state_color, statusbar_time_color,
## alternative_ui_separator_color.
##
## Note: due to technical limitations of older ncurses version, if 256 colors
## are used there is a possibility that you'll be able to use only colors with
## transparent background.
#
#colors_enabled = yes
#
#empty_tag_color = cyan
#
#header_window_color = default
#
#volume_color = default
#
#state_line_color = default
#
#state_flags_color = default:b
#
#main_window_color = yellow
#
#color1 = white
#
#color2 = green
#
#progressbar_color = black:b
#
#progressbar_elapsed_color = green:b
#
#statusbar_color = default
#
#statusbar_time_color = default:b
#
#player_state_color = default:b
#
#alternative_ui_separator_color = black:b
#
#window_border_color = green
#
#active_window_border = red
#

View file

@ -1,24 +0,0 @@
{ pkgs, ... }:
{
systemd.user.services.taskwarrior-web = {
Unit = {
Description = "taskwarrior web";
After = [ "network.target" ];
};
Install = {
WantedBy = [ "multi-user.target" ];
};
Service = {
Type = "simple";
ExecStart = "/run/current-system/sw/bin/bash /home/emenel/.local/bin/tww/tw-start.sh";
Restart = "always";
};
};
# home.file.".local/bin/tww" = {
# source = ./tww;
# recursive = true;
# };
}

View file

@ -1,51 +0,0 @@
{ config, pkgs, ... }:
{
home.packages = with pkgs; [
vit
tasksh
taskwarrior-tui
taskopen
# syncall
];
programs.taskwarrior = {
enable = true;
package = pkgs.taskwarrior3;
config = {
regex = false;
uda.relativeRecurDue.type = "duration";
uda.relativeRecurDue.label = "Rel. Rec. Due";
uda.relativeRecurWait.type = "duration";
uda.relativeRecurWait.label = "Rel. Rec. Wait";
uda.expires.type = "string";
uda.expires.label = "Expires";
uda.completeRecurDue.type = "string";
uda.completeRecurDue.label = "Com. Rec. Due";
uda.completeRecurWait.type = "string";
uda.completeRecurWait.label = "Com. Rec. Wait";
sync.server.url = "http:\/\/media-server:33043";
};
extraConfig = "include ${config.sops.templates."taskchamp".path}";
};
home.file.".local/share/task/hooks" = {
source = ./taskwarrior/hooks;
recursive = true;
};
# services.taskchampion-sync-server = {
# Unit = {
# Description = "taskchamp";
# After = [ "network.target" ];
# };
# Install = {
# WantedBy = [ "multi-user.target" ];
# };
# Service = {
# Type = "simple";
# ExecStart = "${pkgs.taskchampion-sync-server}/bin/taskchampion-sync-server --listen media-server:33043 --data-dir /home/media/.local/share/task-sync --snapshot-days 1 --snapshot-versions 30";
# };
# };
}

View file

@ -1,19 +0,0 @@
#!/bin/bash
# Read the new task JSON object from standard input
read new_task
# Extract the status and the 'expires' attribute from the new task
status=$(echo "$new_task" | jq -r '.status')
due=$(echo "$new_task" | jq -r '.due // empty')
expires=$(echo "$new_task" | jq -r '.expires // empty')
# Check if the status is not 'recurring' and the 'expires' attribute is set
if [[ "$status" != "recurring" && -n "$expires" ]]; then
# Update the 'until' attribute with the value of 'expires'
new_expire_date=$(task calc "$due + $expires")
new_task=$(echo "$new_task" | jq -r -c --arg expires "$new_expire_date" '. + {until: $expires}')
fi
# Output the new task
echo "$new_task"

View file

@ -1,28 +0,0 @@
#!/bin/sh
# This hooks script syncs task warrior to the configured task server.
# The on-exit event is triggered once, after all processing is complete.
# Make sure hooks are enabled
check_for_internet() {
# check for internet connectivity
nc -z 8.8.8.8 53 >/dev/null 2>&1
if [ $? != 0 ]; then
exit 0
fi
}
# Count the number of tasks modified
n=0
while read modified_task
do
n=$(($n + 1))
done
if (($n > 0)); then
check_for_internet
date >> ~/.local/share/task/sync_hook.log
task rc.verbose:nothing sync >> ~/.local/share/task/sync_hook.log &
fi
exit 0

View file

@ -1,92 +0,0 @@
#!/usr/bin/env python
"""
Module is a copy/paste of https://github.com/mlaradji/task-relative-recur.git
Difference is, we'll execute completeRecurDue and completeRecurWait as strings.
Usage example:
task add 'Do the dishes' completeRecurWait:"tomorrow +17hours" completeRecurDue:"tomorrow +1day"
"""
import json
import sys
import subprocess
import uuid
import os
import tempfile
import time
TIME_FORMAT = "%Y%m%dT%H%M%SZ"
UDA_DUE = "completeRecurDue"
UDA_WAIT = "completeRecurWait"
env = os.environ.copy()
# Hand back duration format parsing to task warrior
def calc(statement):
calc = subprocess.Popen(
["task", "rc.verbose=nothing", "rc.date.iso=yes", "calc", statement],
stdout=subprocess.PIPE,
env=env,
)
out, err = calc.communicate()
# Workaround for TW-1254 (https://bug.tasktools.org/browse/TW-1254)
return out.decode("utf-8")
# Parse the modified task
original = json.loads(sys.stdin.readline())
modified = sys.stdin.readline()
# Return the unmodified modified task, so it is actually changed
print(modified)
modified = json.loads(modified)
# Has a task with UDA been marked as completed?
if (
(UDA_DUE in original or UDA_WAIT in original)
and original["status"] != "completed"
and modified["status"] == "completed"
):
del original["modified"]
if "start" in original:
del original["start"]
if UDA_DUE in original:
original["due"] = calc(original[UDA_DUE])
if UDA_WAIT in original:
original["wait"] = calc(original[UDA_WAIT])
original["status"] = "waiting"
else:
original["status"] = "pending"
print("Created follow-up task")
original["entry"] = modified["end"]
original["uuid"] = str(uuid.uuid4())
# Wait for taskwarrior to finish, so we can safely `task import` the new
# task.
sys.stdout.flush()
task_pid = os.getppid()
if 0 < os.fork():
sys.exit(0)
else:
# Taskwarrior also waits for stdout to close
try:
os.close(sys.stdout.fileno())
except OSError:
pass # Thrown because of closing stdout. Don't worry, that's fine.
# Wait for taskwarrior to finish
# while os.path.exists("/proc/%s" % str(task_pid)):
time.sleep(1)
# Import the follow-up task
with tempfile.NamedTemporaryFile(mode="wt") as new_task:
new_task.write(json.dumps(original))
new_task.flush()
add = subprocess.Popen(
["task", "rc.verbose=nothing", "import", new_task.name],
env=env,
)
add.communicate()

View file

@ -1,83 +0,0 @@
#!/usr/bin/env python
import json
import sys
import subprocess
import uuid
import os
import tempfile
import time
TIME_FORMAT = "%Y%m%dT%H%M%SZ"
UDA_DUE = "relativeRecurDue"
UDA_WAIT = "relativeRecurWait"
env = os.environ.copy()
env["TZ"] = "UTC0"
# Hand back duration format parsing to task warrior
def calc(statement):
calc = subprocess.Popen(
["task", "rc.verbose=nothing", "rc.date.iso=yes", "calc", statement],
stdout=subprocess.PIPE,
env=env,
)
out, err = calc.communicate()
# Workaround for TW-1254 (https://bug.tasktools.org/browse/TW-1254)
return out.decode("utf-8").rstrip().replace("-", "").replace(":", "") + "Z"
# Parse the modified task
original = json.loads(sys.stdin.readline())
modified = sys.stdin.readline()
# Return the unmodified modified task, so it is actually changed
print(modified)
modified = json.loads(modified)
# Has a task with UDA been marked as completed?
if (
(UDA_DUE in original or UDA_WAIT in original)
and original["status"] != "completed"
and modified["status"] == "completed"
):
del original["modified"]
if "start" in original:
del original["start"]
if UDA_DUE in original:
original["due"] = calc(modified["end"] + "+" + original[UDA_DUE])
if UDA_WAIT in original:
original["wait"] = calc(modified["end"] + "+" + original[UDA_WAIT])
original["status"] = "waiting"
else:
original["status"] = "pending"
print("Created follow-up task")
original["entry"] = modified["end"]
original["uuid"] = str(uuid.uuid4())
# Wait for taskwarrior to finish, so we can safely `task import` the new
# task.
sys.stdout.flush()
task_pid = os.getppid()
if 0 < os.fork():
sys.exit(0)
else:
# Taskwarrior also waits for stdout to close
try:
os.close(sys.stdout.fileno())
except OSError:
pass # Thrown because of closing stdout. Don't worry, that's fine.
# Wait for taskwarrior to finish
while os.path.exists("/proc/%s" % str(task_pid)):
time.sleep(0.25)
# Import the follow-up task
with tempfile.NamedTemporaryFile(mode="wt") as new_task:
new_task.write(json.dumps(original))
new_task.flush()
add = subprocess.Popen(
["task", "rc.verbose=nothing", "import", new_task.name],
env=env,
)
add.communicate()

View file

@ -1,4 +0,0 @@
TWK_SERVER_PORT=3000
DISPLAY_TIME_OF_THE_DAY=1
TWK_USE_FONT='JetBrains Mono'
TWK_THEME=taskwarrior-dark

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,24 +0,0 @@
<div hx-get="tasks/active" hx-trigger="every 60s" hx-swap="outerHTML" hx-target="this">
{% if active_task %}
<div class="join">
</div>
<div class="pl-2.5 pr-6 py-1.5 bg-green-900 text-green-200 shadow-xl rounded-sm flex flex-wrap " id="active-timer">
<span class="flex-grow">{{ active_task.description }}</span>
<div class="join">
<span class="badge badge-success badge-md badge-soft join-item">
{{ timer_value(date=active_task.start) }}
</span>
<button class="btn btn-accent btn-xs join-item"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-swap="innerHTML"
hx-include="[id='filtering']"
hx-vals='{"uuid":"{{ active_task.uuid }}", "action": "ToggleTimer"}'
hx-trigger="click,keyup[key=='o'] from:#cmd-inp">
<span>St<span class="shortcut_key">o</span>p</span>
</button>
</div>
</div>
{% endif %}
</div>

View file

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en" {% if DEFAULT_THEME %}data-theme="{{ DEFAULT_THEME }}" {% endif %}>
<head>
<link rel="stylesheet" href="/dist/style.css"/>
<style>
{% if USE_FONT %}
body {
font-family: '{{ USE_FONT }}', '{{ FALLBACK_FAMILY }}';
}
{% endif %}
</style>
<script src="/dist/bundle.js" type="module"></script>
<title>
Org.Me
</title>
</head>
<body>
<div id="content" class="px-5">
<main>
<div class="toast" id="toast"></div>
<div id="list-of-tasks">{% include "tasks.html" %}</div>
<div id="ledger_things"></div>
</main>
</div>
</body>
</html>

View file

@ -1,18 +0,0 @@
{% macro desc(task) %}
{% if task.annotations %}
<p>
<strong>{{ task.description }}</strong>
</p>
<ul class="pl-4 text-sm">
{% for annotation in task.annotations %}
<li class="list-outside">
[{{date(date=annotation.entry) }}] {{ annotation.description }}
</li>
{% endfor %}
</ul>
{% else %}
<p>
{{ task.description }}
</p>
{% endif %}
{% endmacro desc %}

View file

@ -1,14 +0,0 @@
<div class="items-center justify-center gap-4 rounded-lg bg-black px-5 py-3 text-white z-50"
hx-trigger="load delay:{{ timeout }}s" hx-get="/msg_clr" id="flash_msg" hx-swap="outerHTML">
<span class="text-sm font-medium hover:opacity-75">{{ msg }} {{ timeout }}</span>
<button class="rounded bg-white/20 p-1 hover:bg-white/10" hx-get="/msg_clr" hx-target="#toast" hx-swap="innerHTML">
<span class="sr-only">Close ,,,</span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
<path
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</div>

View file

@ -1,116 +0,0 @@
<div class="pl-2 pr-2 py-1.5 rounded-sm text-xs flex bg-base-100 gap-2 items-center" xmlns:hx-on="http://www.w3.org/1999/xhtml">
<div class="join" id="tag_search_bar">
<button class="btn btn-neutral btn-xs join-item" id="tag-selection-toggle" onclick="window['toggleTagPanel']()">
<span><span class="shortcut_key"
>t</span>ags</span>
</button>
<span class="btn btn-neutral btn-xs join-item" id="task_action_bar">
<button hx-get="task_action_bar" hx-target="#task_action_bar" hx-swap="outerHTML"
hx-trigger="click,keyup[key=='s'] from:#cmd-inp">ta<span class="shortcut_key">s</span>k</button>
</span>
<button class="btn btn-xs btn-neutral join-item"
hx-get="tasks/undo/report"
hx-trigger="click,keyup[{{mod_key}}key=='u'] from:#cmd-inp"
hx-target="#all-dialog-boxes"
hx-swap="innerHTML">
<span><span class="shortcut_key">u</span>ndo</span>
</button>
<button class="btn btn-xs btn-neutral join-item"
hx-get="tasks/add"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='n'] from:#cmd-inp"
hx-target="#all-dialog-boxes"
hx-swap="innerHTML">
<span><span class="shortcut_key">n</span>ew</span>
</button>
</div>
<div class="join">
<button class="btn btn-xs join-item btn-neutral" id="pending" hx-get="tasks?status=pending"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='p'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">p</span>ending</span>
</button>
<button class="btn btn-xs join-item btn-neutral" id="waiting" hx-get="tasks?status=waiting"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='w'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">w</span>aiting</span>
</button>
<button class="btn btn-xs join-item btn-neutral" id="completed"
hx-get="tasks?status=completed"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='c'] from:#cmd-inp"
hx-target="#list-of-tasks" hx-swap="innerHTML">
<span><span class="shortcut_key">c</span>ompleted</span>
</button>
<button class="btn btn-xs join-item btn-neutral"
hx-get="tasks?report=all"
hx-include="[id='filtering']"
hx-target="#list-of-tasks"
hx-trigger="click,keyup[{{mod_key}}key=='a'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">a</span>ll</span>
</button>
</div>
<div class="join">
<button class="btn btn-xs join-item btn-primary" hx-get="tasks?report=next"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='x'] from:#cmd-inp"
hx-swap="innerHTML">
<span>ne<span class="shortcut_key">x</span>t</span>
</button>
<button class="btn btn-xs join-item btn-primary" hx-get="tasks?report=ready"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='r'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">r</span>eady</span>
</button>
<button class="btn btn-xs join-item btn-primary" hx-get="tasks?report=new"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='e'] from:#cmd-inp"
hx-swap="innerHTML">
<span>n<span class="shortcut_key">e</span>w</span>
</button>
</div>
<div class="join grow">
<button class="btn btn-xs join-item btn-neutral" id="priority-h" hx-get="tasks?query=priority:H"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='h'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">H</span></span>
</button>
<button class="btn btn-xs join-item btn-neutral" id="priority-m" hx-get="tasks?query=priority:M"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='m'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">M</span></span>
</button>
<button class="btn btn-xs join-item btn-neutral" id="priority-l" hx-get="tasks?query=priority:L"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[{{mod_key}}key=='l'] from:#cmd-inp"
hx-swap="innerHTML">
<span><span class="shortcut_key">L</span></span>
</button>
</div>
<!-- Other options -->
<div>
<button class="btn btn-xs btn-ghost" id="theme-switcher"></button>
</div>
<!-- CMD BAR -->
<div>
<label class="" for="cmd-inp"></label>
<input type="search" class="input input-xs input-neutral focus:border-base-100 grow input-ghost border-base-200" placeholder="Cmd Bar, Ctrl+Shift+k" id="cmd-inp"
autofocus value="" autocomplete="off" />
</div>
</div>

View file

@ -1,51 +0,0 @@
<div class="flex flex-wrap gap-2 p-4">
<div class="join">
<button
id="tag-btn-back"
class="btn btn-warning btn-xs join-item"
hx-get="tasks"
hx-trigger="click,keyup[key=='Escape'] from:#task-inp"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
><span><span class="shortcut_key">ESC</span></span></button>
<label for="tag-inp" class="hidden"></label>
<input type="text" id="tag-inp"
class="input input-xs input-accent join-item"
placeholder="Tag Bar"
hx-trigger="changes delay:2s"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
autofocus
onkeyup="if (this.value.length >= 2) { document.getElementById(this.value).click() }"
/>
</div>
{% for tag, shortcut in tags_map %}
{% if tag is keyword_tag %}
{% endif %}
{% if tag is user_tag %}
{% endif %}
<div class="mb-2">
<div class="flex gap-2">
<button id="{{shortcut}}"
{% if tag is starting_with('+') %}
class="btn btn-xs btn-accent shrink"
hx-get="tasks?query={{ tag | replace(from='+', to='%2B') }}"
{% elif tag is starting_with('@') %}
class="btn btn-xs btn-info shrink"
hx-get="tasks?query={{ tag | trim_start_matches(pat='@') }}"
{% else %}
class="btn btn-xs btn-neutral shrink"
hx-get="tasks?query={% if tag is starting_with('project:') %}{{ tag }}{% else %}project:{{tag}}{% endif %}"
{% endif %}
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
>{{ shortcut }}</button>
<div class="text-xs pt-1">{{ tag | trim_start_matches(pat='@') }}</div>
</div>
</div>
{% endfor %}
</div>

View file

@ -1,23 +0,0 @@
<div class="join">
<button
id="tag-btn-back"
class="btn btn-warning btn-xs"
hx-get="tasks"
hx-trigger="click,keyup[key=='Escape'] from:#task-inp"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
><span><span class="shortcut_key">ESC</span></span></button>
<label for="task-inp" class="hidden"></label>
<input type="text" id="task-inp"
class="input input-neutral input-xs join-item"
placeholder="Enter Shortcut"
hx-trigger="changes delay:2s"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
autofocus
onkeyup="if (this.value.length >= 2) { document.getElementById(this.value).click() }"
onfocus="document.querySelectorAll('.task-shortcut-tag').forEach((e) => e.classList.remove('hidden'))"
onblur="document.querySelectorAll('.task-shortcut-tag').forEach((e) => e.classList.add('hidden'));"
/>
</div>

View file

@ -1,98 +0,0 @@
{% set bg_color = "bg-neutral-800" %}
<div class="modal-box">
<h2 class="text-lg font-bold text-neutral-content-50">Adding new task</h2>
<form class="mt-2 text-sm" id="task_add_form"
hx-post="tasks/add"
hx-include="[id='filtering']"
hx-target="#list-of-tasks"
>
<div class="my-1">
<label
for="desc"
class="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600 dark:border-neutral-700 dark:{{bg_color}}"
>
<span class="text-xs font-medium text-gray-700 dark:text-gray-200">Description</span>
<input
autofocus
type="text"
id="desc"
name="description"
placeholder="Task description"
class="mt-1 w-full border-none bg-transparent p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm dark:text-white"
/>
</label>
</div>
<div class="my-1">
<label
for="tags"
class="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600 dark:border-gray-700 dark:{{bg_color}}"
>
<span class="text-xs font-medium text-gray-700 dark:text-gray-200">Tags</span>
<input
type="text"
id="tags"
name="tags"
placeholder="Tags. separate by ,"
value="{{ tags }}"
class="mt-1 w-full border-none bg-transparent p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm dark:text-white"
/>
</label>
</div>
<div class="my-1">
<label
for="project"
class="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600 dark:border-gray-700 dark:{{bg_color}}"
>
<span class="text-xs font-medium text-gray-700 dark:text-gray-200">Project</span>
<input
type="text"
id="project"
name="project"
placeholder="Project"
value="{{ project }}"
class="mt-1 w-full border-none bg-transparent p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm dark:text-white"
/>
</label>
</div>
<div class="my-1">
<label
for="additional"
class="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600 dark:border-neutral-700 dark:{{bg_color}}"
>
<span class="text-xs font-medium text-gray-700 dark:text-gray-200">Additional options, these will be added to task parameters directly</span>
<input
autofocus
type="text"
id="additional"
name="additional"
placeholder="Additional options"
class="mt-1 w-full border-none bg-transparent p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm dark:text-white"
/>
</label>
</div>
</form>
<div class="modal-action" id="model-add-task">
<button class="btn btn-md btn-success" id="btn-mdl-yes" form="task_add_form"
hx-trigger="click,keyup[key=='Enter']">
<kbd class="shortcut_key">Enter</kbd>
</button>
<button class="btn btn-md btn-warning"
hx-get="tasks"
hx-trigger="click,keyup[key=='Escape'] from:body"
hx-include="[id='filtering']"
hx-target="#list-of-tasks">
<kbd class="shortcut_key">Esc</kbd>
</button>
</div>
<script>
document.getElementById('all-dialog-boxes').showModal()
</script>
</div>

View file

@ -1,203 +0,0 @@
{% import "desc.html" as desc %}
<div class="modal-box">
<h2 class="text-lg font-bold text-neutral-content-200">Task Details</h2>
<div class="join mb-3">
<button class="btn btn-xs btn-warning join-item"
id="tag-btn-back-details"
hx-get="tasks"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-trigger="click,keyup[key=='Escape'] from:#task-details-inp">
<kbd class="shortcut_key">Esc</kbd>
</button>
<button
class="btn btn-success btn-xs join-item"
id="btn-mark-as-done"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
{% if task.status !="completed" %}
hx-vals='{"status": "completed", "uuid":"{{ task.uuid }}", "action": "StatusUpdate"}'
{% else %}
hx-vals='{"status": "pending", "uuid":"{{ task.uuid }}", "query": "status:completed", "action": "StatusUpdate" }'
{% endif %}
hx-trigger="click,keyup[key=='d'] from:#task-details-inp"
><span><span class="shortcut_key">d</span>one</span></button>
<button
class="btn btn-accent btn-xs join-item"
id="btn-denotate-task"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-vals='{"uuid":"{{ task.uuid }}", "action": "DenotateTask"}'
hx-trigger="click,keyup[key=='n'] from:#task-details-inp"
>
<span>de<span class="shortcut_key">n</span>otate</span>
</button>
<button
class="btn btn-info btn-xs join-item"
id="btn-timer-toggle"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-vals='{"uuid":"{{ task.uuid }}", "action": "ToggleTimer"}'
hx-trigger="click,keyup[key=='s'] from:#task-details-inp">
<span>
{% if task.start %}
<span class="shortcut_key">s</span>top
{% else %}
<span class="shortcut_key">s</span>tart
{% endif %}
</span>
</button>
<span class="join-item">
<label for="task-details-inp" class="hidden"></label>
<input type="text" id="task-details-inp"
class="input input-neutral input-xs join-item"
placeholder="Cmd Bar, Ctrl+Shift+K"
autofocus /></span>
</div>
<table class="table table-xs table-zebra">
<tbody>
<tr>
<th>Description</th>
<td class="text-wrap w-2/3">
{{ desc::desc(task=task) }}
</td>
</tr>
<tr>
<th class="w-1/6">
<label for="task-edit-inp">Modify</label>
</th>
<td>
<input type="text" id="task-edit-inp"
class="input-neutral input input-xs"
placeholder="Edit task with command"
hx-trigger="keyup[key=='Enter'] from:#task-edit-inp"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-include="[this],[id='filtering']"
name="task_entry"
hx-vals='{"uuid":"{{ task.uuid }}", "action": "ModifyTask"}'
/>
</td>
</tr>
<tr>
<th>
<label for="task-annot-inp">Annotate</label>
</th>
<td>
<input type="text" id="task-annot-inp"
class="input-neutral input input-xs"
placeholder="Annotate task"
hx-trigger="keyup[key=='Enter'] from:#task-annot-inp"
hx-post="tasks"
hx-target="#list-of-tasks"
hx-include="[this],[id='filtering']"
name="task_entry"
hx-vals='{"uuid":"{{ task.uuid }}", "action": "AnnotateTask"}'
/>
</td>
</tr>
<tr>
<th>Age</th>
<td>{% if task.entry %}{{ date_proper(date=task.entry) }}{% endif %}</td>
</tr>
<tr>
<th>Depends on</th>
<td>
{% if task.depends %}
{% for uuid in task.depends %}
{%if tasks_db[uuid] %}{{ tasks_db[uuid].id }}{% endif %}
{% endfor %}
{% endif %}
</td>
</tr>
<tr>
<th>Project</th>
<td>
{% if task.project %}
<div class="breadcrumbs text-sm">
<ul>
{% for p in task.project | split(pat=".") %}
<li class="">
{{ p }}
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</td>
</tr>
<tr>
<th>Tags</th>
<td>
<div>
{% if task.tags %}
{% for p in task.tags %}
<span class="badge-sm badge badge-accent">
{{ p }}
</span>
{% endfor %}
{% endif %}
{% if task.priority %}
<span class="badge badge-sm badge-secondary">{{ task.priority }}</span>
{% endif %}
</div>
</td>
</tr>
<tr>
<th>Urgency</th>
<td>{{ task.urgency }}</td>
</tr>
<tr>
{% if task.start %}
<th>Start</th>
<td>
{{ date_proper(date=task.start) }}
</td>
</tr>
<tr>
{% endif %}
{% if task.due and task.status != 'completed' %}
<th>Due</th>
<td>
{{ date_proper(date=task.due, in_future=true) }}
</td>
{% endif %}
</tr>
<tr>
{% if task.scheduled %}
<th>Schd</th>
<td>
{{ date_proper(date=task.scheduled, in_future=true) }}
</td>
{% endif%}
</tr>
<tr>
{% if task.end %}
<th>End</th>
<td>
{{ date_proper(date=task.end) }}
</td>
{% endif %}
</tr>
<tr>
{% if task.recur %}
<th>RECUR</th>
<td>
{{task.recur}}
</td>
{% endif %}
</tr>
</tbody>
</table>
<script>
try {
document.getElementById('task-inp').value = '';
} catch (e) {
}
document.getElementById('all-dialog-boxes').showModal()
</script>
</div>

View file

@ -1,230 +0,0 @@
{% import "desc.html" as desc %}
{% if has_toast %}
<div hx-swap-oob="beforeend:#toast">
<div class="items-center justify-items-center gap-4 px-5 py-3 text-neutral-300 fixed h-18 top-0 left-0 w-full z-50 bg-cyan-700 shadow-xs shadow-black"
hx-trigger="load delay:{{ toast_timeout }}s" hx-get="/msg_clr" id="flash_msg" hx-swap="outerHTML">
<div class="flex flex-row">
<span class="text-sm font-medium hover:opacity-75 flex-grow">{{ toast_msg }}</span>
<span>
<button class="rounded bg-white/20 p-1 hover:bg-white/10" hx-get="/msg_clr" hx-target="#toast"
hx-trigger="click,keyup[key=='Escape'] from:#cmd-inp"
autofocus
hx-swap="innerHTML">
<span class="shortcut_key">[Esc]</span>
</button>
</span>
</div>
</div>
</div>
{% endif %}
<div class="mb-auto h-max">
<dialog id="all-dialog-boxes" class="modal"></dialog>
<div id="task_form_div"></div>
<div id="task_details"></div>
<!-- Open the modal using ID.showModal() method -->
{% set on_all = "all" %}
{% set on_complete = "btn-success" %}
{% set on_pending = "btn-warning" %}
{% set on_waiting = "btn-accent" %}
{% set mod_key = "" %}
<div class="fixed top-0 left-0 h-[18] z-40 w-full pb-2 shadow-sm shadow-black bg-base-100">
{% include 'left_action_bar.html' %}
<!-- TAG LIST -->
<div class="pl-2 flex justify-center join">
{% for f in current_filter %}
<button class="btn btn-xs join-item {% if f is starting_with('project:') %}btn-accent{% else %}btn-neutral {% endif %}"
hx-include="[id='filtering']"
hx-get="tasks?query={{ f | replace(from='+', to='%2B') }}"
hx-target="#list-of-tasks">
{{ remove_project_tag(task=f) }}
</button>
{% endfor %}
<button class="btn btn-disabled btn-xs btn-neutral join-item"></button>
</div>
<input type="hidden" id="filtering" name="filter_value" value="{{ filter_value }}">
<!-- // -->
</div>
<div class="relative overflow-x-auto shadow-md sm:rounded-b-lg overflow-y-auto mt-20 pt-0 pb-2 mb-5">
{% if display_time_of_the_day == 1 %}
<div class="justify-start items-center h-4" id="time_of_the_day">
<div class="flex-1 w-full rounded-sm text-accent-content text-xs">
<div class="[min-width:4px] mt-1 bg-accent shadow-inner shadow-accent rounded-sm fill-accent px-2 content-end">
</div>
</div>
</div>
{% endif %}
<span hx-get="tasks/active" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></span>
<div class="grid grid-cols-1">
<div id="tags_map_drawer" class="pt-4 hidden mb-2">
<div class="flex flex-wrap gap-2 p-4 bg-base-300">
<div class="join">
<button
id="tag-btn-back"
class="btn btn-warning btn-xs join-item"
hx-get="tasks"
hx-trigger="click,keyup[key=='Escape'] from:#task-inp"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
><span><span class="shortcut_key">ESC</span></span></button>
<label for="tag-inp" class="hidden"></label>
<input type="text" id="tag-inp"
class="input input-xs input-accent join-item"
placeholder="Tag Bar"
hx-trigger="changes delay:2s"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
autofocus
onkeyup="if (this.value.length >= 2) { document.getElementById(this.value).click() }"
/>
</div>
{% for tag, shortcut in tags_map %}
{% if tag is keyword_tag %}
{% endif %}
{% if tag is user_tag %}
{% endif %}
<div class="mb-2">
<div class="flex gap-2">
<button id="{{shortcut}}"
{% if tag is starting_with('+') %}
class="btn btn-xs btn-accent-content shrink"
hx-get="tasks?query={{ tag | replace(from='+', to='%2B') }}"
{% elif tag is starting_with('@') %}
class="btn btn-xs btn-info shrink"
hx-get="tasks?query={{ tag | trim_start_matches(pat='@') }}"
{% else %}
class="btn btn-xs btn-neutral shrink"
hx-get="tasks?query={% if tag is starting_with('project:') %}{{ tag }}{% else %}project:{{tag}}{% endif %}"
{% endif %}
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
>{{ shortcut }}</button>
<div class="text-xs pt-1">{{ tag | trim_start_matches(pat='@') | trim_start_matches(pat='project:') }}</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div>
<ul class="list bg-base-100 rounded-box shadow-md text-sm">
{% for task in tasks %}
<li class="list-row {% if task.start %} bg-green-700 text-green-200 {% endif %} p-2">
<div>
<input type="checkbox"
class="checkbox checkbox-sm"
name="checkbox-{{ task.uuid }}"
id="{{ task_shortcuts[task.uuid] }}"
hx-trigger="change"
hx-post="tasks" hx-target="#list-of-tasks"
hx-include="[id='filtering']"
{% if task.status !="completed" %}
hx-vals='{"status": "completed", "uuid":"{{ task.uuid }}", "action": "StatusUpdate"}'
hx-swap="innerHTML"
{% else %}
checked="checked"
hx-vals='{"status": "pending", "uuid":"{{ task.uuid }}", "query": "status:completed", "action": "StatusUpdate" }'
hx-swap="innerHTML"
{% endif %}>
<button class="btn btn-xs btn-primary hidden task-shortcut-tag">{{ task_shortcuts[task.uuid] }}</button>
<button
id="{{ task_shortcuts[task.id] }}"
class="btn btn-secondary static btn-xs is-a-tag min-w-12"
hx-trigger="click"
hx-get="task_details?task_id={{ task.uuid }}"
hx-target="#all-dialog-boxes"
>
{{ task.id }} <span class="shortcut_key hidden task-shortcut-tag">{{ task_shortcuts[task.id] }}</span>
</button>
</div>
<div class="max-w-3xl">
{{ desc::desc(task=task) }}
</div>
<div class="join">
{% if task.project %}
{% for p in task.project | split(pat=".") %}
{% set ptag = ["project", p] | join(sep=":") %}
<button class="join-item btn btn-accent btn-xs is-a-tag"
hx-include="[id='filtering']"
hx-target="#list-of-tasks"
hx-get="tasks?query=project:{{ project_name(full_name=task.project, index=loop.index) }}">
{{ p }}
</button>
{% endfor %}
{% endif %}
{% if task.priority %}
<button class="btn btn-xs {{ task.priority }} btn-neutral"
hx-get="tasks?query=priority:{{ task.priority }}"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML"
>{{ task.priority }}
</button>
{% endif %}
{% if task.tags %}
{% for p in task.tags %}
<button class="btn btn-xs btn-neutral join-item is-a-tag"
hx-get="tasks?query={{ p | replace(from='+', to='%2B') }}"
hx-target="#list-of-tasks"
hx-include="[id='filtering']"
hx-swap="innerHTML">
{{ p }}
</button>
{% endfor %}
{% else %}
<button class="btn btn-disabled btn-xs btn-neutral join-item"></button>
{% endif %}
</div>
<div class="join">
{% if task.depends %}
{% for uuid in task.depends %}
{%if tasks_db[uuid] %}
<button class="btn btn-secondary btn-xs is-a-tag join-item"
hx-trigger="click"
hx-get="task_details?task_id={{ tasks_db[uuid].uuid }}"
hx-target="#task_details">
{{ tasks_db[uuid].id }}
</button>
{% endif %}
{% endfor %}
{% endif %}
{% if task.urgency > 20 %}
<div class="btn btn-xs btn-warning join-item">{{ task.urgency }}</div>
{% elif task.urgency > 10 %}
<div class="btn btn-xs btn-primary join-item">{{ task.urgency }}</div>
{% else %}
<div class="btn btn-xs btn-neutral join-item">
{{ task.urgency }}</div>
{% endif %}
{% if task.due and task.status != 'completed' %}
<div class="btn btn-neutral btn-xs join-item">
{{ date_proper(date=task.due, in_future=true) }}
</div>
{% endif %}
{% if task.start %}
<div class="btn btn-neutral btn-xs join-item">{{ date_proper(date=task.start) }}</div>
{% endif %}
{% if task.end %}
<div class="btn btn-neutral btn-xs join-item">{{ date_proper(date=task.end) }}</div>
{% endif %}
<div class="btn btn-neutral btn-xs join-item">
{% if task.entry %}{{ date_proper(date=task.entry) }}{% endif %}
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>

View file

@ -1,32 +0,0 @@
<div class="modal-box">
<h2 class="text-lg font-bold text-neutral-50">{{ heading }}</h2>
<p class="mt-2 text-sm text-neutral-400">
The undo command is not reversible. Are you sure you want to revert to the previous state?
<ul class="text-neutral-500 text-sm mb-4">
{% for line in report %}
<li class="mt-2">{{line | replace(from='\t', to=' ') }}</li>
{% endfor %}
</ul>
</p>
<div class="modal-action" id="model-undo">
<button class="btn btn-warning btn-md"
id="btn-mdl-yes"
hx-include="[id='filtering']"
hx-target="#list-of-tasks"
hx-trigger="click,keyup[key=='Enter'] from:body"
hx-post="tasks/undo/confirmed">
<kbd class="shortcut_key">Enter</kbd> Yes, Sure
</button>
<button class="btn btn-success btn-md"
hx-get="tasks"
hx-trigger="click,keyup[key=='Escape'] from:all-dialog-boxes"
hx-include="[id='filtering']"
hx-target="#list-of-tasks">
<kbd class="shortcut_key">Esc</kbd> Cancel
</button>
</div>
<script>
document.getElementById('all-dialog-boxes').showModal()
</script>
</div>

Binary file not shown.

View file

@ -1,6 +0,0 @@
# !/bin/bash
# Run taskwarrior with debug
#
cd /home/emenel/.local/bin/tww/
RUST_LOG=trace ./taskwarrior-web

View file

@ -77,7 +77,7 @@ ${shared-alias}
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 prtsc esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 prtsc
grv 1 2 3 4 5 6 7 8 9 0 - = \ del home grv 1 2 3 4 5 6 7 8 9 0 - = \ del home
tab q w e r t y u i o p [ ] bspc end tab q w e r t y u i o p [ ] bspc end
@supesc a s d f g h j k l ; ' ret pgup @supesc @a @s @d f g h j k l ; ' ret pgup
@sp-lsft z x c v b n m , . / @sp-rsft up pgdn @sp-lsft z x c v b n m , . / @sp-rsft up pgdn
lmet @controls lalt lctrl @spcnav rctrl ralt rmet left down right) lmet @controls lalt lctrl @spcnav rctrl ralt rmet left down right)
@ -85,7 +85,7 @@ ${shared-alias}
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 prtsc esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 prtsc
grv 1 2 3 4 5 6 7 8 9 0 - = \ del home grv 1 2 3 4 5 6 7 8 9 0 - = \ del home
tab q w e r t home pgdn pgup end p [ ] bspc end tab q w e r t home pgdn pgup end p [ ] bspc end
caps a s d f g left down up right ; ' ret pgup caps _ _ _ f g left down up right ; ' ret pgup
@sp-lsft z x c v b n m , . / @sp-rsft up pgdn @sp-lsft z x c v b n m , . / @sp-rsft up pgdn
lmet @controls lalt lctrl _ rctrl ralt rmet left down right) lmet @controls lalt lctrl _ rctrl ralt rmet left down right)
@ -93,7 +93,7 @@ ${shared-alias}
esc VolumeMute VolumeDown VolumeUp f4 MediaTrackPrevious MediaPlayPause MediaTrackNext f8 f9 f10 f11 f12 prtsc esc VolumeMute VolumeDown VolumeUp f4 MediaTrackPrevious MediaPlayPause MediaTrackNext f8 f9 f10 f11 f12 prtsc
grv 1 2 3 4 5 6 7 8 9 0 - = \ del home grv 1 2 3 4 5 6 7 8 9 0 - = \ del home
tab q w e r t y u i o MediaPlayPause [ ] bspc end tab q w e r t y u i o MediaPlayPause [ ] bspc end
@supesc a s d f g MediaTrackPrevious VolumeDown VolumeUp MediaTrackNext ; ' ret pgup @supesc _ _ _ f g MediaTrackPrevious VolumeDown VolumeUp MediaTrackNext ; ' ret pgup
@sp-lsft z x c v b n VolumeMute , . / @sp-rsft pgup _ @sp-lsft z x c v b n VolumeMute , . / @sp-rsft pgup _
lmet lmet lalt lctrl _ rctrl ralt rmet home pgdn end) lmet lmet lalt lctrl _ rctrl ralt rmet home pgdn end)
''; '';

View file

@ -1,107 +0,0 @@
{ lib
, stdenv
, fetchFromGitHub
, cmake
, pkg-config
, alsa-lib
, freetype
, webkitgtk
, curl
, fftwFloat
, jack2
, xorg
, pcre2
, pcre
, libuuid
, libselinux
, libsepol
, libthai
, libdatrie
, libxkbcommon
, libepoxy
, libsysprof-capture
, sqlite
, libpsl
}:
let
buildType = "Release";
in
stdenv.mkDerivation (finalAttrs: {
pname = "paulxstretch";
version = "1.6.0";
src = fetchFromGitHub {
owner = "essej";
repo = finalAttrs.pname;
rev = "v${finalAttrs.version}";
sha256 = "sha256-Oen9W7frt7l1m9YVJCFSIDKXdmj8tWrYx68+V2Mozt0=";
fetchSubmodules = true;
};
nativeBuildInputs = [ cmake pkg-config ];
buildInputs = [
freetype
alsa-lib
webkitgtk
curl
fftwFloat
jack2
xorg.libX11
xorg.libXext
xorg.libXinerama
xorg.xrandr
xorg.libXcursor
xorg.libXfixes
xorg.libXrender
xorg.libXScrnSaver
];
# JUCE dlopens these, make sure they are in rpath
# Otherwise, segfault will happen
NIX_LDFLAGS = (toString [
"-lX11"
"-lXext"
"-lXcursor"
"-lXinerama"
"-lXrandr"
"-lXfixes"
"-lXrender"
"-lXss"
]);
# Needed for LTO to work, currently unsure as to why
cmakeFlags = [
"-DCMAKE_AR=${stdenv.cc.cc}/bin/gcc-ar"
"-DCMAKE_RANLIB=${stdenv.cc.cc}/bin/gcc-ranlib"
"-DCMAKE_NM=${stdenv.cc.cc}/bin/gcc-nm"
];
cmakeBuildType = buildType;
installPhase = let
vst3path = "${placeholder "out"}/lib/vst3";
binpath = "${placeholder "out"}/bin";
clappath = "${placeholder "out"}/lib/clap";
in
''
runHook preInstall
mkdir -p ${vst3path}
mkdir -p ${binpath}
mkdir -p ${clappath}
cp -R PaulXStretch_artefacts/${buildType}/VST3/* ${vst3path}
cp -R PaulXStretch_artefacts/${buildType}/Standalone/* ${binpath}
cp -R PaulXStretch_artefacts/${buildType}/CLAP/* ${clappath}
runHook postInstall
'';
meta = with lib; {
description = "Extreme timestretch plugin";
homepage = "https://sonosaurus.com/paulxstretch/";
license = licenses.gpl3;
platforms = platforms.linux;
maintainers = with maintainers; [ polygon ];
};
})

View file

@ -1,34 +0,0 @@
{ stdenv, pkgs, unzip, autoPatchelfHook, fetchurl, lib, ... }:
stdenv.mkDerivation {
pname = "tasklite";
version = "ci";
src = fetchurl {
url = "https://productionresultssa18.blob.core.windows.net/actions-results/3145698a-7fd9-415c-99d6-d74d4dfc1a7a/workflow-job-run-015d34fc-67a3-589c-a72e-541495a912de/artifacts/653fbd898f6c68fd4665912e4d0b14e295fe658fbdd60da07ab9cd8ac0793d65.zip?rscd=attachment%3B+filename%3D%22tasklite_linux_x86_64.zip%22&se=2025-04-03T17%3A06%3A50Z&sig=CVkJI8x6BFh1D2dRJZVAeqUeQ26%2BQpE0VYBfslOYrGM%3D&ske=2025-04-04T04%3A23%3A10Z&skoid=ca7593d4-ee42-46cd-af88-8b886a2f84eb&sks=b&skt=2025-04-03T16%3A23%3A10Z&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skv=2025-01-05&sp=r&spr=https&sr=b&st=2025-04-03T16%3A56%3A45Z&sv=2025-01-05";
sha256 = "2b8c98d8adbc56ebccf17f175a52e6633c16562924ef2bdca62a21a273f0051a";
};
nativeBuildInputs = [ unzip autoPatchelfHook ];
buildInputs = with pkgs; [
libz
gmp
stdenv
];
unpackPhase = ''
unzip $src
'';
installPhase = ''
mkdir -p $out/bin
cp tasklite $out/bin
'';
meta = with lib; {
homepage = "";
description = "";
platforms = platforms.linux;
};
}