Commit cd5ce69f authored by ransome1's avatar ransome1
Browse files

Added toggle to show/hide empty filters in sidebar

parent 27d62115
......@@ -155,9 +155,6 @@ nav ul li.is-highlighted a {
#todoTable .flex-table:hover .flex-row.todoTableItemMore a {
color: #CCCDCF;
}
#todoTable .flex-table.completed {
opacity: 0.4;
}
#todoTable .flex-table.due .button {
color: #f5f5f5;
}
......@@ -176,18 +173,18 @@ nav ul li.is-highlighted a {
#todoTable .flex-table .flex-row.itemDueDate {
color: white;
}
#todoTable .flex-table .flex-row.itemDueDate .fa-sort-down {
color: #3B3B3B;
#todoTable .flex-table .flex-row.itemDueDate i {
color: inherit;
}
#todoTable .flex-table .flex-row.itemDueDate.isToday,
#todoTable .flex-table .flex-row.itemDueDate.isPast {
color: #ff3860;
}
#todoTable .flex-table .flex-row.itemDueDate.isToday .fa-sort-down,
#todoTable .flex-table .flex-row.itemDueDate.isPast .fa-sort-down {
#todoTable .flex-table .flex-row.itemDueDate.isToday i,
#todoTable .flex-table .flex-row.itemDueDate.isPast i {
color: inherit;
}
#todoTable .flex-table .flex-row.itemDueDate.isTomorrow .fa-sort-down {
#todoTable .flex-table .flex-row.itemDueDate.isTomorrow i {
color: #fa745e !important;
}
#todoTable .flex-table .flex-row span.contexts {
......
{"version":3,"sourceRoot":"","sources":["../scss/dark.scss","../scss/variables.scss"],"names":[],"mappings":"AAGA;EACE,kBCOa;EDNb;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;AAAA;EAEE;;;AAEF;AAAA;AAAA;EAGE,OCfa;;;ADiBf;AAAA;AAAA;EAGE;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;EACA;;;AAEF;EACE;;;AAEF;AAAA;EAEE;EACA;;;AAEF;EACE;EACA;;AACA;EACE;;;AAGJ;AAAA;EAEE;;AACA;AAAA;EACE;;;AAGJ;AAAA;EAEE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE,kBClFY;;ADmFZ;EACE,OCxFW;;AD2FX;EACE;;AAGA;EACE,OChGO;EDiGP;;AAEF;AAAA;EAEE,OCrGO;EDsGP;EACA,kBClGW;;ADqGf;EACE,OC3GS;ED4GT;EACA,kBCxGa;;;AD8Gf;EACE;;AAEF;EACE;;;AAIN;EACE,kBCtHa;;ADuHb;EACE;;;AAIF;EACE;EACA;;;AAIF;EACE,kBCpIe;;ADsIjB;EACE,OC5IW;;AD8Ib;EACE;;AAGA;EACE,OCpJS;;ADuJb;EACE,cClJe;;ADmJf;EACE,OCzJS;;AD2JX;EACE;;AAEF;EACE,OC/JS;;ADiKX;EACE;;AACA;EACE,OC/JW;;ADkKf;AAAA;EAEE,OCjKY;;ADkKZ;AAAA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE,OC7LO;ED8LP;;AAGJ;EACE,OClMS;;ADoMX;EACE,YChMa;EDiMb;;AAEF;EACE,YCrMQ;;;AD0MZ;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAGA;AAAA;AAAA;AAAA;EAIE;;AAEF;EACE,YC5Na;;;ADiOjB;AAAA;EAEE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE,YC/OU;;ADgPV;EACE,cC/OS;;;ADmPf;EACE,YCrPiB;;ADsPjB;EACE,OC5PW;;;ADgQb;EACE;;AACA;EACE;;AACA;EACE;;AAIN;EACE;;AAEF;EACE;;AAEF;EACE;;;AAIF;EACE,YChRe;;ADiRf;EACE;EACA;;AAGJ;EACE;;;AAIF;EACE,OCpRoB;EDqRpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE,OCjSoB;EDkSpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE;;;AAKA;EACE,kBChUM;;ADkUR;EACE;;AAEF;EACE;;AAEF;EACE;;;AAMF;EACE,YC9Ua;ED+Ub,OCpVS;;ADqVT;EACE;;AAEF;AACE;AAAA;AAAA;;AAIF;AAAA;EAEE,cC3VM;;;ADqWd;EACE;;AACA;EACE;;AAEF;EACE;;AAEF;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE;EACA;;AAEF;AAAA;EAEE,YC5Xe;ED6Xf;;AAEF;AAAA;EAEE;;AAEF;AAAA;AAAA;EAGE;;AAEF;EACE;;AAEF;EACE;EACA,cC/YQ;;ADiZV;EACE,cCrZW;;ADuZb;EACE;EACA,cCzZW;;;AD4Zf;EACE;;AACA;EACE;;AAEF;EACE,OClaW;EDmaX;;AACA;EACE;;;AAKJ;AAAA;EAEE;EACA;EACA;;;AAGJ;EACE;;AACA;EACE;;AAEF;AAAA;EAEE;;AAEF;AAAA;EAEE;;AAEF;EACE,YC3bU;ED4bV;;AACA;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE,OCxcQ;EDycR;;AAEF;AAAA;EAEE,OC7cQ;ED8cR,YCldS;;;ADudb;EACE;;AAEF;AAAA;EAEE,OC5dW","file":"dark.css"}
\ No newline at end of file
{"version":3,"sourceRoot":"","sources":["../scss/dark.scss","../scss/variables.scss"],"names":[],"mappings":"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","file":"dark.css"}
\ No newline at end of file
......@@ -302,7 +302,7 @@ nav ul:nth-child(2) {
}
#drawerContainer #handle {
position: absolute;
right: 0;
right: -1em;
top: 0;
height: 100%;
width: 1em;
......@@ -376,8 +376,7 @@ nav ul:nth-child(2) {
z-index: 35;
}
#drawerContainer .drawer .is-greyed-out {
opacity: 0.75;
-webkit-filter: grayscale(100%);
filter: opacity(75%) grayscale(100%);
}
#drawerContainer .drawer .button.is-greyed-out {
cursor: default;
......@@ -522,7 +521,7 @@ nav ul:nth-child(2) {
background: none;
}
#todoTable .flex-table .flex-row span.tag {
margin-right: 0.25em;
margin: 0.25em 0.25em 0 0;
}
#todoTable .flex-table .flex-row span.tag.projects {
background: #f1d6f1;
......@@ -540,9 +539,12 @@ nav ul:nth-child(2) {
max-width: 88%;
cursor: pointer;
color: #4a4a4a;
}
#todoTable .flex-table .flex-row.text svg {
color: inherit;
/*svg {
color: inherit;
}*/
/*.categories {
margin-bottom: .5em;
}*/
}
#todoTable .flex-table .flex-row.text .button {
font-size: 1em;
......@@ -555,8 +557,8 @@ nav ul:nth-child(2) {
color: #666666;
margin-right: 0.5em;
}
#todoTable .flex-table .flex-row.text .categories {
padding: 0.5em;
#todoTable .flex-table .flex-row.text .text {
margin-right: 0.5em;
}
#todoTable .flex-table .flex-row.spacer {
width: 0.5em;
......@@ -607,6 +609,7 @@ nav ul:nth-child(2) {
position: absolute;
top: -1.4em;
right: -1.5em;
z-index: 60;
display: none;
}
#todoTable .flex-table .flex-row.itemDueDate .tags .tag {
......@@ -684,11 +687,9 @@ nav ul:nth-child(2) {
display: block;
}
#todoTable .flex-table.completed .flex-row {
opacity: 0.5;
-webkit-filter: grayscale(100%);
filter: opacity(50%) grayscale(100%);
}
#todoTable .flex-table.completed .flex-row.todoTableItemMore {
opacity: 1;
-webkit-filter: none;
}
......@@ -1033,7 +1034,8 @@ nav ul:nth-child(2) {
.modal.content .modal-card {
z-index: 60;
background: #ebebeb;
padding: 2em;
padding: 0 2em 2em 2em;
max-height: calc(100vh - 5em);
border-radius: 0.25rem;
}
.modal.content .modal-background {
......
This diff is collapsed.
......@@ -127,6 +127,24 @@
</td>
</tr>
</table>
<table>
<tr>
<th colspan="100%" id="viewHeadlineFilterList"></th>
</tr>
<tr>
<td>
<p id="viewToggleShowEmptyFilters"></p>
</td>
<td>
<span class="toggle">
<label class="switch" for="showEmptyFilters">
<input type="checkbox" id="showEmptyFilters" class="viewToggle" tabindex="0">
<span class="slider round"></span>
</label>
</span>
</td>
</tr>
</table>
<table>
<tr>
<th colspan="100%" id="viewHeadlineAppView"></th>
......@@ -145,7 +163,7 @@
</td>
</tr>
<tr>
<td>Zoom</td>
<td id="viewToggleZoom"></td>
<td class="zoom">
<input type="range" id="zoomRangePicker" name="vol" min="75" max="125"><br>
<span id="zoomStatus"></span><span id="zoomUndo"><i class="fas fa-undo"></i></span>
......
......@@ -3,7 +3,6 @@ import { userData, handleError, translations, setUserData, startBuilding, _paq }
import { items, generateGroups, generateTable } from "./todos.mjs";
import { isToday, isPast, isFuture } from "./date.mjs";
//const modalFormInput = document.getElementById("modalFormInput");
const todoTableSearch = document.getElementById("todoTableSearch");
const autoCompleteContainer = document.getElementById("autoCompleteContainer");
const todoFilters = document.getElementById("todoFilters");
......@@ -23,35 +22,51 @@ filterMenuSave.innerHTML = translations.save;
filterMenuDelete.innerHTML = translations.delete;
function saveFilter(newFilter, oldFilter, category) {
items.objects.forEach((item) => {
if(category!=="priority" && item[category]) {
const index = item[category].findIndex((el) => el === oldFilter);
item[category][index] = newFilter;
} else if(category==="priority" && item[category]===oldFilter) {
item[category] = newFilter.toUpperCase();
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
try {
items.objects.forEach((item) => {
if(category!=="priority" && item[category]) {
const index = item[category].findIndex((el) => el === oldFilter);
item[category][index] = newFilter;
} else if(category==="priority" && item[category]===oldFilter) {
item[category] = newFilter.toUpperCase();
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Filter-Drawer", "Filter renamed"]);
return Promise.resolve("Success: Filter renamed");
} catch(error) {
error.functionName = saveFilter.name;
return Promise.reject(error);
}
}
function deleteFilter(filter, category) {
items.objects.forEach((item) => {
if(category!=="priority" && item[category]) {
const index = item[category].indexOf(filter);
if(index!==-1) item[category].splice(index, 1);
if(item[category].length===0) item[category] = null;
} else if(category==="priority" && item[category]===filter) {
item[category] = null;
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
try {
items.objects.forEach((item) => {
if(category!=="priority" && item[category]) {
const index = item[category].indexOf(filter);
if(index!==-1) item[category].splice(index, 1);
if(item[category].length===0) item[category] = null;
} else if(category==="priority" && item[category]===filter) {
item[category] = null;
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Filter-Drawer", "Filter deleted"]);
return Promise.resolve("Success: Filter deleted");
} catch(error) {
error.functionName = deleteFilter.name;
return Promise.reject(error);
}
}
function filterItems(items, searchString) {
try {
......@@ -134,8 +149,14 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
categories.forEach((category) => {
// array to collect all the available filters in the data
let filters = new Array();
let temp;
// run the array and collect all possible filters, duplicates included
items.objects.forEach((item) => {
if(userData.showEmptyFilters) {
temp = items.objects;
} else {
temp = items.filtered;
}
temp.forEach((item) => {
// check if the object has values in either the project or contexts field
if(item[category]) {
// push all filters found so far into an array
......@@ -180,23 +201,6 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
// remove duplicates from available filters
// https://wsvincent.com/javascript-remove-duplicates-array/
filters = [...new Set(filters.join(",").split(","))];
// filter persisted filters
/*if(userData.selectedFilters && userData.selectedFilters.length>0) {
selectedFilters = JSON.parse(userData.selectedFilters);
// check if selected filters is still part of all available filters
selectedFilters.forEach(function(selectedFilter,index){
if(selectedFilter[1]==category) {
// category found, but the selected filter is not part of available filters
if(!filters.includes(selectedFilter[0])) {
// delete persisted filters
selectedFilters.splice(index, 1);
// persist the change
setUserData("selectedFilters", JSON.stringify(selectedFilters));
}
}
});
}*/
// TODO: basically a duplicate
// count reduced filter when persisted filters are present
let filtersReduced = new Array();
......@@ -233,7 +237,6 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
return filters;
}
}, {});
// build the filter buttons
if(filters[0]!="" && filters.length>0) {
generateFilterButtons(category, autoCompleteValue, autoCompletePrefix, caretPosition).then(response => {
......@@ -328,6 +331,7 @@ function generateFilterButtons(category, autoCompleteValue, autoCompletePrefix,
// add the headline before category container
todoFiltersContainer.appendChild(todoFilterHeadline);
}
// to figure out how many buttons with filters behind them have been build in the end
// build one button each
for (let filter in filtersCounted) {
// skip this loop if no filters are present
......@@ -352,25 +356,37 @@ function generateFilterButtons(category, autoCompleteValue, autoCompletePrefix,
filterMenu.classList.add("is-active");
filterMenuInput.value = filter;
filterMenuInput.focus();
filterMenuInput.addEventListener("keyup", function(event) {
filterMenuInput.onkeyup = function(event) {
if(event.key === "Escape") filterMenu.classList.remove("is-active");
if(event.key === "Enter") {
if(filterMenuInput.value!==filter && filterMenuInput.value) {
saveFilter(filterMenuInput.value, filter, category);
saveFilter(filterMenuInput.value, filter, category).then(function(response) {
console.info(response);
}).catch(function(error) {
handleError(error);
});
} else {
filterMenu.classList.remove("is-active");
}
}
});
}
filterMenuSave.onclick = function() {
if(filterMenuInput.value!==filter && filterMenuInput.value) {
saveFilter(filterMenuInput.value, filter, category);
saveFilter(filterMenuInput.value, filter, category).then(function(response) {
console.info(response);
}).catch(function(error) {
handleError(error);
});
} else {
filterMenu.classList.remove("is-active");
}
}
filterMenuDelete.onclick = function() {
deleteFilter(filter, category);
deleteFilter(filter, category).then(function(response) {
console.info(response);
}).catch(function(error) {
handleError(error);
});
}
});
if(filtersCountedReduced[filter]) {
......
......@@ -303,7 +303,7 @@ function generateTableRow(todo) {
if(todo.text) {
if(todo.priority && userData.sortBy!="priority") todoTableBodyCellText.innerHTML = "<span class=\"priority\"><span class=\"button " + todo.priority + "\">" + todo.priority + "</span></span>";
// parse text string through markdown parser
todoTableBodyCellText.innerHTML += marked.parseInline(todo.text);
todoTableBodyCellText.innerHTML += "<span class=\"text\">" + marked.parseInline(todo.text) + "</span>";
//todoTableBodyCellText.innerHTML = todo.text;
// replace line feed replacement character with a space
todoTableBodyCellText.innerHTML = todoTableBodyCellText.innerHTML.replaceAll(String.fromCharCode(16)," ");
......@@ -575,16 +575,15 @@ function checkIsTodoVisible(todo) {
}
function generateNotification(todo, offset) {
try {
let notifications = userData.notifications;
let dismissedNotifications = userData.dismissedNotifications;
// abort if user didn't permit notifications within sleek
if(!notifications) return Promise.resolve("Info: Notification surpressed (turned off in sleek's settings)");
if(!userData.notifications) return Promise.resolve("Info: Notification surpressed (turned off in sleek's settings)");
// check for necessary permissions
return navigator.permissions.query({name: 'notifications'}).then(function(result) {
return navigator.permissions.query({name: "notifications"}).then(function(result) {
// abort if user didn't permit notifications
if(result.state!="granted") return Promise.resolve("Info: Notification surpressed (not permitted by OS)");
// add the offset so a notification shown today with "due tomorrow", will be shown again tomorrow but with "due today"
const hash = generateHash(todo.due.toISOString().slice(0, 10) + todo.text) + offset;
//const hash = generateHash(todo.due.toISOString().slice(0, 10) + todo.text) + offset;
const hash = generateHash(todo.toString()) + offset;
let title;
switch (offset) {
case 0:
......@@ -595,7 +594,7 @@ function generateNotification(todo, offset) {
break;
}
// if notification already has been triggered once it will be discarded
if(dismissedNotifications.includes(hash)) return Promise.resolve("Info: Notification skipped (has already been sent)");
if(userData.dismissedNotifications.includes(hash)) return Promise.resolve("Info: Notification skipped (has already been sent)");
// set options for notifcation
const config = {
title: title,
......@@ -611,11 +610,11 @@ function generateNotification(todo, offset) {
text: 'Show Button'
}]
}
// once shown, it will be persisted as hash to it won't be shown a second time
userData.dismissedNotifications.push(hash);
setUserData("dismissedNotifications", userData.dismissedNotifications);
// send notification object to main process for execution
window.api.send("showNotification", config);
// once shown, it will be persisted as hash to it won't be shown a second time
dismissedNotifications.push(hash);
setUserData("dismissedNotifications", dismissedNotifications);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Notification", "Shown"]);
return Promise.resolve("Info: Notification successfully sent");
......@@ -625,8 +624,8 @@ function generateNotification(todo, offset) {
return Promise.reject(error);
}
}
function generateHash(str) {
return str.split('').reduce((prevHash, currVal) =>
function generateHash(string) {
return string.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
......
......@@ -19,6 +19,7 @@ const toggleNotifications = document.getElementById("toggleNotifications");
const toggleTray = document.getElementById("toggleTray");
const viewHeadlineAppView = document.getElementById("viewHeadlineAppView");
const viewHeadlineTodoList = document.getElementById("viewHeadlineTodoList");
const viewHeadlineFilterList = document.getElementById("viewHeadlineFilterList");
const viewSelectSortBy = document.getElementById("viewSelectSortBy");
const viewToggleCompactView = document.getElementById("viewToggleCompactView");
const viewToggleDueIsFuture = document.getElementById("viewToggleDueIsFuture");
......@@ -28,6 +29,7 @@ const viewToggles = document.querySelectorAll('.viewToggle');
const viewToggleShowCompleted = document.getElementById("viewToggleShowCompleted");
const viewToggleShowHidden = document.getElementById("viewToggleShowHidden");
const viewToggleSortCompletedLast = document.getElementById("viewToggleSortCompletedLast");
const viewToggleZoom = document.getElementById("viewToggleZoom");
const zoomRangePicker = document.getElementById("zoomRangePicker");
const zoomUndo = document.getElementById("zoomUndo");
......@@ -38,6 +40,7 @@ sortByPriority.innerHTML = translations.priority;
sortByProjects.innerHTML = translations.projects;
viewHeadlineAppView.innerHTML = translations.viewHeadlineAppView;
viewHeadlineTodoList.innerHTML = translations.viewHeadlineTodoList;
viewHeadlineFilterList.innerHTML = translations.viewHeadlineFilterList;
viewToggleDueIsFuture.innerHTML = translations.dueFuture;
viewToggleDueIsPast.innerHTML = translations.duePast;
viewToggleDueIsToday.innerHTML = translations.dueToday;
......@@ -45,6 +48,9 @@ viewToggleShowCompleted.innerHTML = translations.completedTodos;
viewToggleShowHidden.innerHTML = translations.hiddenTodos;
viewToggleSortCompletedLast.innerHTML = translations.sortCompletedLast;
viewToggleCompactView.innerHTML = translations.compactView;
zoomRangePicker.innerHTML = translations.zoomRangePicker;
viewToggleZoom.innerHTML = translations.viewToggleZoom;
viewToggleShowEmptyFilters.innerHTML = translations.viewToggleShowEmptyFilters;
viewSelectSortBy.onchange = async function() {
if(this.value) {
......@@ -119,7 +125,7 @@ function toggle(toggleName, variable) {
startBuilding();
}
setUserData(toggle.id, userData[toggle.id]);
return Promise.resolve("Success: Show " + toggle.id + " todo set to: " + userData[toggle.id]);
return Promise.resolve("Success: " + toggle.id + " set to: " + userData[toggle.id]);
} catch(error) {
error.functionName = toggle.name;
return Promise.reject(error);
......
......@@ -4,7 +4,10 @@
"openFile": "打开todo.txt",
"toggleDarkMode": "浅色/深色模式",
"viewHeadlineTodoList": "任务列表",
"viewHeadlineFilterList": "侧边栏",
"viewHeadlineAppView": "App视图",
"viewToggleZoom": "缩放",
"viewToggleShowEmptyFilters": "空过滤器",
"toggleCompletedTodos": "显示/隐藏已完成任务",
"sortBy": "排序",
"completedTodos": "已完成任务",
......
......@@ -4,7 +4,10 @@
"openFile": "todo.txt öffnen",
"toggleDarkMode": "Nachtmodus ein- und ausschalten",
"viewHeadlineTodoList": "Todo-Liste",
"viewHeadlineFilterList": "Filter-Seitenleiste",
"viewHeadlineAppView": "App-Ansicht",
"viewToggleZoom": "Zoom",
"viewToggleShowEmptyFilters": "Leere Filter",
"toggleCompletedTodos": "Erledigte Aufgaben ein- und ausblenden",
"sortBy": "Sortiere nach",
"completedTodos": "Erledigte Aufgaben",
......
......@@ -4,7 +4,10 @@
"openFile": "Open todo.txt",
"toggleDarkMode": "Toggle dark mode",
"viewHeadlineTodoList": "Todo list",
"viewHeadlineFilterList": "Filter sidebar",
"viewHeadlineAppView": "App view",
"viewToggleZoom": "Zoom",
"viewToggleShowEmptyFilters": "Empty filters",
"toggleCompletedTodos": "Toggle completed todos",
"sortBy": "Sort by",
"completedTodos": "Completed todos",
......
......@@ -4,7 +4,10 @@
"openFile": "Abrir todo.txt",
"toggleDarkMode": "Activar el modo oscuro",
"viewHeadlineTodoList": "Lista de quehaceres",
"viewHeadlineFilterList": "Barra lateral",
"viewHeadlineAppView": "Vista de la aplicación",
"viewToggleZoom": "Empinadura",
"viewToggleShowEmptyFilters": "Filtros vacíos",
"toggleCompletedTodos": "Activar los todo completados",
"sortBy": "Ordenar por",
"completedTodos": "Todos completados",
......
......@@ -4,7 +4,10 @@
"openFile": "Ouvrir un fichier",
"toggleDarkMode": "Changer le thème",
"viewHeadlineTodoList": "Liste de tâches",
"viewHeadlineFilterList": "Barre latérale",
"viewHeadlineAppView": "Vue de l'application",
"viewToggleZoom": "Zoom",
"viewToggleShowEmptyFilters": "Filtres vides",
"toggleCompletedTodos": "Afficher/masquer les tâches complétées",
"sortBy": "Trier par",
"completedTodos": "Tâches complétées",
......
......@@ -4,7 +4,10 @@
"openFile": "Apri todo.txt",
"toggleDarkMode": "Attiva la modalità scura",
"viewHeadlineTodoList": "Lista di todo",
"viewHeadlineFilterList": "Barra laterale",
"viewHeadlineAppView": "Visualizzazione app",
"viewToggleZoom": "Zumata",
"viewToggleShowEmptyFilters": "Filtri vuoti",
"sortBy": "Ordina per",
"completedTodos": "Todo completati",
"sortCompletedLast": "Tutto completato alla fine",
......
......@@ -222,6 +222,7 @@ const createWindow = async function() {
}
userData.set("theme", getTheme());
}
console.log(userData.data.dismissedNotifications);
if(typeof userData.data.width != "number") userData.set("width", 1100);
if(typeof userData.data.height != "number") userData.set("height", 700);
if(typeof userData.data.horizontal != "number") userData.set("horizontal", 160);
......@@ -241,9 +242,12 @@ const createWindow = async function() {
if(typeof userData.data.sortBy != "string") userData.set("sortBy", "priority");
if(typeof userData.data.zoom != "string") userData.set("zoom", "100");
if(typeof userData.data.tray != "boolean") userData.data.tray = false;
if(typeof userData.data.showEmptyFilters != "boolean") userData.data.showEmptyFilters = true;
if(!Array.isArray(userData.data.dismissedNotifications)) userData.set("dismissedNotifications", []);
if(!Array.isArray(userData.data.dismissedMessages)) userData.set("dismissedMessages", []);
if(!Array.isArray(userData.data.hideFilterCategories)) userData.set("hideFilterCategories", []);
return Promise.resolve(userData);
} catch(error) {
error.functionName = configureUserData.id;
......@@ -573,12 +577,6 @@ const createWindow = async function() {
try {
// Write content to file
fs.writeFileSync(args[1], args[0], {encoding: "utf-8"});
// Restart file watcher
startFileWatcher(userData.data.file).then(response => {
console.info(response);
}).catch(error => {
console.error(error);
});
} catch(error) {
console.error(error);
error.functionName = "fs.writeFileSync";
......
......@@ -105,7 +105,7 @@ function configureMatomo() {
if(userData.zoom)_paq.push(['setCustomDimension', 17, userData.zoom]);
if(appData.channel)_paq.push(['setCustomDimension', 18, appData.channel]);
if(userData.tray)_paq.push(['setCustomDimension', 19, userData.tray]);
console.log(appData.tray);
if(typeof userData.showEmptyFilters === "boolean")_paq.push(['setCustomDimension', 20, userData.showEmptyFilters]);
_paq.push(['requireConsent']);
_paq.push(['setConsentGiven']);
_paq.push(['trackPageView']);
......@@ -781,6 +781,7 @@ function setToggles() {
showDueIsPast.checked = userData.showDueIsPast;
toggleTray.checked = userData.tray;
compactView.checked = userData.compactView;
showEmptyFilters.checked = userData.showEmptyFilters;
return Promise.resolve("Success: Toggles set");
} catch(error) {
error.functionName = setToggles.name;
......
......@@ -145,9 +145,6 @@ nav {
.flex-table:hover .flex-row.todoTableItemMore a {
color: $lighter-grey;
}
.flex-table.completed {
opacity: .4;
}
.flex-table.due {
.button {
color: $almost-white;
......@@ -166,19 +163,19 @@ nav {
}
.flex-row.itemDueDate {
color: white;
.fa-sort-down {
color: $even-darker-grey;
i {
color: inherit;
}
}
.flex-row.itemDueDate.isToday,
.flex-row.itemDueDate.isPast {
color: $has-text-danger;
.fa-sort-down {
i {
color: inherit;
}
}
.flex-row.itemDueDate.isTomorrow {
.fa-sort-down {
i {
color: $has-text-attention!important;