Skip to content

Commit

Permalink
implement deep linking of langauges and words
Browse files Browse the repository at this point in the history
commit 8d841926b10f72abf165ce6bb4c4e94f894e2154
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:58:37 2023 +1100

    deep linking related changes

commit e76e0b672791665005611bba8b7aa338165edb7b
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:55:51 2023 +1100

    trigger and await data loading before mount

    This is required for deep linking to languages and words to work. In the
    old way of dispatch the store we wouldn't know when the data was
    available and ready.

commit ee472c904f36094e3fb705910820638fcf8ec059
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:54:10 2023 +1100

    adjust layout

commit 5355d20964695f99c24be50a9d73b8a2d1d95ef8
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:53:44 2023 +1100

    revise map height for small screens

commit 7e3ec21f5b0ff861045c1a20aa5b6b57f2662f4e
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:33:12 2023 +1100

    revise home link to be languages

commit ee80ba0cc115d7cc439b5b5ce67574ad33ddf54f
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:29:12 2023 +1100

    set bounds on mamp init; cleanup

commit f82af1ff9fda1b9e763e45a97d176e0ba44b7cf3
Author: Marco La Rosa <[email protected]>
Date:   Fri Nov 3 09:28:16 2023 +1100

    add routes for deep links to langauges and words
  • Loading branch information
