mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
Implement accepting suggestions via Enter
This commit is contained in:
parent
b93646209a
commit
a29d21f4fd
4 changed files with 44 additions and 17 deletions
|
@ -51,8 +51,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: button.$focus-color;
|
background-color: button.$focus-color !important;
|
||||||
color: white;
|
color: white !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
let activeName = "";
|
let activeName = "";
|
||||||
let activeInput: HTMLInputElement;
|
let activeInput: HTMLInputElement;
|
||||||
|
|
||||||
function onAutocomplete({ detail }) {
|
|
||||||
const activeTag = tags[active!];
|
|
||||||
const selected = detail.selected;
|
|
||||||
|
|
||||||
activeName = selected ?? activeTag.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
let suggestionsPromise: Promise<string[]> = Promise.resolve([]);
|
let suggestionsPromise: Promise<string[]> = Promise.resolve([]);
|
||||||
|
|
||||||
function updateSuggestions(): void {
|
function updateSuggestions(): void {
|
||||||
|
@ -49,6 +42,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAutocomplete(selected: string): void {
|
||||||
|
const activeTag = tags[active!];
|
||||||
|
|
||||||
|
activeName = selected ?? activeTag.name;
|
||||||
|
activeInput.setSelectionRange(Infinity, Infinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChosen(chosen: string) {
|
||||||
|
onAutocomplete(chosen);
|
||||||
|
splitTag(active!, Infinity, Infinity);
|
||||||
|
}
|
||||||
|
|
||||||
function updateWithTagName(tag: TagType): void {
|
function updateWithTagName(tag: TagType): void {
|
||||||
tag.name = activeName;
|
tag.name = activeName;
|
||||||
tags = tags;
|
tags = tags;
|
||||||
|
@ -96,13 +101,26 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
contained
|
contained
|
||||||
);
|
);
|
||||||
if (contained >= 0) {
|
if (contained >= 0) {
|
||||||
tags[contained].flash();
|
tags[contained >= index ? contained + 1 : contained].flash();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function enterBehavior(
|
||||||
|
index: number,
|
||||||
|
start: number,
|
||||||
|
end: number,
|
||||||
|
autocomplete: any
|
||||||
|
): Promise<void> {
|
||||||
|
if (autocomplete.isVisible()) {
|
||||||
|
autocomplete.chooseSelected();
|
||||||
|
} else {
|
||||||
|
splitTag(index, start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function splitTag(index: number, start: number, end: number): Promise<void> {
|
async function splitTag(index: number, start: number, end: number): Promise<void> {
|
||||||
const current = activeName.slice(0, start);
|
const current = activeName.slice(0, start);
|
||||||
const splitOff = activeName.slice(end);
|
const splitOff = activeName.slice(end);
|
||||||
|
@ -271,8 +289,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
<WithAutocomplete
|
<WithAutocomplete
|
||||||
class="d-flex flex-column-reverse"
|
class="d-flex flex-column-reverse"
|
||||||
{suggestionsPromise}
|
{suggestionsPromise}
|
||||||
on:autocomplete={onAutocomplete}
|
|
||||||
on:update={updateSuggestions}
|
on:update={updateSuggestions}
|
||||||
|
on:autocomplete={({ detail }) =>
|
||||||
|
onAutocomplete(detail.selected)}
|
||||||
|
on:choose={({ detail }) => onChosen(detail.chosen)}
|
||||||
let:createAutocomplete
|
let:createAutocomplete
|
||||||
let:autocomplete
|
let:autocomplete
|
||||||
>
|
>
|
||||||
|
@ -280,7 +300,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
id={tag.id}
|
id={tag.id}
|
||||||
bind:name={activeName}
|
bind:name={activeName}
|
||||||
bind:input={activeInput}
|
bind:input={activeInput}
|
||||||
on:click={(event) => event.stopPropagation()}
|
|
||||||
on:focus={() => {
|
on:focus={() => {
|
||||||
activeName = tag.name;
|
activeName = tag.name;
|
||||||
createAutocomplete(activeInput);
|
createAutocomplete(activeInput);
|
||||||
|
@ -288,7 +307,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
on:keydown={(event) => update(event, autocomplete)}
|
on:keydown={(event) => update(event, autocomplete)}
|
||||||
on:input={() => updateWithTagName(tag)}
|
on:input={() => updateWithTagName(tag)}
|
||||||
on:tagsplit={({ detail }) =>
|
on:tagsplit={({ detail }) =>
|
||||||
splitTag(index, detail.start, detail.end)}
|
enterBehavior(
|
||||||
|
index,
|
||||||
|
detail.start,
|
||||||
|
detail.end,
|
||||||
|
autocomplete
|
||||||
|
)}
|
||||||
on:tagadd={() => insertTag(index)}
|
on:tagadd={() => insertTag(index)}
|
||||||
on:tagdelete={() => deleteTagAt(index)}
|
on:tagdelete={() => deleteTagAt(index)}
|
||||||
on:tagjoinprevious={() => joinWithPreviousTag(index)}
|
on:tagjoinprevious={() => joinWithPreviousTag(index)}
|
||||||
|
|
|
@ -87,6 +87,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
function onEnter(event: Event): void {
|
function onEnter(event: Event): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
dispatch("tagsplit", { start: input.selectionStart, end: input.selectionEnd });
|
dispatch("tagsplit", { start: input.selectionStart, end: input.selectionEnd });
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeydown(event: KeyboardEvent): void {
|
function onKeydown(event: KeyboardEvent): void {
|
||||||
|
|
|
@ -19,9 +19,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
let target: HTMLElement;
|
let target: HTMLElement;
|
||||||
let dropdown: Dropdown;
|
let dropdown: Dropdown;
|
||||||
let autocomplete: any;
|
let autocomplete: any;
|
||||||
let selected: number | null = null;
|
|
||||||
|
|
||||||
// blue highlight
|
let selected: number | null = null;
|
||||||
let active: boolean = false;
|
let active: boolean = false;
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
@ -54,8 +53,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
dispatch("autocomplete", { selected: suggestions[selected ?? -1] });
|
dispatch("autocomplete", { selected: suggestions[selected ?? -1] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseSelected() {
|
async function chooseSelected() {
|
||||||
|
const suggestions = await suggestionsPromise;
|
||||||
|
|
||||||
active = true;
|
active = true;
|
||||||
|
dispatch("choose", { chosen: suggestions[selected ?? -1] });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update() {
|
async function update() {
|
||||||
|
@ -102,7 +104,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
async function chooseIndex(index: number): Promise<void> {
|
async function chooseIndex(index: number): Promise<void> {
|
||||||
const suggestions = await suggestionsPromise;
|
const suggestions = await suggestionsPromise;
|
||||||
dispatch("autocomplete", { selected: suggestions[index] });
|
dispatch("autocomplete", { name: suggestions[index] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectIfMousedown(event: MouseEvent, index: number): void {
|
function selectIfMousedown(event: MouseEvent, index: number): void {
|
||||||
|
|
Loading…
Reference in a new issue