Skip to content

Commit

Permalink
Squashed commit of the following: st3v3nmw#839 commit 965c394 [FEAT] …
Browse files Browse the repository at this point in the history
…For improved UX, split the long list of plug-in options across categories within a tab control
  • Loading branch information
ronzulu committed Jul 19, 2024
1 parent f6bb04f commit 82b94e0
Show file tree
Hide file tree
Showing 17 changed files with 819 additions and 363 deletions.
2 changes: 1 addition & 1 deletion manifest-beta.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "obsidian-spaced-repetition",
"name": "Spaced Repetition",
"version": "1.13-beta.8",
"version": "1.13-beta.9",
"minAppVersion": "0.15.4",
"description": "Fight the forgetting curve by reviewing flashcards & entire notes.",
"author": "Stephen Mwangi",
Expand Down
171 changes: 171 additions & 0 deletions src/gui/Tabs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* 'Shell commands' plugin for Obsidian.
* Copyright (C) 2021 - 2023 Jarkko Linnanvirta
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.0 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Contact the author (Jarkko Linnanvirta): https://github.com/Taitava/
*/

import {setIcon} from "obsidian";

export interface Tab {
title: string;
icon: string;
content_generator: (container_element: HTMLElement) => Promise<void>;
}

export interface TabStructure {
header: HTMLElement,
active_tab_id: string,
buttons: {
[key: string]: HTMLElement,
}
contentContainers: {
[key: string]: HTMLElement,
},
contentGeneratorPromises: {
[key: string]: Promise<void>,
}
}

export interface Tabs {
[key: string]: Tab;
}

interface TabContentContainers {
[key: string]: HTMLElement,
}

interface TabButtons {
[key: string]: HTMLElement,
}

export function createTabs(container_element: HTMLElement, tabs: Tabs, activateTabId: string): TabStructure {
const tab_header = container_element.createEl("div", {attr: {class: "sr-tab-header"}});
const tab_content_containers: TabContentContainers = {};
const tab_buttons: TabButtons = {};
const tab_structure: TabStructure = {
header: tab_header,
active_tab_id: Object.keys(tabs)[0] as string, // Indicate that the first tab is active. This does not affect what tab is active in practise, it just reports the active tab.
buttons: tab_buttons,
contentContainers: tab_content_containers,
contentGeneratorPromises: {},
};
let first_button: HTMLElement | undefined;
for (const tab_id in tabs) {
const tab = tabs[tab_id];

// Create button
const button = tab_header.createEl("button", {
attr: {
class: "sr-tab-header-button",
activateTab: "sr-tab-" + tab_id,
},
});
button.onclick = function (event: MouseEvent) {
const tab_button = this as HTMLElement; // Use 'this' instead of event.target because this way we'll always get a button element, not an element inside the button (i.e. an icon).

// Hide all tab contents and get the max dimensions
let max_width = 0;
let max_height = 0;
const tab_header = tab_button.parentElement;
if (null === tab_header) {
throw new Error("Tab header is missing. Did not get a parent from tab button.");
}
const container_element = tab_header.parentElement;
if (null === container_element) {
throw new Error("Container element is missing. Did not get a parent from tab header.");
}
const tab_contents = container_element.findAll("div.sr-tab-content"); // Do not get all tab contents that exist, because there might be multiple tab systems open at the same time.
const is_main_settings_modal = container_element.hasClass("vertical-tab-content");
for (const index in tab_contents) {
const tab_content = tab_contents[index];

// Get the maximum tab dimensions so that all tabs can have the same dimensions.
// But don't do it if this is the main settings modal
if (!is_main_settings_modal) {
tab_content.addClass("sr-tab-active"); // Need to make the tab visible temporarily in order to get the dimensions.
if (tab_content.offsetHeight > max_height) {
max_height = tab_content.offsetHeight;
}
if (tab_content.offsetWidth > max_width) {
max_width = tab_content.offsetWidth;
}
}

// Finally hide the tab
tab_content.removeClass("sr-tab-active");
}

// Remove active status from all buttons
const adjacent_tab_buttons = tab_header.findAll(".sr-tab-header-button"); // Do not get all tab buttons that exist, because there might be multiple tab systems open at the same time.
for (const index in adjacent_tab_buttons) {
const tab_button = adjacent_tab_buttons[index];
tab_button.removeClass("sr-tab-active");
}

// Activate the clicked tab
tab_button.addClass("sr-tab-active");
const activateTabAttribute: Attr | null = tab_button.attributes.getNamedItem("activateTab");
if (null === activateTabAttribute) {
throw new Error("Tab button has no 'activateTab' HTML attribute! Murr!");
}
const activate_tab_id = activateTabAttribute.value;
const tab_content: HTMLElement | null = document.getElementById(activate_tab_id);
if (null === tab_content) {
throw new Error("No tab content was found with activate_tab_id '"+activate_tab_id+"'! Hmph!");
}
tab_content.addClass("sr-tab-active");

// Mark the clicked tab as active in TabStructure (just to report which tab is currently active)
tab_structure.active_tab_id = activate_tab_id.replace(/^sr-tab-/, ""); // Remove "sr-tab" prefix.

// Focus an element (if a focusable element is present)
tab_content.find(".sr-focus-element-on-tab-opening")?.focus(); // ? = If not found, do nothing.

// Apply the max dimensions to this tab
// But don't do it if this is the main settings modal
if (!is_main_settings_modal) {
tab_content.style.width = max_width + "px";
tab_content.style.height = max_height + "px";
}

// Do nothing else (I don't know if this is needed or not)
event.preventDefault();
};
if (tab.icon)
setIcon(button, tab.icon);

button.insertAdjacentText("beforeend", " " + tab.title);
tab_buttons[tab_id] = button;

// Create content container
tab_content_containers[tab_id] = container_element.createEl("div", {attr: {class: "sr-tab-content", id: "sr-tab-" + tab_id}});

// Generate content
tab_structure.contentGeneratorPromises[tab_id] = tab.content_generator(tab_content_containers[tab_id]);

// Memorize the first tab's button
if (undefined === first_button) {
first_button = button;
}
}

// Open a tab.
tab_buttons[activateTabId].click();

// Return the TabStructure
return tab_structure;
}

