From a5ee5c20cd53d83cbbc30f9ca8e3126f2456d440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Advaita=20K=E1=B9=9B=E1=B9=A3=E1=B9=87a=20D=C4=81sa?= Date: Fri, 24 Feb 2023 17:13:22 +0100 Subject: [PATCH] Add audio to "Add verse" dialog Fixes #167 --- .gitignore | 3 +- docker-compose.e2e.yml | 10 + ios/App/Podfile | 2 + package-lock.json | 45 ++- package.json | 4 +- src/app/Env.ts | 7 +- src/app/library/components/AddVerseDialog.vue | 11 + src/app/library/components/VersePlayer.vue | 69 ++++ src/app/library/models/LibraryVerse.ts | 4 + src/init/app/initStaticData.ts | 1 + src/services/DownloadService.ts | 56 ++++ src/verses.en.json | 315 ++++++++++++------ src/verses.ru.json | 315 ++++++++++++------ 13 files changed, 622 insertions(+), 220 deletions(-) create mode 100644 src/app/library/components/VersePlayer.vue create mode 100644 src/services/DownloadService.ts diff --git a/.gitignore b/.gitignore index d065f53d..81174e16 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ test-results/ coverage/ .idea .DS_Store -resources/ios/**/* \ No newline at end of file +resources/ios/**/* +content/ \ No newline at end of file diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml index e4bdca90..82b16b40 100644 --- a/docker-compose.e2e.yml +++ b/docker-compose.e2e.yml @@ -38,8 +38,18 @@ services: expose: - 80 + content: + image: ghcr.io/akdasa-studios/shlokas-landing:latest + # image: shlokas-content-content:latest + restart: always + expose: + - 80 + volumes: + - ./content:/usr/share/nginx/html + balancer: image: ghcr.io/akdasa-studios/shlokas-balancer:latest + # image: shlokas-balancer-balancer:latest ports: - 80:80 - 443:443 diff --git a/ios/App/Podfile b/ios/App/Podfile index e298cd3c..5b8356b9 100644 --- a/ios/App/Podfile +++ b/ios/App/Podfile @@ -13,12 +13,14 @@ def capacitor_pods pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app' pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device' + pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem' pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics' pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard' pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen' pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' pod 'CapawesomeCapacitorBackgroundTask', :path => '../../node_modules/@capawesome/capacitor-background-task' pod 'SentryCapacitor', :path => '../../node_modules/@sentry/capacitor' + pod 'CapacitorBlobWriter', :path => '../../node_modules/capacitor-blob-writer' pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins' end diff --git a/package-lock.json b/package-lock.json index da6a9f29..1ce12a2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,12 @@ "name": "@akdasa-studios/shlokas", "version": "1.1.0", "dependencies": { - "@akdasa-studios/shlokas-core": "1.0.10", + "@akdasa-studios/shlokas-core": "1.0.11", "@capacitor/app": "^4.1.1", "@capacitor/assets": "^2.0.4", "@capacitor/core": "4.6.3", "@capacitor/device": "^4.1.0", + "@capacitor/filesystem": "^4.1.4", "@capacitor/haptics": "4.1.0", "@capacitor/ios": "4.6.3", "@capacitor/keyboard": "4.1.1", @@ -26,6 +27,7 @@ "@sentry/capacitor": "^0.11.0", "@sentry/vue": "7.25.0", "@vueuse/core": "^9.13.0", + "capacitor-blob-writer": "^1.1.9", "cordova-sqlite-storage": "^6.1.0", "core-js": "^3.28.0", "eventemitter2": "^6.4.9", @@ -117,9 +119,9 @@ } }, "node_modules/@akdasa-studios/shlokas-core": { - "version": "1.0.10", - "resolved": "https://npm.pkg.github.com/download/@akdasa-studios/shlokas-core/1.0.10/9c777d20e60d2beb5f1b920a81f939749c535ed0", - "integrity": "sha512-IYfeyyH+L1jvqok7+rFK0tm7QQkM3AUwevkdDnDdJAUfm+ayvDpVgvuNvhdSHct9Ph6bSyvKjszB1oTan6FW1w==", + "version": "1.0.11", + "resolved": "https://npm.pkg.github.com/download/@akdasa-studios/shlokas-core/1.0.11/ec17b7a396216ad44d760f205d0759ccca2f9294", + "integrity": "sha512-XJJmHesj3/eNW+BtQ5EF1QFB8XA1iLdRm2XqssrXt3FHXFzBjl5W1zcS93fDLZ6Q19yw5jIzdI4CqeNwzitcvw==", "license": "ISC", "dependencies": { "@akdasa-studios/framework": "0.2.9", @@ -2285,6 +2287,14 @@ "@capacitor/core": "^4.0.0" } }, + "node_modules/@capacitor/filesystem": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-4.1.4.tgz", + "integrity": "sha512-ivko1RNK4hq63xhMacq8D6D97N5/SAafTsrmY/pghYrG6Cl2SEY0+IgRu7V9/VWeN3FSplyUPucjUTAFQxXN5g==", + "peerDependencies": { + "@capacitor/core": "^4.0.0" + } + }, "node_modules/@capacitor/haptics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.1.0.tgz", @@ -11002,6 +11012,15 @@ } ] }, + "node_modules/capacitor-blob-writer": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/capacitor-blob-writer/-/capacitor-blob-writer-1.1.9.tgz", + "integrity": "sha512-+bsBgotCMfQzT0k+vZHKGCMC3TvFL80n3zFRZfcI4EVG6kOsuEv5ZGu1rKcIDUJSLLJZdMjMAhbGs1uy5fpJBQ==", + "peerDependencies": { + "@capacitor/core": ">=3.0.0", + "@capacitor/filesystem": ">=1.0.0" + } + }, "node_modules/capacitor-resources": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/capacitor-resources/-/capacitor-resources-2.0.5.tgz", @@ -30751,9 +30770,9 @@ } }, "@akdasa-studios/shlokas-core": { - "version": "1.0.10", - "resolved": "https://npm.pkg.github.com/download/@akdasa-studios/shlokas-core/1.0.10/9c777d20e60d2beb5f1b920a81f939749c535ed0", - "integrity": "sha512-IYfeyyH+L1jvqok7+rFK0tm7QQkM3AUwevkdDnDdJAUfm+ayvDpVgvuNvhdSHct9Ph6bSyvKjszB1oTan6FW1w==", + "version": "1.0.11", + "resolved": "https://npm.pkg.github.com/download/@akdasa-studios/shlokas-core/1.0.11/ec17b7a396216ad44d760f205d0759ccca2f9294", + "integrity": "sha512-XJJmHesj3/eNW+BtQ5EF1QFB8XA1iLdRm2XqssrXt3FHXFzBjl5W1zcS93fDLZ6Q19yw5jIzdI4CqeNwzitcvw==", "requires": { "@akdasa-studios/framework": "0.2.9", "@akdasa-studios/framework-sync": "0.0.3", @@ -32280,6 +32299,12 @@ "integrity": "sha512-BlcYb6e6m+vC1SxeyUDIUGfuNXdKEcpFPDCs/kxk2SByFc/BkvXeoy4NjY4qmTderGELofX9bta5Iy9JV7rGUg==", "requires": {} }, + "@capacitor/filesystem": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-4.1.4.tgz", + "integrity": "sha512-ivko1RNK4hq63xhMacq8D6D97N5/SAafTsrmY/pghYrG6Cl2SEY0+IgRu7V9/VWeN3FSplyUPucjUTAFQxXN5g==", + "requires": {} + }, "@capacitor/haptics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.1.0.tgz", @@ -39049,6 +39074,12 @@ "integrity": "sha512-06wzzdAkCPZO+Qm4e/eNghZBDfVNDsCgw33T27OwBH9unE9S478OYw//Q2L7Npf/zBzs7rjZOszIFQkwQKAEqA==", "dev": true }, + "capacitor-blob-writer": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/capacitor-blob-writer/-/capacitor-blob-writer-1.1.9.tgz", + "integrity": "sha512-+bsBgotCMfQzT0k+vZHKGCMC3TvFL80n3zFRZfcI4EVG6kOsuEv5ZGu1rKcIDUJSLLJZdMjMAhbGs1uy5fpJBQ==", + "requires": {} + }, "capacitor-resources": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/capacitor-resources/-/capacitor-resources-2.0.5.tgz", diff --git a/package.json b/package.json index cb7d896a..6dbe1137 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,12 @@ "gen:resources": "npx capacitor-assets generate --assetPath 'resources' --ios" }, "dependencies": { - "@akdasa-studios/shlokas-core": "1.0.10", + "@akdasa-studios/shlokas-core": "1.0.11", "@capacitor/app": "^4.1.1", "@capacitor/assets": "^2.0.4", "@capacitor/core": "4.6.3", "@capacitor/device": "^4.1.0", + "@capacitor/filesystem": "^4.1.4", "@capacitor/haptics": "4.1.0", "@capacitor/ios": "4.6.3", "@capacitor/keyboard": "4.1.1", @@ -31,6 +32,7 @@ "@sentry/capacitor": "^0.11.0", "@sentry/vue": "7.25.0", "@vueuse/core": "^9.13.0", + "capacitor-blob-writer": "^1.1.9", "cordova-sqlite-storage": "^6.1.0", "core-js": "^3.28.0", "eventemitter2": "^6.4.9", diff --git a/src/app/Env.ts b/src/app/Env.ts index 60cb0b03..0da37d80 100644 --- a/src/app/Env.ts +++ b/src/app/Env.ts @@ -1,2 +1,7 @@ +export const PROTOCOL = process.env.NODE_ENV === 'development' ? 'http' : 'https' export const HOST = process.env.NODE_ENV === 'development' ? 'localhost' : 'shlokas.app' -export const AUTH_HOST = process.env.NODE_ENV === 'development' ? `http://${HOST}/auth` : `https://${HOST}/auth` \ No newline at end of file +export const AUTH_HOST = process.env.NODE_ENV === 'development' ? `http://${HOST}/auth` : `https://${HOST}/auth` + +export function getContentUrl(fileName: string): string { + return `${PROTOCOL}://${HOST}/content/${fileName}` +} \ No newline at end of file diff --git a/src/app/library/components/AddVerseDialog.vue b/src/app/library/components/AddVerseDialog.vue index 6def7cbb..51f1e51c 100644 --- a/src/app/library/components/AddVerseDialog.vue +++ b/src/app/library/components/AddVerseDialog.vue @@ -36,6 +36,12 @@ class="verse" /> + +
\ No newline at end of file diff --git a/src/app/library/components/VersePlayer.vue b/src/app/library/components/VersePlayer.vue new file mode 100644 index 00000000..681b5fae --- /dev/null +++ b/src/app/library/components/VersePlayer.vue @@ -0,0 +1,69 @@ + + + + + + \ No newline at end of file diff --git a/src/app/library/models/LibraryVerse.ts b/src/app/library/models/LibraryVerse.ts index 5e74a50b..213db71d 100644 --- a/src/app/library/models/LibraryVerse.ts +++ b/src/app/library/models/LibraryVerse.ts @@ -2,6 +2,7 @@ import { Decks, Verse, VerseStatus } from '@akdasa-studios/shlokas-core' import { computed, Ref } from 'vue' +import { getContentUrl } from '@/app/Env' /** * Library verse view model @@ -18,6 +19,9 @@ export class LibraryVerse { get translation() { return this._verse.translation.text } get text() { return this._verse.text.lines } get synonyms() { return this._verse.synonyms } + get textAudioUri() { return this._verse.textAudioUri + ? getContentUrl(this._verse.textAudioUri) + : undefined } isAlreadyAdded = computed(() => this._status.value.inDeck !== Decks.None) showStatus = computed(() => this._status.value.inDeck !== Decks.None) diff --git a/src/init/app/initStaticData.ts b/src/init/app/initStaticData.ts index 213490a4..18758e35 100644 --- a/src/init/app/initStaticData.ts +++ b/src/init/app/initStaticData.ts @@ -23,6 +23,7 @@ function loadVerses( .withNumber(new VerseNumber(verse.number)) .withText(new Text(verse.text)) .withTranslation(new Translation(verse.translation)) + .withTextAudioUri(verse.textAudioUri) for (const w of verse.synonyms) { builder.withSynonym(w.words.join(' '), w.translation) diff --git a/src/services/DownloadService.ts b/src/services/DownloadService.ts new file mode 100644 index 00000000..dde63795 --- /dev/null +++ b/src/services/DownloadService.ts @@ -0,0 +1,56 @@ +import { Capacitor } from '@capacitor/core' +import { Directory, Filesystem } from '@capacitor/filesystem' +import write_blob from 'capacitor-blob-writer' + +export class DownloadService { + /** + * Download a file from a URL and return device-specific URI + * what can be used to play the file with