Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard modes #1960

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions app/bibleview-js/src/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,24 @@ $modal-content-background-color-night: rgb(33, 33, 33);
}
}

$focusDay: rgb(255, 182, 123, 1.0);
$focusNight: rgb(255, 182, 123, 0.5);

:focus-visible {
outline: $focusDay auto 1px;
& .night {
outline: $focusNight auto 1px;
}
}

.isFocused {
//@extend .isHighlighted;
//background-color: rgba(255, 0, 0, 0.1);
//.night & {
// background-color: rgba(255, 0, 0, 0.3);
//}
}

.one-liner {
white-space: nowrap;
text-overflow: ellipsis;
Expand Down
26 changes: 18 additions & 8 deletions app/bibleview-js/src/components/BibleView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
-->

<template>
<div @click="ambiguousSelection.handle" :class="{night: appSettings.nightMode}" :style="topStyle" :dir="direction">
<div @click="ambiguousSelection.handle" :class="{keyboardMode, night: appSettings.nightMode}" :style="topStyle" :dir="direction">
<div class="background" :style="backgroundStyle"/>
<div :style="`height:${calculatedConfig.topOffset}px`"/>
<div :style="modalStyle" id="modals"/>
Expand All @@ -27,7 +27,7 @@
<ErrorBox v-if="appSettings.errorBox"/>
<DevelopmentMode :current-verse="currentVerse" v-if="config.developmentMode"/>
<div v-if="calculatedConfig.topMargin > 0" class="top-margin" :style="`height: ${calculatedConfig.topOffset}px;`"/>
<div v-if="appSettings.hasActiveIndicator">
<div v-if="appSettings.hasActiveIndicator || keyboardMode">
<div class="top-left-corner"/>
<div class="top-right-corner"/>
<div class="bottom-left-corner"/>
Expand All @@ -51,7 +51,6 @@ import {
useCustomCss,
useCustomFeatures,
useFontAwesome, useModal, useSharing,
useVerseHighlight,
useVerseNotifier
} from "@/composables";
import {testBookmarkLabels, testData} from "@/testdata";
Expand All @@ -69,6 +68,7 @@ import Color from "color";
import {useStrings} from "@/composables/strings";
import {DocumentTypes} from "@/constants";
import {useKeyboard} from "@/composables/keyboard";
import {useVerseHandler} from "@/composables/verse-handling";

export default {
name: "BibleView",
Expand All @@ -89,19 +89,22 @@ export default {
window.bibleViewDebug.documents = documents;
const topElement = ref(null);
const documentPromise = ref(null);
const verseHighlight = useVerseHighlight();
provide("verseHighlight", verseHighlight);
const {resetHighlights} = verseHighlight;
const scroll = useScroll(config, appSettings, calculatedConfig, verseHighlight, documentPromise);
const verseHandler = useVerseHandler(computed(() => keyboardMode.value));
provide("verseHandler", verseHandler);
const {resetHighlights} = verseHandler;
const scroll = useScroll(config, appSettings, calculatedConfig, verseHandler, documentPromise);
const {doScrolling, scrollToId} = scroll;
provide("scroll", scroll);
const globalBookmarks = useGlobalBookmarks(config);
const android = useAndroid(globalBookmarks, config);
useKeyboard(android);

const modal = useModal(android);
provide("modal", modal);

const keyboard = useKeyboard( {android, appSettings, verseHandler, modal});
const {keyboardMode} = keyboard;
provide("keyboard", keyboard);

let footNoteCount = 0;

function getFootNoteCount() {
Expand Down Expand Up @@ -282,6 +285,7 @@ export default {
updateBookmarks: globalBookmarks.updateBookmarks, ambiguousSelection,
config, strings, documents, topElement, currentVerse, mounted, emit, Events, isLoading,
contentStyle, backgroundStyle, modalStyle, topStyle, calculatedConfig, appSettings,
keyboardMode,
};
},
}
Expand Down Expand Up @@ -360,8 +364,14 @@ $borderDistance: 0;
border-width: 2.5px;
.night & {
border-color: rgba(196, 196, 255, 0.8);
.keyboardMode & {
border-color: $focusNight;
}
}
border-color: rgba(0, 0, 255, 0.6);
.keyboardMode & {
border-color: $focusDay;;
}
}

.top-left-corner {
Expand Down
2 changes: 1 addition & 1 deletion app/bibleview-js/src/components/OSIS/Reference.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default {
const clicked = ref(false);
const isHighlighted = ref(false);
const {strings, ...common} = useCommon();
const {addCustom, resetHighlights} = inject("verseHighlight");
const {addCustom, resetHighlights} = inject("verseHandler");
const referenceCollector = inject("referenceCollector", null);
const content = ref(null);
const osisFragment = inject("osisFragment");
Expand Down
26 changes: 22 additions & 4 deletions app/bibleview-js/src/components/OSIS/Verse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
-->

<template>
<span :id="`v-${ordinal}`" @click="verseClicked">
<span :id="`v-${ordinal}`" @click="verseClicked" class="verse" ref="verseRef">
<span
:id="fromBibleDocument ? `o-${ordinal}` : null"
class="verse"
:class="{ordinal: fromBibleDocument}"
:data-ordinal="ordinal"
>
<span class="highlight-transition" :class="{isHighlighted: highlighted}">
<span class="highlight-transition" :class="{isFocused, isHighlighted: highlighted}">
<VerseNumber v-if="shown && config.showVerseNumbers && verse !== 0" :verse-num="verse"/><slot/> <span/>
</span>
</span>
Expand All @@ -32,7 +32,7 @@
</template>

<script>
import {inject, provide, reactive, ref} from "@vue/runtime-core";
import {inject, provide, reactive, ref, watch} from "@vue/runtime-core";
import VerseNumber from "@/components/VerseNumber";
import {useCommon} from "@/composables";
import {addEventVerseInfo, getVerseInfo} from "@/utils";
Expand All @@ -49,19 +49,31 @@ export default {
const bibleDocumentInfo = inject("bibleDocumentInfo", {})
const {bookInitials, bibleBookName, originalOrdinalRange, ordinalRange, v11n} = bibleDocumentInfo;
const verseInfo = {...getVerseInfo(props), v11n};
const verseRef = ref(null);

const shown = ref(true);
if(verseInfo) {
verseInfo.showStack = reactive([shown]);
provide("verseInfo", verseInfo);
}

const {highlightedVerses, highlightVerse} = inject("verseHighlight");
const {highlightedVerses, highlightVerse, focusedVerse} = inject("verseHandler");

const ordinal = computed(() => {
return parseInt(props.verseOrdinal);
});

const isFocused = computed(() => focusedVerse.value === ordinal.value);

watch(isFocused, v => {
if(v) {
//if(!isCompletelyInViewport(verseRef.value)) {
// verseRef.value.scrollIntoView({behavior: "smooth"});
//}
verseRef.value.focus();
}
})

const book = computed(() => {
return props.osisID.split(".")[0]
});
Expand Down Expand Up @@ -97,6 +109,8 @@ export default {
highlighted,
fromBibleDocument,
verseClicked,
isFocused,
verseRef,
...common,
}
},
Expand All @@ -108,4 +122,8 @@ export default {
.linebreak {
display: block;
}
.verse {

}

</style>
2 changes: 1 addition & 1 deletion app/bibleview-js/src/components/OSIS/W.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default {
checkUnsupportedProps(props, "subType")
const {strings, config, ...common} = useCommon();
const isHighlighted = ref(false);
const {addCustom, resetHighlights} = inject("verseHighlight");
const {addCustom, resetHighlights} = inject("verseHandler");
function prep(string) {
let remainingString = string;
const res = []
Expand Down
5 changes: 4 additions & 1 deletion app/bibleview-js/src/components/TextEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ export default {
}
}

watch(editText, debounce(save, 2000))
const {setEditMode} = inject("keyboard");

watch(editText, debounce(save, 2000))
const divider = {divider: true};

function openDownloads() {
Expand All @@ -199,6 +200,7 @@ export default {
editor.value.content.innerHTML = editText.value;
editor.value.content.focus();
android.setEditing(true);
setEditMode(true);
});

setupElementEventListener(editorElement, "keyup", e => {
Expand All @@ -215,6 +217,7 @@ export default {

onUnmounted(() => {
android.setEditing(false);
setEditMode(false);
})

return {setFocus, editorElement, dirty, inputText, showHelp, openDownloads, hasRefParser, refChooserDialog, ...useCommon()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default {
const android = inject("android");
const multiSelectionMode = ref(false);

const {resetHighlights, highlightVerse, hasHighlights} = inject("verseHighlight");
const {resetHighlights, highlightVerse, hasHighlights} = inject("verseHandler");
const {modalOpen, closeModals} = inject("modal");

const showModal = ref(false);
Expand Down
26 changes: 0 additions & 26 deletions app/bibleview-js/src/composables/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,32 +470,6 @@ export function useReferenceCollector() {
return {references, collect, clear}
}

export function useVerseHighlight() {
const highlightedVerses = reactive(new Set());
const undoCustomHighlights = reactive([]);

const hasHighlights = computed(() => highlightedVerses.size > 0 || undoCustomHighlights.length > 0);

function resetHighlights(onlyVerses = false) {
highlightedVerses.clear();
if(!onlyVerses) {
undoCustomHighlights.forEach(f => f())
undoCustomHighlights.splice(0);
}
}

function highlightVerse(ordinal) {
highlightedVerses.add(ordinal);
}

function addCustom(f) {
undoCustomHighlights.push(f);
}

return {highlightVerse, addCustom, highlightedVerses, resetHighlights, hasHighlights}
}


function useParsers(android) {
const enParser = new BcvParser;
const parsers = [enParser];
Expand Down
76 changes: 69 additions & 7 deletions app/bibleview-js/src/composables/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,82 @@
*/

import {setupDocumentEventListener} from "@/utils";
import {ref} from "@vue/reactivity";
import {watch} from "@vue/runtime-core";

const altKeys = new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "KeyW", "KeyM", "KeyO", "KeyG"]);
const keys = new Set([]);
const keys = new Set(["KeyW", "KeyM", "KeyO", "KeyG"]);
const focusKeys = new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Tab"]);

export function useKeyboard(
{
android: {onKeyDown},
appSettings,
verseHandler: {adjFocusedVerse},
modal: {modalOpen},
}) {
const keyboardMode = ref(false);
const editMode = ref(false);

export function useKeyboard({onKeyDown}) {
setupDocumentEventListener("keydown", e => {
if(keys.has(e.code) || (e.altKey && altKeys.has(e.code))) {
if(editMode.value) {
return;
}

console.log("Keycode:", e.code);

if (keys.has(e.code)) {
let key = e.code;
if(e.altKey) {
key = "Alt" + key;
}
onKeyDown(key);
e.preventDefault();
e.stopPropagation();
return;
}

if(!keyboardMode.value) {
if(e.code === "Enter") {
keyboardMode.value = true
}
else if(focusKeys.has(e.code)) {
onKeyDown(e.code);
}
e.preventDefault();
e.stopPropagation();
}

if(keyboardMode.value) {
let handled = false;

if(modalOpen.value) return;

switch(e.code) {
case "Escape":
keyboardMode.value = false
handled = true;
break;
case "ArrowUp":
adjFocusedVerse(-1);
handled = true;
break;
case "ArrowDown":
adjFocusedVerse(1);
handled = true;
break;
}
if (handled) {
e.preventDefault();
e.stopPropagation();
}
}
});

watch(() => appSettings.activeWindow, v => {
if(!v) {
keyboardMode.value = false;
}
});

return {
setEditMode: v => editMode.value = v,
keyboardMode,
}
}
5 changes: 4 additions & 1 deletion app/bibleview-js/src/composables/scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import {Events, setupEventBusListener} from "@/eventbus";
import {computed, ref} from "@vue/reactivity";
import {isInViewport} from "@/utils";

export function useScroll(config, appSettings, calculatedConfig, {highlightVerse, resetHighlights}, documentPromise) {
export function useScroll(
config, appSettings, calculatedConfig, {highlightVerse, resetHighlights, setFocusedVerse}, documentPromise
) {
let currentScrollAnimation = ref(null);
const isScrolling = computed(() => currentScrollAnimation.value != null)

Expand Down Expand Up @@ -138,6 +140,7 @@ export function useScroll(config, appSettings, calculatedConfig, {highlightVerse

if (jumpToOrdinal != null) {
scrollToId(`o-${jumpToOrdinal}`, {now: true, force: true});
setFocusedVerse(jumpToOrdinal);
} else if (jumpToAnchor !== null) {
scrollToId(`o-${jumpToAnchor}`, {now: true, force: true});
} else if(jumpToId !== null) {
Expand Down
Loading