9 changes: 8 additions & 1 deletion src/lang/locale/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,16 @@ export default {
// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - Settings",
CHECK_WIKI: '.<a href="${wiki_url}">wiki</a> لمزيد من المعلومات ، تحقق من',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "مجلدات لتجاهلها",
FOLDERS_TO_IGNORE_DESC:
"Templates Meta/Scripts : أدخل مسارات المجلد مفصولة بواسطة سطور جديدة,مثال",
`Templates Meta/Scripts.
Note that this setting is common to both Flashcards and Notes. : أدخل مسارات المجلد مفصولة بواسطة سطور جديدة,مثال`,
FLASHCARDS: "البطاقات",
FLASHCARD_EASY_LABEL: "نص الزر سهل",
FLASHCARD_GOOD_LABEL: "نص الزر جيد",
Expand Down
11 changes: 9 additions & 2 deletions src/lang/locale/cz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,18 @@ export default {
YEARS_STR_IVL_MOBILE: "${interval}r",

// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - Nastavení",
SETTINGS_HEADER: "Spaced Repetition - Nastavení",
CHECK_WIKI: 'Pro více informací jděte na <a href="${wiki_url}">wiki</a>.',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "Ignorované složky",
FOLDERS_TO_IGNORE_DESC:
"Zadejte cesty ke složkám oddělené odřádkováním napříkad. Šablony Meta/Scripts",
`Zadejte cesty ke složkám oddělené odřádkováním napříkad. Šablony Meta/Scripts.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "Kartičky",
FLASHCARD_EASY_LABEL: "Easy Button Text",
FLASHCARD_GOOD_LABEL: "Good Button Text",
Expand Down
11 changes: 9 additions & 2 deletions src/lang/locale/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ export default {
YEARS_STR_IVL_MOBILE: "${interval}j",

// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - Einstellungen",
SETTINGS_HEADER: "Spaced Repetition - Einstellungen",
CHECK_WIKI: 'Weitere Informationen gibt es im <a href="${wiki_url}">Wiki</a> (english).',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "Ausgeschlossene Ordner",
FOLDERS_TO_IGNORE_DESC:
"Mehrere Ordner mit Zeilenumbrüchen getrennt angeben. Bsp. OrdnerA[Zeilenumbruch]OrdnerB/Unterordner",
`Mehrere Ordner mit Zeilenumbrüchen getrennt angeben. Bsp. OrdnerA[Zeilenumbruch]OrdnerB/Unterordner.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "Lernkarten",
FLASHCARD_EASY_LABEL: "Einfach Knopf Text",
FLASHCARD_GOOD_LABEL: "Gut Knopf Text",
Expand Down
11 changes: 9 additions & 2 deletions src/lang/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,17 @@ export default {
YEARS_STR_IVL_MOBILE: "${interval}y",

// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - Settings",
SETTINGS_HEADER: "Spaced Repetition - Settings",
CHECK_WIKI: 'For more information, check the <a href="${wiki_url}">wiki</a>.',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "Folders to ignore",
FOLDERS_TO_IGNORE_DESC: "Enter folder paths separated by newlines i.e. Templates Meta/Scripts",
FOLDERS_TO_IGNORE_DESC: `Enter folder paths separated by newlines e.g. Templates Meta/Scripts.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "Flashcards",
FLASHCARD_EASY_LABEL: "Easy Button Text",
FLASHCARD_GOOD_LABEL: "Good Button Text",
Expand Down
9 changes: 8 additions & 1 deletion src/lang/locale/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,16 @@ export default {
// settings.ts
SETTINGS_HEADER: "Extensión de Repetición Espaciada - Ajustes",
CHECK_WIKI: 'Para más información revisa la <a href="${wiki_url}">wiki</a>.',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "Directorios a ignorar",
FOLDERS_TO_IGNORE_DESC:
"Escriba las rutas de los directorios separadas por saltos de línea, por ejemplo, Plantillas Extra/Guiones",
`Escriba las rutas de los directorios separadas por saltos de línea, por ejemplo, Plantillas Extra/Guiones.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "Tarjetas de Memorización",
FLASHCARD_EASY_LABEL: "Texto del botón: Fácil",
FLASHCARD_GOOD_LABEL: "Texto del botón: Bien",
Expand Down
9 changes: 8 additions & 1 deletion src/lang/locale/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,16 @@ export default {
// settings.ts
SETTINGS_HEADER: "Plugin per ripetizione spaziata - Impostazioni",
CHECK_WIKI: 'Per maggiori informazioni, rivolgersi alla <a href="${wiki_url}">wiki</a>.',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "Cartelle da ignorare",
FOLDERS_TO_IGNORE_DESC:
"Inserisci i percorsi delle cartelle separati da a capo, per esempio, Templates Meta/Scripts",
`Inserisci i percorsi delle cartelle separati da a capo, per esempio, Templates Meta/Scripts.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "Schede",
FLASHCARD_EASY_LABEL: "Testo del bottone facile",
FLASHCARD_GOOD_LABEL: "Testo del bottone buono",
Expand Down
11 changes: 9 additions & 2 deletions src/lang/locale/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,18 @@ export default {
YEARS_STR_IVL_MOBILE: "${interval}y",

// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - 設定",
SETTINGS_HEADER: "Spaced Repetition - 設定",
CHECK_WIKI: '詳細については<a href="${wiki_url}">wiki</a>を確認してください。',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "無視するフォルダ",
FOLDERS_TO_IGNORE_DESC:
'フォルダパスを改行で区切って入力してください。"Templates Meta/Scripts" のようなスペースによる区切りでの書き方は無効です。',
`フォルダパスを改行で区切って入力してください。"Templates Meta/Scripts" のようなスペースによる区切りでの書き方は無効です。.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "フラッシュカード",
FLASHCARD_EASY_LABEL: "Easy Button Text",
FLASHCARD_GOOD_LABEL: "Good Button Text",
Expand Down
11 changes: 9 additions & 2 deletions src/lang/locale/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,18 @@ export default {
YEARS_STR_IVL_MOBILE: "${interval}y",

// settings.ts
SETTINGS_HEADER: "Spaced Repetition Plugin - 설정",
SETTINGS_HEADER: "Spaced Repetition - 설정",
CHECK_WIKI: '더 많은 정보를 원하시면, <a href="${wiki_url}">wiki</a>를 확인해주세요.',
GITHUB_DISCUSSIONS: 'Visit the <a href="${discussions_url}">discussions</a> section for Q&A help, feedback, and general discussion.',
GITHUB_ISSUES: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report.',
GITHUB_SOURCE_CODE: 'Project source code available on <a href="${github_project_url}">GitHub</a>',
CODE_CONTRIBUTION_INFO: 'Information on <a href="${code_contribution_url}">code contributions</a>',
TRANSLATION_CONTRIBUTION_INFO: 'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
PROJECT_CONTRIBUTIONS: 'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug-report',
FOLDERS_TO_IGNORE: "무시할 폴더들",
FOLDERS_TO_IGNORE_DESC:
"폴더 경로를 빈 줄로 구분해서 입력해주세요. 'Templates Meta/Scripts' 와 같이 입력하는 것은 유효하지 않습니다.",
`폴더 경로를 빈 줄로 구분해서 입력해주세요. 'Templates Meta/Scripts' 와 같이 입력하는 것은 유효하지 않습니다.
Note that this setting is common to both Flashcards and Notes.`,
FLASHCARDS: "플래시카드",
FLASHCARD_EASY_LABEL: "Easy Button Text",
FLASHCARD_GOOD_LABEL: "Good Button Text",
Expand Down
Loading

0 comments on commit 82b94e0

Please sign in to comment.