add keystroke hints
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { BoardStatusGridPage } from "./boardStatusGridPage";
|
||||
import { BoardKanbanPage } from "./boardKanbanPage";
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
||||
import { SearchModal } from "../Modals/searchModal";
|
||||
import { BoardSettingsModal } from "../Modals/boardSettingsModal";
|
||||
@@ -96,6 +97,7 @@ export function BoardPage(
|
||||
toggle:selected={
|
||||
boardViewModel.taskPageViewModel.isShowingBoadList
|
||||
}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Options)}
|
||||
>
|
||||
<span class="icon">dock_to_right</span>
|
||||
</button>
|
||||
@@ -106,6 +108,7 @@ export function BoardPage(
|
||||
.boardSettingsHeadline
|
||||
}
|
||||
on:click={boardViewModel.showSettings}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Settings)}
|
||||
>
|
||||
<span class="icon">settings</span>
|
||||
</button>
|
||||
@@ -117,6 +120,7 @@ export function BoardPage(
|
||||
"view_list",
|
||||
BoardPageTypes.List,
|
||||
boardViewModel,
|
||||
"j",
|
||||
)}
|
||||
{BoardViewToggleButton(
|
||||
coreViewModel.translations.chatPage.task
|
||||
@@ -124,6 +128,7 @@ export function BoardPage(
|
||||
"view_kanban",
|
||||
BoardPageTypes.Kanban,
|
||||
boardViewModel,
|
||||
"k",
|
||||
)}
|
||||
{BoardViewToggleButton(
|
||||
coreViewModel.translations.chatPage.task
|
||||
@@ -131,6 +136,7 @@ export function BoardPage(
|
||||
"grid_view",
|
||||
BoardPageTypes.StatusGrid,
|
||||
boardViewModel,
|
||||
"l",
|
||||
)}
|
||||
</span>
|
||||
<span>
|
||||
@@ -142,6 +148,7 @@ export function BoardPage(
|
||||
}
|
||||
on:click={boardViewModel.showFilterModal}
|
||||
toggle:selected={boardViewModel.isFilterActive}
|
||||
ctkeystroke={CommonKeys.Filter}
|
||||
>
|
||||
<span class="icon">filter_alt</span>
|
||||
</button>
|
||||
@@ -152,6 +159,7 @@ export function BoardPage(
|
||||
.createTaskButtonAudioLabel
|
||||
}
|
||||
on:click={boardViewModel.createTask}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Create)}
|
||||
>
|
||||
<span class="icon">add</span>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "./calendarPage.css";
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
||||
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
||||
import { PlaceholderView } from "../Components/placeholderView";
|
||||
@@ -115,6 +116,7 @@ export function CalendarPage(
|
||||
.todayButtonAudioLabel
|
||||
}
|
||||
on:click={calendarPageViewModel.showToday}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Reset)}
|
||||
>
|
||||
<span class="icon">today</span>
|
||||
</button>
|
||||
@@ -129,6 +131,7 @@ export function CalendarPage(
|
||||
on:click={
|
||||
calendarPageViewModel.showPreviousMonth
|
||||
}
|
||||
ctkeystroke="k"
|
||||
>
|
||||
<span class="icon">arrow_back</span>
|
||||
</button>
|
||||
@@ -171,6 +174,7 @@ export function CalendarPage(
|
||||
.nextMonthButtonAudioLabel
|
||||
}
|
||||
on:click={calendarPageViewModel.showNextMonth}
|
||||
ctkeystroke="l"
|
||||
>
|
||||
<span class="icon">arrow_forward</span>
|
||||
</button>
|
||||
@@ -183,6 +187,7 @@ export function CalendarPage(
|
||||
.createTaskButtonAudioLabel
|
||||
}
|
||||
on:click={calendarPageViewModel.createEvent}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Create)}
|
||||
>
|
||||
<span class="icon">add</span>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "./messagePage.css";
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { MessageFilterModal } from "../Modals/messageFilterModal";
|
||||
import { ReplyPreview } from "../Components/replyPreview";
|
||||
import { ChatMessage } from "../Components/chatMessage";
|
||||
@@ -129,6 +130,7 @@ export function MessagePage(
|
||||
toggle:selected={
|
||||
messagePageViewModel.isFilterActive
|
||||
}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Filter)}
|
||||
>
|
||||
<span class="icon">filter_alt</span>
|
||||
</button>
|
||||
|
||||
@@ -9,6 +9,7 @@ export function BoardViewToggleButton(
|
||||
icon: string,
|
||||
page: BoardPageTypes,
|
||||
boardViewModel: BoardViewModel,
|
||||
key: string,
|
||||
) {
|
||||
function select() {
|
||||
boardViewModel.selectedPage.value = page;
|
||||
@@ -19,5 +20,5 @@ export function BoardViewToggleButton(
|
||||
() => boardViewModel.selectedPage.value == page,
|
||||
);
|
||||
|
||||
return RibbonButton(label, icon, isSelected, select);
|
||||
return RibbonButton(label, icon, isSelected, select, undefined, key);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export function ChatViewToggleButton(
|
||||
icon: string,
|
||||
page: ChatPageTypes,
|
||||
chatViewModel: ChatViewModel,
|
||||
key: string,
|
||||
) {
|
||||
function select() {
|
||||
chatViewModel.openPage(page);
|
||||
@@ -26,5 +27,5 @@ export function ChatViewToggleButton(
|
||||
);
|
||||
}
|
||||
|
||||
return RibbonButton(label, icon, isSelected, select, isHighlighted);
|
||||
return RibbonButton(label, icon, isSelected, select, isHighlighted, key);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@ export function HomePageButton(
|
||||
action: () => void,
|
||||
label: string,
|
||||
icon: string,
|
||||
key: string,
|
||||
) {
|
||||
return (
|
||||
<button class="tile flex-no" on:click={action}>
|
||||
<button class="tile flex-no" on:click={action} ctkeystroke={key}>
|
||||
<span class="icon">{icon}</span>
|
||||
<div>
|
||||
<span>{label}</span>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import * as React from "../../react";
|
||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||
@@ -25,6 +26,7 @@ export function ReplyPreview(
|
||||
coreViewModel.translations.chatPage.message
|
||||
.cancelReplyAudioLabel
|
||||
}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -6,6 +6,7 @@ export function RibbonButton(
|
||||
isSelected: React.State<boolean>,
|
||||
select: () => void,
|
||||
isHighlighted: React.State<boolean> = new React.State(false),
|
||||
key: string,
|
||||
) {
|
||||
return (
|
||||
<button
|
||||
@@ -14,6 +15,7 @@ export function RibbonButton(
|
||||
toggle:selected={isSelected}
|
||||
toggle:highlight={isHighlighted}
|
||||
on:click={select}
|
||||
ctkeystroke={key}
|
||||
>
|
||||
<span class="icon">{icon}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||
import { ColorPicker } from "../Components/colorPicker";
|
||||
import * as React from "../../react";
|
||||
@@ -60,7 +61,10 @@ export function BoardSettingsModal(
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={boardViewModel.hideSettings}>
|
||||
<button
|
||||
on:click={boardViewModel.hideSettings}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Apply)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { StringToTextSpan } from "../Components/textSpan";
|
||||
import * as React from "../../react";
|
||||
import FileTransferViewModel, {
|
||||
@@ -172,7 +173,10 @@ function DirectionSelectionModal(
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={fileTransferViewModel.close}>
|
||||
<button
|
||||
on:click={fileTransferViewModel.close}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { MessageReactionFilterButton } from "../Components/messageReactionFilterButton";
|
||||
import * as React from "../../react";
|
||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||
@@ -112,7 +113,10 @@ export function MessageFilterModal<T>(
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={messagePageViewModel.hideFilterModal}>
|
||||
<button
|
||||
on:click={messagePageViewModel.hideFilterModal}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { v4 } from "uuid";
|
||||
import { ViewController } from "../viewController";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { StringToOption } from "../Components/option";
|
||||
import { DeletableListItem } from "../Components/deletableListItem";
|
||||
import * as React from "../../react";
|
||||
@@ -55,6 +56,7 @@ export function SearchModal<T>(
|
||||
}
|
||||
on:click={searchViewModel.clear}
|
||||
toggle:disabled={searchViewModel.cannotClear}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Reset)}
|
||||
>
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
@@ -93,7 +95,10 @@ export function SearchModal<T>(
|
||||
></div>
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={close}>
|
||||
<button
|
||||
on:click={close}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { SplitModal } from "./splitModal";
|
||||
import { languageNames } from "../translations";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { PlaceholderView } from "../Components/placeholderView";
|
||||
import { OptionButtonList } from "../Components/optionButtonList";
|
||||
import { NavigationButton } from "../Components/navigationButton";
|
||||
@@ -62,7 +63,10 @@ export function SettingsModal(
|
||||
settingsViewModel.selectedModalPage,
|
||||
)}
|
||||
</main>
|
||||
<button on:click={settingsViewModel.close}>
|
||||
<button
|
||||
on:click={settingsViewModel.close}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SplitModal } from "./splitModal";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import { UsageBar } from "../Components/usageBar";
|
||||
import { DirectoryItemList } from "../Components/directoryItemList";
|
||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||
@@ -95,7 +96,10 @@ export function StorageModal(
|
||||
true,
|
||||
)}
|
||||
</main>
|
||||
<button on:click={storageViewModel.close}>
|
||||
<button
|
||||
on:click={storageViewModel.close}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { v4 } from "uuid";
|
||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||
import {
|
||||
Entry,
|
||||
Option,
|
||||
@@ -269,12 +270,14 @@ export function TaskSettingsModal(
|
||||
<button
|
||||
class="flex"
|
||||
on:click={taskViewModel.closeAndDiscard}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.CloseOrCancel)}
|
||||
>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
</button>
|
||||
<button
|
||||
class="flex primary"
|
||||
on:click={taskViewModel.closeAndSave}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Apply)}
|
||||
>
|
||||
{coreViewModel.translations.general.saveButton}
|
||||
<span class="icon">save</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ViewController } from "./viewController";
|
||||
import { CommonKeys, getKeySymbol } from "./keystrokes";
|
||||
import "./homePage.css";
|
||||
import { ChatViewToggleButton } from "./Components/chatViewToggleButton";
|
||||
import { TaskPage } from "./ChatPages/taskPage";
|
||||
@@ -80,6 +81,7 @@ export function ChatPage(
|
||||
.closeChatAudioLabe
|
||||
}
|
||||
on:click={chatViewModel.close}
|
||||
ctkeystroke={getKeySymbol(CommonKeys.Home)}
|
||||
>
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
@@ -111,24 +113,28 @@ export function ChatPage(
|
||||
"calendar_month",
|
||||
ChatPageTypes.Calendar,
|
||||
chatViewModel,
|
||||
"o",
|
||||
)}
|
||||
{ChatViewToggleButton(
|
||||
coreViewModel.translations.chatPage.pages.tasks,
|
||||
"task_alt",
|
||||
ChatPageTypes.Tasks,
|
||||
chatViewModel,
|
||||
"i",
|
||||
)}
|
||||
{ChatViewToggleButton(
|
||||
coreViewModel.translations.chatPage.pages.messages,
|
||||
"forum",
|
||||
ChatPageTypes.Messages,
|
||||
chatViewModel,
|
||||
"u",
|
||||
)}
|
||||
{ChatViewToggleButton(
|
||||
coreViewModel.translations.chatPage.pages.settings,
|
||||
"settings",
|
||||
ChatPageTypes.Settings,
|
||||
chatViewModel,
|
||||
getKeySymbol(CommonKeys.Settings),
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -57,6 +57,7 @@ export function HomePage(
|
||||
}
|
||||
on:click={connectionViewModel.disconnect}
|
||||
toggle:disabled={connectionViewModel.cannotDisonnect}
|
||||
ctkeystroke="x"
|
||||
>
|
||||
<span class="icon">link_off</span>
|
||||
</button>
|
||||
@@ -80,6 +81,7 @@ export function HomePage(
|
||||
}
|
||||
on:click={connectionViewModel.connect}
|
||||
toggle:disabled={connectionViewModel.cannotConnect}
|
||||
ctkeystroke="c"
|
||||
>
|
||||
<span class="icon">link</span>
|
||||
</button>
|
||||
@@ -91,16 +93,19 @@ export function HomePage(
|
||||
settingsViewModel.showSettingsModal,
|
||||
coreViewModel.translations.homePage.settingsButton,
|
||||
"settings",
|
||||
",",
|
||||
)}
|
||||
{HomePageButton(
|
||||
fileTransferViewModel.showDirectionSelectionModal,
|
||||
coreViewModel.translations.homePage.transferDataButton,
|
||||
"sync_alt",
|
||||
"t",
|
||||
)}
|
||||
{HomePageButton(
|
||||
storageViewModel.showStorageModal,
|
||||
coreViewModel.translations.homePage.manageStorageButton,
|
||||
"hard_drive",
|
||||
"e",
|
||||
)}
|
||||
|
||||
<button
|
||||
|
||||
+12
-1
@@ -1,5 +1,5 @@
|
||||
export enum CommonKeys {
|
||||
Home = " ",
|
||||
Home = "w",
|
||||
Filter = "=",
|
||||
Reset = "-",
|
||||
Options = ".",
|
||||
@@ -8,3 +8,14 @@ export enum CommonKeys {
|
||||
Settings = ",",
|
||||
Create = "a",
|
||||
}
|
||||
|
||||
export function getKeySymbol(keystroke: string): string {
|
||||
switch (keystroke) {
|
||||
case "backspace":
|
||||
return "⌫";
|
||||
case "enter":
|
||||
return "⏎";
|
||||
default:
|
||||
return keystroke;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ export default class CoreViewModel {
|
||||
if (!(e instanceof KeyboardEvent))
|
||||
return console.trace("NOT A KEY EVENT");
|
||||
if (CoreViewModel.checkIsKeystroke(e) == false) return;
|
||||
document.body.setAttribute("keystroke-active", "");
|
||||
e.preventDefault();
|
||||
const contexts: Context[] = this.contexts;
|
||||
while (contexts.length > 0) {
|
||||
@@ -75,6 +76,10 @@ export default class CoreViewModel {
|
||||
}
|
||||
};
|
||||
|
||||
handleKeyUp = (): void => {
|
||||
document.body.removeAttribute("keystroke-active");
|
||||
};
|
||||
|
||||
// CHRON
|
||||
chronHandlerManager = new HandlerManager<void>();
|
||||
todayDate = new React.State<Date>(new Date());
|
||||
@@ -154,6 +159,7 @@ export default class CoreViewModel {
|
||||
});
|
||||
|
||||
document.body.addEventListener("keydown", this.handleKeyDown);
|
||||
document.body.addEventListener("keyup", this.handleKeyUp);
|
||||
|
||||
window.onpopstate = () => {
|
||||
if (!this.context) return;
|
||||
|
||||
@@ -324,7 +324,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
|
||||
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal);
|
||||
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter);
|
||||
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter); //
|
||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, this.hideFilterModal);
|
||||
this.registerKeyStroke(CommonKeys.Settings, this.showSettings);
|
||||
this.registerKeyStroke(CommonKeys.Apply, this.hideSettings);
|
||||
|
||||
@@ -113,3 +113,37 @@ body[theme="dark"] #background-wrapper #grass-2 {
|
||||
|
||||
padding: var(--content-padding);
|
||||
}
|
||||
|
||||
/* Keystrokes */
|
||||
[ctkeystroke] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[ctkeystroke]::after {
|
||||
content: attr(ctkeystroke);
|
||||
|
||||
background: var(--primary);
|
||||
color: var(--text-on-color);
|
||||
|
||||
--size: 24px;
|
||||
|
||||
position: absolute;
|
||||
top: calc(50% - var(--size) / 2);
|
||||
left: calc(50% - var(--size) / 2);
|
||||
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
transition: all calc(var(--animation-duration) / 2);
|
||||
}
|
||||
|
||||
body[keystroke-active] [ctkeystroke]::after {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user