Skip to content

Commit

Permalink
Merge pull request #82 from camarm-dev/dev
Browse files Browse the repository at this point in the history
Resolved #80 and #74 (end of 1.0.0-beta)
  • Loading branch information
camarm-dev authored Jan 21, 2024
2 parents 58a5ca4 + 26e2706 commit 15d2b9f
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 53 deletions.
2 changes: 1 addition & 1 deletion api-definition
4 changes: 2 additions & 2 deletions app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "com.camarm.remede"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
versionCode 1100
versionName '1.1.0-beta'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
Expand Down
4 changes: 2 additions & 2 deletions app/android/app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"versionCode": 1100,
"versionName": "1.1.0-beta",
"outputFile": "app-release.apk"
}
],
Expand Down
2 changes: 1 addition & 1 deletion app/electron/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "remede",
"version": "1.0.0",
"version": "1.1.0-beta",
"description": "A french mobile and offline dictionary.",
"build": {
"appId": "com.camarm.remede",
Expand Down
Binary file added app/src/assets/kofi.webp
Binary file not shown.
Binary file added app/src/assets/labse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 94 additions & 32 deletions app/src/components/WordModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ import {
IonItem,
IonModal,
IonAccordion,
IonAccordionGroup,
useBackButton,
useIonRouter
IonAccordionGroup
} from "@ionic/vue";
import {
bookmark,
bookmarkOutline,
bookmarkOutline, caretBackOutline,
chevronBackOutline,
chevronDownOutline,
ellipsisVertical,
Expand All @@ -35,16 +33,6 @@ import {
import WordModal from "@/components/WordModal.vue";
import example from "@/assets/example.svg"
import copyright from "@/assets/copyright.svg"
const ionRouter = useIonRouter()
useBackButton(110, () => {
if (ionRouter.canGoBack()) {
ionRouter.back()
return
}
ionRouter.navigate('/dictionnaire', 'back', 'replace')
});
</script>

<template>
Expand Down Expand Up @@ -74,6 +62,12 @@ useBackButton(110, () => {
</ion-header>
<ion-content :fullscreen="true" class="ion-padding">
<ion-header collapse="condense">
<ion-buttons v-if="history.length > 0">
<ion-button size="small" color="dark" @click="goToPreviousDefinition()">
<ion-icon slot="start" :icon="caretBackOutline"/>
Revenir à "{{ history[history.length - 1] }}"
</ion-button>
</ion-buttons>
<ion-toolbar>
<ion-label>
<ion-title class="remede-font" size="large">{{ mot }}</ion-title>
Expand Down Expand Up @@ -101,7 +95,7 @@ useBackButton(110, () => {
</ion-note>
</div>
<div v-if="tab == 'def'" class="tab-content">
<div class="definition" :key="def" v-for="def in document.definitions">
<div class="definition" :key="`def-genre-${document.definitions.indexOf(def).toString()}`" v-for="def in document.definitions">
<header>
<h4 v-if="typeof def.genre !== 'string'">{{ def.genre[0] }}, {{ def.genre[1] }}</h4>
<h4 v-else-if="def.genre != def.classe && def.classe != ''">{{ def.genre }}, {{ def.classe }}</h4>
Expand All @@ -115,10 +109,10 @@ useBackButton(110, () => {
</ion-list>
<div class="content">
<ul>
<li :key="meaning" v-for="meaning in def.explications">
<span v-html="meaning.replaceAll('https://fr.wiktionary.org/wiki/', '/dictionnaire/')" v-if="typeof meaning === 'string'"></span>
<li :key="`def-${meaning}`" v-for="meaning in def.explications">
<span v-html="parseMeaning(meaning)" v-if="typeof meaning === 'string'"></span>
<ul v-else class="ion-padding-start">
<li :key="subMeaning" v-for="subMeaning in meaning" v-html="subMeaning"></li>
<li :key="subMeaning" v-for="subMeaning in meaning" v-html="parseMeaning(subMeaning)"></li>
</ul>
<ion-icon v-if="def.exemples.length > 0" :id="meaning" :icon="example" color="medium"/>
<ion-popover :trigger="meaning">
Expand Down Expand Up @@ -263,23 +257,40 @@ useBackButton(110, () => {

<script lang="ts">
import {getWordDocument} from "@/functions/dictionnary";
import {getWordDocument, wordExists} from "@/functions/dictionnary";
import {isWordStarred, starWord} from "@/functions/favorites";
import {Share} from "@capacitor/share";
import {RemedeConjugateDocument, RemedeWordDocument} from "@/functions/types/remede";
import {defineComponent} from "vue";
import {navigateBackFunction} from "@/functions/types/utils";
import {loadingController, useBackButton, useIonRouter} from "@ionic/vue";
import { iosTransitionAnimation } from '@ionic/core';
export default defineComponent({
props: ['motRemede'],
setup() {
const ionRouter = useIonRouter()
useBackButton(110, () => {
if (ionRouter.canGoBack()) {
ionRouter.back(iosTransitionAnimation)
return
}
ionRouter.navigate('/dictionnaire', 'back', 'replace', iosTransitionAnimation)
});
return {
ionRouter
}
},
data() {
return {
mot: '',
currentMode: '',
currentTemps: '',
modeTemps: [],
currentSujets: [],
tab: localStorage.getItem('defaultTab') || 'def',
modeTemps: [] as string[],
currentSujets: [] as string[],
tab: localStorage.getItem('defaultTab') || 'def' as string,
document: {
synonymes: [] as string[],
antonymes: [] as string[],
Expand All @@ -295,28 +306,40 @@ export default defineComponent({
notFound: false,
stared: false,
audioLoading: false,
history: [],
push: function () {
return
},
navigateBack: function () {
return false
} as navigateBackFunction
}
},
mounted() {
const ionRouter = useIonRouter()
function navigateBackIfNoHistory() {
if (!ionRouter.canGoBack()) {
ionRouter.navigate('/dictionnaire', 'back', 'replace')
ionRouter.navigate('/dictionnaire', 'back', 'replace', iosTransitionAnimation)
return true
}
return false
}
function push(path: string) {
ionRouter.push(path, iosTransitionAnimation)
}
this.push = push
this.navigateBack = navigateBackIfNoHistory
},
created() {
this.loadData()
this.loadData().then(() => {
this.listenSpecialTags()
})
},
methods: {
async loadData() {
this.mot = this.motRemede
async loadData(mot: null | string) {
this.mot = mot || this.motRemede
if (!this.motRemede) {
this.mot = this.$router.params.mot
}
Expand Down Expand Up @@ -352,13 +375,13 @@ export default defineComponent({
this.$router.push(path)
},
getModes() {
return Object.keys(this.document.conjugaisons)
return Object.keys(this.document.conjugaisons) as string[]
},
getTemps(mode: string) {
return Object.keys(this.document.conjugaisons[mode])
return Object.keys(this.document.conjugaisons[mode]) as string[]
},
getSujets(mode: string, temps: string) {
return Object.keys(this.document.conjugaisons[mode][temps])
return Object.keys(this.document.conjugaisons[mode][temps]) as string[]
},
getFormeVerbale(mode: string, temps: string, sujet: string) {
return this.document.conjugaisons[mode][temps][sujet]
Expand Down Expand Up @@ -390,13 +413,52 @@ export default defineComponent({
this.currentSujets = this.getSujets(this.currentMode, this.currentTemps)
},
getHtmlCredits() {
return `
Ce mot provient de la base Remède. Il suit les conditions et schémas <a href="https://remede.camarm.fr/FR#données-remède" target="_blank">de Remède</a>.
`
return `Ce mot provient de la base Remède. Il suit les conditions et schémas <a href="https://remede.camarm.fr/FR#données-remède" target="_blank">de Remède</a>.`
},
open(url: string) {
window.open(url)
},
async listenSpecialTags() {
document.querySelectorAll('reference').forEach(el => {
el.addEventListener('click', async () => {
const href = el.getAttribute('href')
const word = href.replaceAll('https://fr.wiktionary.org/wiki/', '')
if (await wordExists(word)) {
const oldWord = this.mot
const loader = await loadingController.create({
message: 'Chargement'
})
await loader.present()
await this.loadData(word).then(() => {
this.listenSpecialTags()
this.history.push(oldWord)
})
await loader.dismiss()
} else {
window.open(href)
}
})
})
},
parseMeaning(meaning: string) {
try {
return meaning.replaceAll('<a', '<reference').replaceAll('</a>', '</reference>')
} catch (e) {
return meaning
}
},
async goToPreviousDefinition() {
const word = this.history[this.history.length - 1]
const loader = await loadingController.create({
message: 'Chargement'
})
await loader.present()
await this.loadData(word).then(() => {
this.listenSpecialTags()
this.history.splice(-1, 1)
})
await loader.dismiss()
},
starWord
}
})
Expand Down
23 changes: 22 additions & 1 deletion app/src/functions/dictionnary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ async function getRandomWordFromDatabase() {
return await database?.getRandomWord() as string
}

async function doesWordExistsWithAPI(word: string) {
return (await fetch(`https://api-remede.camarm.fr/word/${word}`).then(resp => resp.json())).message != 'Mot non trouvé'
}

async function doesWordExistsWithDatabase(word: string) {
try {
await database?.getWord(word)
return true
} catch (e) {
return false
}
}

async function getAutocomplete(word: string) {
if (await useApi()) {
return await getAutocompleteWithAPI(word)
Expand Down Expand Up @@ -58,11 +71,19 @@ async function getTodayWord() {
}
}

async function wordExists(word: string) {
if (await useApi()) {
return doesWordExistsWithAPI(word)
}
return doesWordExistsWithDatabase(word)
}

const database = await useApi() ? null: new RemedeDatabase()

export {
getWordDocument,
getAutocomplete,
getRandomWord,
getTodayWord
getTodayWord,
wordExists
}
10 changes: 8 additions & 2 deletions app/src/functions/types/remede.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ interface RemedeExample {
sources: string
}


interface RemedeExplication {
[key: string]: string[] | string[][]
}

interface RemedeWordDefinition {
genre: string | string[]
classe: string
explications: string[] | string[][]
explications: RemedeExplication
exemples: RemedeExample[]
}

Expand Down Expand Up @@ -62,5 +67,6 @@ export type {
RemedeDictionaryIndex,
RemedeWordDocument,
RemedeConjugateDocument,
RemedeSheet
RemedeSheet,
RemedeWordDefinition
}
11 changes: 11 additions & 0 deletions app/src/theme/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ http://ionicframework.com/docs/theming/ */
src: url("./font/IBMPlexSerif-Bold.ttf");
}

reference {
cursor: pointer;
color: var(--ion-color-primary);
text-decoration: underline solid var(--ion-color-primary);
}

reference:hover {
color: var(--ion-color-primary-tint);
text-decoration: underline solid var(--ion-color-primary-tint);
}

.remede-font {
font-family: "IMBPlexSerif", serif !important;
text-transform: capitalize;
Expand Down
Loading

0 comments on commit 15d2b9f

Please sign in to comment.