a lightweight, interval-based utility to combat digital strain through "Ma" (intentional pauses) for the eyes and body.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(ay11): make rhythm tab keyboard and ARIA accessible

+99 -16
+19 -2
ui/components/buttons.slint
··· 9 9 min-width: 100px; 10 10 preferred-width: 160px; 11 11 12 + accessible-role: AccessibleRole.button; 13 + accessible-label: root.text; 14 + accessible-action-default => { root.clicked(); } 15 + 16 + fs := FocusScope { 17 + key-pressed(event) => { 18 + if event.text == " " || event.text == Key.Return { 19 + root.clicked(); 20 + return EventResult.accept; 21 + } 22 + EventResult.reject 23 + } 24 + } 25 + 12 26 ta := TouchArea { 13 27 clicked => { 28 + fs.focus(); 14 29 root.clicked(); 15 30 } 16 31 } 17 32 18 33 Rectangle { 19 34 border-radius: 6px; 20 - background: Theme.surface; 35 + background: ta.has-hover ? Theme.surface-hov : Theme.surface; 21 36 border-width: 1px; 22 - border-color: Theme.line; 37 + border-color: fs.has-focus ? Theme.accent-muted : Theme.line; 38 + animate background { duration: 120ms; } 39 + animate border-color { duration: 120ms; } 23 40 24 41 Text { 25 42 text: root.text;
+58 -6
ui/components/chips.slint
··· 9 9 spacing: 6px; 10 10 alignment: center; 11 11 12 - for label[i] in root.labels: chip-ta := TouchArea { 12 + for label[i] in root.labels: chip-root := Rectangle { 13 13 height: 32px; 14 14 min-width: 48px; 15 - clicked => { 15 + 16 + accessible-role: AccessibleRole.radio-button; 17 + accessible-label: label; 18 + accessible-checked: i == root.selected-index; 19 + accessible-action-default => { 16 20 root.selected-index = i; 17 21 root.selection-changed(i); 18 22 } 19 23 24 + chip-fs := FocusScope { 25 + key-pressed(event) => { 26 + if event.text == " " || event.text == Key.Return { 27 + root.selected-index = i; 28 + root.selection-changed(i); 29 + return EventResult.accept; 30 + } 31 + EventResult.reject 32 + } 33 + } 34 + 35 + chip-ta := TouchArea { 36 + clicked => { 37 + chip-fs.focus(); 38 + root.selected-index = i; 39 + root.selection-changed(i); 40 + } 41 + } 42 + 20 43 Rectangle { 21 44 border-radius: 6px; 22 45 background: i == root.selected-index 23 46 ? Theme.btn-bg 24 47 : (chip-ta.has-hover ? Theme.surface-hov : Theme.surface); 25 48 border-width: 1px; 26 - border-color: i == root.selected-index ? transparent : Theme.line; 49 + border-color: chip-fs.has-focus 50 + ? Theme.accent-muted 51 + : (i == root.selected-index ? transparent : Theme.line); 27 52 animate background { duration: 120ms; } 53 + animate border-color { duration: 120ms; } 28 54 29 55 HorizontalLayout { 30 56 padding-left: 12px; ··· 53 79 spacing: 6px; 54 80 alignment: center; 55 81 56 - for name in root.profile-names: chip-ta := TouchArea { 82 + for name in root.profile-names: chip-root := Rectangle { 57 83 height: 32px; 58 84 min-width: 48px; 59 - clicked => { 85 + 86 + accessible-role: AccessibleRole.radio-button; 87 + accessible-label: name; 88 + accessible-checked: name == root.active-profile; 89 + accessible-action-default => { 60 90 root.active-profile = name; 61 91 root.selection-changed(name); 62 92 } 63 93 94 + chip-fs := FocusScope { 95 + key-pressed(event) => { 96 + if event.text == " " || event.text == Key.Return { 97 + root.active-profile = name; 98 + root.selection-changed(name); 99 + return EventResult.accept; 100 + } 101 + EventResult.reject 102 + } 103 + } 104 + 105 + chip-ta := TouchArea { 106 + clicked => { 107 + chip-fs.focus(); 108 + root.active-profile = name; 109 + root.selection-changed(name); 110 + } 111 + } 112 + 64 113 Rectangle { 65 114 border-radius: 6px; 66 115 background: name == root.active-profile 67 116 ? Theme.btn-bg 68 117 : (chip-ta.has-hover ? Theme.surface-hov : Theme.surface); 69 118 border-width: 1px; 70 - border-color: name == root.active-profile ? transparent : Theme.line; 119 + border-color: chip-fs.has-focus 120 + ? Theme.accent-muted 121 + : (name == root.active-profile ? transparent : Theme.line); 71 122 animate background { duration: 120ms; } 123 + animate border-color { duration: 120ms; } 72 124 73 125 HorizontalLayout { 74 126 padding-left: 12px;
+17 -2
ui/components/inputs.slint
··· 183 183 in-out property <float> value: 0.5; 184 184 private property <length> fill-w: root.width * root.value; 185 185 186 - width: 200px; 187 - height: 16px; 186 + min-width: 120px; 187 + height: 28px; 188 188 animate fill-w { duration: 80ms; } 189 189 190 190 Rectangle { ··· 215 215 drop-shadow-color: Theme.shadow; 216 216 } 217 217 218 + fs := FocusScope { 219 + key-pressed(event) => { 220 + if event.text == Key.RightArrow || event.text == Key.UpArrow { 221 + root.value = min(1.0, root.value + 0.05); 222 + return EventResult.accept; 223 + } 224 + if event.text == Key.LeftArrow || event.text == Key.DownArrow { 225 + root.value = max(0.0, root.value - 0.05); 226 + return EventResult.accept; 227 + } 228 + EventResult.reject 229 + } 230 + } 231 + 218 232 TouchArea { 219 233 accessible-role: slider; 220 234 accessible-label: "Volume"; ··· 228 242 } 229 243 pointer-event(e) => { 230 244 if e.kind == PointerEventKind.down { 245 + fs.focus(); 231 246 root.value = max(0.0, min(1.0, self.mouse-x / parent.width)); 232 247 } 233 248 }
+5 -6
ui/views/rhythm_tab.slint
··· 61 61 62 62 Rectangle { horizontal-stretch: 1; } 63 63 64 - PaperToggle { checked <=> root.enforced-mode; } 64 + PaperToggle { checked <=> root.enforced-mode; label: "Enforced mode"; } 65 65 } 66 66 67 67 HorizontalLayout { ··· 88 88 89 89 Rectangle { horizontal-stretch: 1; } 90 90 91 - PaperToggle { checked <=> root.idle-detection-enabled; } 91 + PaperToggle { checked <=> root.idle-detection-enabled; label: "Pause on idle"; } 92 92 } 93 93 94 94 HorizontalLayout { ··· 133 133 134 134 Rectangle { horizontal-stretch: 1; } 135 135 136 - PaperToggle { checked <=> root.sound-enabled; } 136 + PaperToggle { checked <=> root.sound-enabled; label: "Chime on break start"; } 137 137 } 138 138 139 139 HorizontalLayout { 140 140 padding-bottom: 12px; 141 141 spacing: 12px; 142 - alignment: start; 143 142 144 143 Text { 145 144 text: "volume"; ··· 148 147 vertical-alignment: center; 149 148 } 150 149 151 - VolumeSlider { value <=> root.sound-volume; } 150 + VolumeSlider { value <=> root.sound-volume; horizontal-stretch: 1; } 152 151 } 153 152 154 153 PaperDivider { } ··· 165 164 166 165 Rectangle { horizontal-stretch: 1; } 167 166 168 - PaperToggle { checked <=> root.autostart; } 167 + PaperToggle { checked <=> root.autostart; label: "Launch with system"; } 169 168 } 170 169 171 170 HorizontalLayout {