Skip to content

Commit

Permalink
Fixed broken translations of attribute group headlines. Refactoring #609
Browse files Browse the repository at this point in the history
.
  • Loading branch information
ransome1 committed Feb 27, 2024
1 parent fd0ee07 commit 0e7a36e
Show file tree
Hide file tree
Showing 22 changed files with 149 additions and 141 deletions.
2 changes: 1 addition & 1 deletion flatpak/com.github.ransome1.sleek.appdata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<developer_name>Robin Ahle</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="2.0.12-rc.1" date="2024-02-26"/>
<release version="2.0.12-rc.2" date="2024-02-27"/>
</releases>
<url type="homepage">https://github.com/ransome1/sleek</url>
<url type="contact">https://github.com/ransome1/sleek/issues</url>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sleek",
"version": "2.0.12-rc.1",
"version": "2.0.12-rc.2",
"main": "./src/main/main.tsx",
"scripts": {
"build": "concurrently \"yarn run peggy\" \"yarn run build:main\" \"yarn run build:renderer\"",
Expand Down
2 changes: 1 addition & 1 deletion release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sleek",
"version": "2.0.12-rc.1",
"version": "2.0.12-rc.2",
"description": "todo.txt manager for Linux, Windows and MacOS, free and open-source (FOSS)",
"synopsis": "todo.txt manager for Linux, Windows and MacOS, free and open-source (FOSS)",
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: sleek
base: core20
version: "2.0.12-rc.1"
version: "2.0.12-rc.2"
summary: todo.txt manager for Linux, free and open-source (FOSS)
description: |
sleek is an open-source (FOSS) todo manager based on the todo.txt syntax. Stripped down to only the most necessary features, and with a clean and simple interface, sleek aims to help you focus on getting things done.
Expand Down
28 changes: 14 additions & 14 deletions src/__tests__/__mock__/recurrence.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

2024-02-26 Line 1 rec:1d due:2024-02-27
2024-02-26 Line 1 rec:w due:2024-03-04
2024-02-26 Line 1 rec:2m due:2024-04-26
2024-02-26 Line 1 rec:+1d due:2024-02-28
2024-02-26 Line 1 rec:7w due:2024-04-15
2024-02-26 Line 1 due:2023-07-24 rec:+1b
2024-02-26 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y
2024-02-26 Water plants @home +quick due:2024-03-04 t:2024-02-23 rec:1w
2024-02-26 Line 1 rec:+1d t:2023-09-20
2024-02-26 Line 1 rec:1d pri:A due:2024-02-27
2024-02-26 (A) Do something rec:d t:2024-02-27 @SomeContext
2024-02-26 Do something rec:0d
2024-02-26 Do something rec:0d due:2024-02-26
2024-02-26 Do something rec:0d due:2024-02-26 t:2024-02-26
2024-02-27 Line 1 rec:1d due:2024-02-28
2024-02-27 Line 1 rec:w due:2024-03-05
2024-02-27 Line 1 rec:2m due:2024-04-27
2024-02-27 Line 1 rec:+1d due:2024-02-29
2024-02-27 Line 1 rec:7w due:2024-04-16
2024-02-27 Line 1 due:2023-07-24 rec:+1b
2024-02-27 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y
2024-02-27 Water plants @home +quick due:2024-03-05 t:2024-02-24 rec:1w
2024-02-27 Line 1 rec:+1d t:2023-09-20
2024-02-27 Line 1 rec:1d pri:A due:2024-02-28
2024-02-27 (A) Do something rec:d t:2024-02-28 @SomeContext
2024-02-27 Do something rec:0d
2024-02-27 Do something rec:0d due:2024-02-27
2024-02-27 Do something rec:0d due:2024-02-27 t:2024-02-27
2 changes: 1 addition & 1 deletion src/__tests__/main/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('Should filter todos based on passed filters', () => {

test('should filter todo objects based on project filter', () => {
const filters = {
projects: [ { value: 'Project 1', exclude: false } ]
projects: [ { values: ['Project 1'], exclude: false } ]
}
const expected = [
{ id: 1, body: 'Test', created: null, complete: false, completed: null, priority: null, contexts: null, projects: ['Project 1'], due: '2023-01-01', dueString: '2023-01-01', t: null, tString: null, rec: null, hidden: false, pm: null, visible: true, string: '' },
Expand Down
5 changes: 2 additions & 3 deletions src/main/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import './modules/IpcMain';
const environment: string | undefined = process.env.NODE_ENV;
let mainWindow: BrowserWindow | null = null;
let eventListeners: Record<string, any | undefined> = {};
let resizeTimeout;
let resizeTimeout: NodeJS.Timeout | undefined;

const handleCreateWindow = () => {
if(mainWindow) {
Expand Down Expand Up @@ -131,8 +131,7 @@ const createMainWindow = () => {

handleWindowSizeAndPosition();

const colorTheme = config.get('colorTheme');
nativeTheme.themeSource = colorTheme;
nativeTheme.themeSource = config.get('colorTheme');

mainWindow
.on('resize', handleResize)
Expand Down
2 changes: 1 addition & 1 deletion src/main/modules/Filters/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function applyFilters(todoObjects: TodoObject[], filters: Filters | null): TodoO

const hasMatchingValue = Array.isArray(attributeValues)
? attributeValues.some((val) => values.includes(val))
: values.includes(attributeValues);
: attributeValues !== undefined && values.includes(attributeValues);

return exclude ? !hasMatchingValue : hasMatchingValue;
});
Expand Down
33 changes: 16 additions & 17 deletions src/main/util.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,22 @@ function resolveHtmlPath(htmlFileName: string): string {
}

function getChannel(): string {
switch (true) {
case process.env.APPIMAGE:
return "AppImage";
case process.windowsStore:
return "Windows Store";
case process.mas:
return "Mac App Store";
case process.env.SNAP:
return "Snap Store";
case process.env.FLATPAK_ID:
return "Flathub";
case process.env.AUR:
return "AUR";
case process.env.PORTABLE_EXECUTABLE_DIR:
return "Portable";
default:
return "Misc";
if (process.env.APPIMAGE) {
return "AppImage";
} else if (process.windowsStore) {
return "Windows Store";
} else if (process.mas) {
return "Mac App Store";
} else if (process.env.SNAP) {
return "Snap Store";
} else if (process.env.FLATPAK_ID) {
return "Flathub";
} else if (process.env.AUR) {
return "AUR";
} else if (process.env.PORTABLE_EXECUTABLE_DIR) {
return "Portable";
} else {
return "Misc";
}
}

Expand Down
14 changes: 0 additions & 14 deletions src/renderer/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@ import './App.scss';

const { ipcRenderer, store } = window.api;

const translatedAttributes = (t: typeof i18n.t) => ({
t: t('shared.attributeMapping.t'),
due: t('shared.attributeMapping.due'),
projects: t('shared.attributeMapping.projects'),
contexts: t('shared.attributeMapping.contexts'),
priority: t('shared.attributeMapping.priority'),
rec: t('shared.attributeMapping.rec'),
pm: t('shared.attributeMapping.pm'),
created: t('shared.attributeMapping.created'),
completed: t('shared.attributeMapping.completed'),
});

const App = () => {
const [settings, setSettings] = useState<Settings>(store.getConfig());
const [snackBarOpen, setSnackBarOpen] = useState<boolean>(false);
Expand All @@ -55,7 +43,6 @@ const App = () => {
const [promptItem, setPromptItem] = useState<PromptItem | null>(null);
const [triggerArchiving, setTriggerArchiving] = useState<boolean>(false);
const searchFieldRef = useRef<HTMLInputElement>(null);
const [attributeMapping] = useState<TranslatedAttributes>(translatedAttributes(i18n.t) || {});
const [visibleRowCount, setVisibleRowCount] = useState(50);
const [loadMoreRows, setLoadMoreRows] = useState(true);

Expand Down Expand Up @@ -123,7 +110,6 @@ const App = () => {
attributes={attributes}
filters={filters}
searchFieldRef={searchFieldRef}
attributeMapping={attributeMapping}
/>
)}
<div className="flexItems">
Expand Down
36 changes: 8 additions & 28 deletions src/renderer/Drawer/Attributes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,42 @@ import Badge from '@mui/material/Badge';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import AirIcon from '@mui/icons-material/Air';
import { handleFilterSelect } from '../Shared';
import { handleFilterSelect, friendlyDate, translatedAttributes } from '../Shared';
import { withTranslation, WithTranslation } from 'react-i18next';
import { i18n } from '../Settings/LanguageSelector';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import duration from 'dayjs/plugin/duration';
import calendar from 'dayjs/plugin/calendar';
import './Attributes.scss';
dayjs.extend(relativeTime);
dayjs.extend(duration);
dayjs.extend(calendar);


const { store } = window.api;

interface DrawerAttributesProps extends WithTranslation {
settings: Settings;
attributes: Attributes | null;
attributeMapping: TranslatedAttributes;
filters: Filters | null;
t: typeof i18n.t;
}

const DrawerAttributes: React.FC<DrawerAttributesProps> = memo(({
settings,
attributes,
attributeMapping,
filters,
t,
}) => {
const firstTabbableElementRef = useRef<HTMLDivElement | null>(null);
const [hovered, setHovered] = useState<string | null>(null);

const friendlyDate = (value: string) => {
dayjs.locale(settings.language);
return dayjs(value).calendar(null, {
sameDay: `[${t(`drawer.attributes.today`)}]`,
nextDay: `[${t(`drawer.attributes.tomorrow`)}]`,
nextWeek: `[${t(`drawer.attributes.nextWeek`)}]`,
lastDay: `[${t(`drawer.attributes.yesterday`)}]`,
lastWeek: `[${t(`drawer.attributes.lastWeek`)}]`,
sameElse: function () {
return dayjs(this).fromNow();
},
});
};

const preprocessAttributes = (attributeKey, attributes) => {
if (!attributes) {
return null;
}

const isDate: boolean = ['due', 't', 'completed', 'created'].includes(attributeKey);
const processedAttributes = {};

Object.keys(attributes).forEach((key) => {
if (attributes[key]) {
const count = attributes[key].count;
const formattedValue = settings.useHumanFriendlyDates && dayjs(key).isValid() ? friendlyDate(key) : key;
const formattedValue = settings.useHumanFriendlyDates && isDate ? friendlyDate(key, t) : key;

if (!processedAttributes[formattedValue]) {
processedAttributes[formattedValue] = {
Expand Down Expand Up @@ -166,7 +145,8 @@ const DrawerAttributes: React.FC<DrawerAttributesProps> = memo(({
{!isAttributesEmpty ? (
Object.keys(attributes).map((key, index) => {

const preprocessedAttributes = attributes[key] ? preprocessAttributes(key, attributes[key]) : attributes[key];
const preprocessedAttributes: Attributes = preprocessAttributes(key, attributes[key]);
const attributeHeadline: string = translatedAttributes(t)[key];

return Object.keys(preprocessedAttributes).length > 0 ? (
<Accordion
Expand All @@ -178,7 +158,7 @@ const DrawerAttributes: React.FC<DrawerAttributesProps> = memo(({
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Badge variant="dot" invisible={!(key === 'due' && Object.values(preprocessedAttributes).some((attribute) => attribute.notify))}>
<h3 data-testid={`drawer-attributes-accordion-${key}`}>
{attributeMapping[key]}
{attributeHeadline}
</h3>
</Badge>
</AccordionSummary>
Expand All @@ -199,4 +179,4 @@ const DrawerAttributes: React.FC<DrawerAttributesProps> = memo(({
);
});

export default withTranslation()(DrawerAttributes);
export default withTranslation()(DrawerAttributes);
5 changes: 1 addition & 4 deletions src/renderer/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ interface Props extends WithTranslation {
attributes: Attributes | null;
filters: Filters | null;
searchFieldRef: React.RefObject<HTMLInputElement>;
attributeMapping: TranslatedAttributes;
t: typeof i18n.t;
}

Expand All @@ -28,7 +27,6 @@ const DrawerComponent: React.FC<Props> = memo(({
attributes,
filters,
searchFieldRef,
attributeMapping,
t
}) => {
const [activeTab, setActiveTab] = useState<string>('attributes');
Expand Down Expand Up @@ -97,13 +95,12 @@ const DrawerComponent: React.FC<Props> = memo(({
<DrawerAttributes
settings={settings}
attributes={attributes}
attributeMapping={attributeMapping}
filters={filters}
/>
)}
{settings.isDrawerOpen && activeTab === 'filters' && <DrawerFilters settings={settings} />}
{settings.isDrawerOpen && activeTab === 'sorting' && (
<DrawerSorting attributeMapping={attributeMapping} settings={settings} />
<DrawerSorting settings={settings} />
)}
</Drawer>
);
Expand Down
3 changes: 0 additions & 3 deletions src/renderer/Drawer/Sorting/DraggableList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ const { store } = window.api;

type DraggableListProps = {
settings: Settings;
attributeMapping: TranslatedAttributes;
};

const DraggableList: React.FC<DraggableListProps> = ({
settings,
attributeMapping,
}) => {
const [accordionOrder, setAccordionOrder] = useState<Sorting[]>(settings.sorting);
const reorder = (list: Sorting[], startIndex: number, endIndex: number): Sorting[] => {
Expand Down Expand Up @@ -44,7 +42,6 @@ const DraggableList: React.FC<DraggableListProps> = ({
key={item.id}
settings={settings}
setAccordionOrder={setAccordionOrder}
attributeMapping={attributeMapping}
/>
))}
{provided.placeholder}
Expand Down
13 changes: 9 additions & 4 deletions src/renderer/Drawer/Sorting/DraggableListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import ListItem from '@mui/material/ListItem';
import Button from '@mui/material/Button';
import SortIcon from '@mui/icons-material/Sort';
import DragHandleIcon from '@mui/icons-material/DragHandle';
import { withTranslation } from 'react-i18next';
import { i18n } from '../../Settings/LanguageSelector';
import { translatedAttributes } from '../../Shared';
import './DraggableListItem.scss';

type DraggableListItemProps = {
item: Sorting;
index: number;
settings: Settings;
attributeMapping: TranslatedAttributes;
setAccordionOrder: React.Dispatch<React.SetStateAction<Sorting[]>>;
t: typeof i18n.t;
};

const DraggableListItem: React.FC<DraggableListItemProps> = ({
item,
index,
settings,
attributeMapping,
setAccordionOrder,
t,
}) => {
const updatedSorting = settings.sorting.map((sortingItem: Sorting) => {
if(sortingItem.id === item.id) {
Expand All @@ -31,6 +34,8 @@ const DraggableListItem: React.FC<DraggableListItemProps> = ({
setAccordionOrder(updatedSorting);
};

const attributeHeadline: string = translatedAttributes(t)[item.value];

return (
<Draggable draggableId={item.id} index={index}>
{(provided, snapshot) => (
Expand All @@ -42,7 +47,7 @@ const DraggableListItem: React.FC<DraggableListItemProps> = ({
data-testid={`drawer-sorting-draggable-list-item-${item.value}`}
>
<div><DragHandleIcon /></div>
{attributeMapping[item.value]}
{attributeHeadline}
<Button onClick={handleButtonClick} data-testid={`drawer-sorting-draggable-list-item-${item.value}-invert`}>
{!item.invert && <SortIcon className='invert' />}
{item.invert && <SortIcon />}
Expand All @@ -53,4 +58,4 @@ const DraggableListItem: React.FC<DraggableListItemProps> = ({
);
};

export default DraggableListItem;
export default withTranslation()(DraggableListItem);
Loading

0 comments on commit 0e7a36e

Please sign in to comment.