marcolarosa committed Nov 2, 2023
1 parent 1dbabc8 commit 97239b8
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 232 deletions.
2 changes: 1 addition & 1 deletion src/components/Header.component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ function playAll() {
router.push({ name: "playall" });
}
function home() {
router.push({ name: "home" });
router.push({ name: "languages" });
}
</script>
6 changes: 3 additions & 3 deletions src/components/HeaderMobile.component.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="flex flex-col">
<div class="flex flex-row justify-between">
<div class="flex flex-col space-y-4">
<div class="flex flex-row justify-between mt-2">
<el-button
:link="true"
class="text-gray-600"
Expand Down Expand Up @@ -74,7 +74,7 @@ export default {
},
methods: {
home() {
this.$router.push({ name: "home" }).catch(() => {});
this.$router.push({ name: "languages" }).catch(() => {});
},
showHelp() {
this.$router.push({ name: "help" }).catch(() => {});
Expand Down
108 changes: 64 additions & 44 deletions src/components/InformationPanel.component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="flex flex-col">
<div class="text-sm text-gray-600">View by</div>
<el-tabs v-model="activeTab" @tab-click="handleTabSelect" class="text-gray-700">
<el-tab-pane name="language">
<el-tab-pane name="languages">
<template #label>
<span
:class="{
Expand All @@ -13,12 +13,12 @@
LANGUAGE
</span>
</template>
<div v-if="activeTab === 'language'">
<div v-if="activeTab === 'languages'">
<information-panel-language-list-component v-if="show === 'list'" />
<information-panel-view-language-component v-if="show === 'language'" />
</div>
</el-tab-pane>
<el-tab-pane label="word" name="word">
<el-tab-pane label="word" name="words">
<template #label>
<span
:class="{
Expand All @@ -28,7 +28,7 @@
>WORD</span
>
</template>
<div v-if="activeTab === 'word'">
<div v-if="activeTab === 'words'">
<information-panel-word-list-component v-if="show === 'list'" />
<information-panel-view-word-component v-if="show === 'word'" />
</div>
Expand All @@ -37,51 +37,71 @@
</div>
</template>

<script>
<script setup>
import InformationPanelLanguageListComponent from "./InformationPanelLanguageList.component.vue";
import InformationPanelViewLanguageComponent from "./InformationPanelViewLanguage.component.vue";
import InformationPanelWordListComponent from "./InformationPanelWordList.component.vue";
import InformationPanelViewWordComponent from "./InformationPanelViewWord.component.vue";
import { ref, reactive, watch, computed } from "vue";
import { useStore } from "vuex";
import { useRouter, useRoute } from "vue-router";
const $store = useStore();
const $route = useRoute();
const $router = useRouter();
export default {
components: {
InformationPanelLanguageListComponent,
InformationPanelViewLanguageComponent,
InformationPanelWordListComponent,
InformationPanelViewWordComponent,
},
data() {
return {
activeTab: "language",
show: "list",
language: undefined,
};
},
computed: {
selection: function () {
return this.$store.state.selection;
},
},
watch: {
selection: function () {
this.show = this.$store.state.selection.type
? this.$store.state.selection.type
: "list";
},
let activeTab = ref("languages");
let show = ref("list");
// this watcher handles loading the correct component
// as a result of back / forward navigation events
watch(
() => $route.path,
() => {
if ($route.name === "home") $router.push("languages");
if ($route.path.match(/\languages/)) activeTab.value = "languages";
if ($route.path.match(/\/words/)) activeTab.value = "words";
if (["/languages", "/words"].includes($route.path)) {
handleTabSelect({ props: { name: $route.name } });
}
},
methods: {
handleTabSelect(tab) {
this.$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
if (tab.props.name === "language") {
this.$store.commit("setLayer", "languages");
this.show = "list";
} else {
this.$store.commit("setLayer", "words");
}
},
{ immediate: true }
);
// this watcher handles route updates as the user selects
// languages / words to interact with
watch(
() => $store.state.selection,
() => {
const selection = $store.state.selection;
show.value = selection?.type ?? "list";
if (show.value === "list") {
$router.push({ path: `/${activeTab.value}` });
} else {
let name =
activeTab.value === "languages"
? selection.data?.properties?.name
: selection.data?.name;
$router.push({ path: `/${activeTab.value}/${name}` });
}
},
};
{ deep: true }
);
function handleTabSelect(tab) {
$router.push(`/${tab.props.name}`);
activeTab.value = tab.props.name;
setTimeout(() => {
$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
show.value = "list";
if (tab.props.name === "languages") {
$store.commit("setLayer", "languages");
} else {
$store.commit("setLayer", "words");
}
}, 100);
}
</script>
25 changes: 21 additions & 4 deletions src/components/InformationPanelLanguageList.component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,39 @@
</template>

<script setup>
import { reactive, computed } from "vue";
import { reactive, computed, watch } from "vue";
import { useStore } from "vuex";
const store = useStore();
import { useRoute } from "vue-router";
const $store = useStore();
const $route = useRoute();
// this watcher handles language loading in response to nav events
watch(
() => $route.path,
() => {
if ($route.params?.language) {
let language = $store.state.languages
.map((language) => language.properties)
.filter((language) => language.name === $route.params.language);
if (language.length) displayLanguage(language[0]);
}
},
{ immediate: true }
);
const data = reactive({
filter: "",
});
let languages = computed(() => {
const regexp = new RegExp(data.filter, "i");
return store.state.languages
return $store.state.languages
.map((language) => language.properties)
.filter((language) => language.words)
.filter((l) => l.language.name.match(regexp));
});
function displayLanguage(language) {
store.dispatch("loadLanguage", { code: language.code });
$store.dispatch("loadLanguage", { code: language.code });
}
</script>
Expand Down
61 changes: 25 additions & 36 deletions src/components/InformationPanelViewLanguage.component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,45 +63,34 @@
</div>
</template>

<script>
<script setup>
import RenderLanguageInformationPlayComponent from "./RenderLanguageInformationPlay.component.vue";
import InformationPanelRenderWordComponent from "./InformationPanelRenderWord.component.vue";
import LanguageInformationComponent from "./LanguageInformation.component.vue";
import PlayAllWordsComponent from "./PlayAllWords.component.vue";
import { ref, computed } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
const $store = useStore();
const $router = useRouter();
export default {
components: {
RenderLanguageInformationPlayComponent,
InformationPanelRenderWordComponent,
LanguageInformationComponent,
PlayAllWordsComponent,
},
data() {
return {
playAllWords: false,
height:
window.innerWidth < 768
? `${window.innerHeight - (window.innerHeight * 0.4 + 60)}px`
: `${window.innerHeight - 170}px`,
};
},
computed: {
language: function () {
return this.$store.getters.getSelectionData();
},
},
methods: {
back() {
this.$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
},
index(word) {
return `${word.english}${word.indigenous}`;
},
},
};
let playAllWords = ref(false);
let height = ref(
window.innerWidth < 768
? `${window.innerHeight - (window.innerHeight * 0.4 + 60)}px`
: `${window.innerHeight - 170}px`
);
let language = computed(() => $store.getters.getSelectionData());
function back() {
$router.push("/languages");
setTimeout(() => {
$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
}, 100);
}
function index(word) {
return `${word.english}${word.indigenous}`;
}
</script>

<style lang="scss" scoped></style>
62 changes: 26 additions & 36 deletions src/components/InformationPanelViewWord.component.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="overflow-scroll text-black" :style="{ height: height }" v-if="data">
<div class="overflow-scroll text-black" :style="{ height: height }">
<div class="flex flex-col">
<div class="flex flex-row px-2 md:my-2">
<div
Expand All @@ -8,7 +8,7 @@
>
<i class="fas fa-chevron-left"></i>
</div>
<div class="text-2xl">{{ data.name }}</div>
<div class="text-2xl">{{ selection.name }}</div>
<div class="flex flex-grow"></div>
</div>

Expand All @@ -32,54 +32,44 @@

<div v-if="playAllWords">
<play-all-words-component
:words="data.words"
:words="selection.words"
display="languageName"
@finished-playing="playAllWords = false"
/>
</div>
<div v-if="!playAllWords">
<div v-for="(word, idx) of data.words" :key="idx" class="m-1">
<div v-for="(word, idx) of selection.words" :key="idx" class="m-1">
<information-panel-render-word-component :data="word" display="languageName" />
</div>
</div>
</div>
</div>
</template>

<script>
<script setup>
import RenderLanguageInformationPlayComponent from "./RenderLanguageInformationPlay.component.vue";
import InformationPanelRenderWordComponent from "./InformationPanelRenderWord.component.vue";
import PlayAllWordsComponent from "./PlayAllWords.component.vue";
import { ref, computed } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
const $store = useStore();
const $router = useRouter();
export default {
components: {
RenderLanguageInformationPlayComponent,
InformationPanelRenderWordComponent,
PlayAllWordsComponent,
},
data() {
return {
playAllWords: false,
height:
window.innerWidth < 768
? `${window.innerHeight - (window.innerHeight * 0.4 + 60)}px`
: `${window.innerHeight - 170}px`,
};
},
computed: {
data: function () {
return this.$store.getters.getSelectionData();
},
},
methods: {
back() {
this.$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
},
},
};
let playAllWords = ref(false);
let height = ref(
window.innerWidth < 768
? `${window.innerHeight - (window.innerHeight * 0.4 + 60)}px`
: `${window.innerHeight - 170}px`
);
let selection = computed(() => $store.getters.getSelectionData());
function back() {
$router.push("/words");
setTimeout(() => {
$store.commit("setSelectionToDisplay", {
type: undefined,
data: undefined,
});
}, 100);
}
</script>

<style lang="scss" scoped></style>
Loading

0 comments on commit 97239b8

Please sign in to comment.