From 9f0068233dd773189a78f45a24190a758901d150 Mon Sep 17 00:00:00 2001 From: Emma Date: Sat, 6 Apr 2024 13:13:07 -0400 Subject: [PATCH 1/9] Fix issue with light mode navigation bar appearing when user switches to dark mode from system light --- android/app/src/main/res/values-v23/themes.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/res/values-v23/themes.xml b/android/app/src/main/res/values-v23/themes.xml index d4b2a34101713..8934e3b5c5877 100644 --- a/android/app/src/main/res/values-v23/themes.xml +++ b/android/app/src/main/res/values-v23/themes.xml @@ -2,8 +2,8 @@ - \ No newline at end of file + From 0f2d3f3675b6cb67785b53c34374dc649ceea922 Mon Sep 17 00:00:00 2001 From: Emma Date: Sat, 6 Apr 2024 13:58:22 -0400 Subject: [PATCH 2/9] Add ability to change icon colour based on the environment targeted --- .github/workflows/buildCordova.yml | 5 ++ _scripts/_setAppSplashTheme.mjs | 69 +++++++++++++++++++ .../src/main/res/values-night-v31/themes.xml | 11 +++ .../app/src/main/res/values-v31/themes.xml | 10 +++ 4 files changed, 95 insertions(+) create mode 100644 _scripts/_setAppSplashTheme.mjs create mode 100644 android/app/src/main/res/values-night-v31/themes.xml create mode 100644 android/app/src/main/res/values-v31/themes.xml diff --git a/.github/workflows/buildCordova.yml b/.github/workflows/buildCordova.yml index 32ad70a0b8e41..707a060f5e77a 100644 --- a/.github/workflows/buildCordova.yml +++ b/.github/workflows/buildCordova.yml @@ -22,6 +22,11 @@ jobs: - name: 🧢 Yarn install run: yarn ci + - name: Set environment icon & splash for android app + run: | + # to make it easier to tell which is which when multiple are installed + node ./_scripts/_setAppSplashTheme.mjs --nightly + - name: πŸ”Lint code run: yarn lint diff --git a/_scripts/_setAppSplashTheme.mjs b/_scripts/_setAppSplashTheme.mjs new file mode 100644 index 0000000000000..43a487c819a91 --- /dev/null +++ b/_scripts/_setAppSplashTheme.mjs @@ -0,0 +1,69 @@ + +import { readFile, writeFile } from 'fs/promises' +import { join } from 'path' +import { fileURLToPath } from 'url' + + +// sets the splashscreen & icon to one of three predefined themes (this makes it easier to tell, at a glance, which one is open) +// - release (the default production look) +// - nightly +// OR +// - development + +const COLOURS = { + RELEASE: { + primary: '#f04242', + secondary: '#14a4df', + back: '#E4E4E4', + backDark: '#212121' + }, + // catppucin mocha theme colours + NIGHTLY: { + primary: '#cdd6f4', + secondary: '#cdd6f4', + back: '#1e1e2e', + backDark: '#1e1e2e' + }, + // inverted release colours + DEVELOPMENT: { + primary: '#E4E4E4', + secondary: '#E4E4E4', + back: '#f04242', + backDark: '#f04242' + } +} +let colour = 'RELEASE' +for (const key in COLOURS) { + if (process.argv.indexOf(`--${key.toLowerCase()}`) !== -1) { + colour = key + } +} + +const currentTheme = COLOURS[colour] + +const scriptDir = fileURLToPath(import.meta.url) +const drawablePath = join(scriptDir, '../../android/app/src/main/res/drawable/') + +const foreground = join(drawablePath, 'ic_launcher_foreground.xml') +let foregroundXML = (await readFile(foreground)).toString() +foregroundXML = foregroundXML.replace(//g, `android:fillColor="${currentTheme.back}" />`) +await writeFile(background, backgroundXML) + +const lightTheme = join(scriptDir, '..', '..', 'android/app/src/main/res/values-v31/themes.xml') +let lightThemeXml = (await readFile(lightTheme)).toString() +lightThemeXml = lightThemeXml.replace(/[^"]*?<\/item>/g, `${currentTheme.back}`) +lightThemeXml = lightThemeXml.replace(/[^"]*?<\/item>/g, `${currentTheme.back}`) +await writeFile(lightTheme, lightThemeXml) + +const darkTheme = join(scriptDir, '..', '..', 'android/app/src/main/res/values-night-v31/themes.xml') +let darkThemeXml = (await readFile(darkTheme)).toString() +darkThemeXml = darkThemeXml.replace(/[^"]*?<\/item>/g, `${currentTheme.backDark}`) +darkThemeXml = darkThemeXml.replace(/[^"]*?<\/item>/g, `${currentTheme.backDark}`) +await writeFile(darkTheme, darkThemeXml) diff --git a/android/app/src/main/res/values-night-v31/themes.xml b/android/app/src/main/res/values-night-v31/themes.xml new file mode 100644 index 0000000000000..b26199a98ad73 --- /dev/null +++ b/android/app/src/main/res/values-night-v31/themes.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/android/app/src/main/res/values-v31/themes.xml b/android/app/src/main/res/values-v31/themes.xml new file mode 100644 index 0000000000000..f1e53118c1e0d --- /dev/null +++ b/android/app/src/main/res/values-v31/themes.xml @@ -0,0 +1,10 @@ + + + + + From 4d82e526d34429e0018a752a0215f4b1743344d2 Mon Sep 17 00:00:00 2001 From: Emma Date: Sat, 6 Apr 2024 16:01:48 -0400 Subject: [PATCH 3/9] Make FreeTube icon background match dark mode splashscreen --- android/app/src/main/res/values-night-v31/themes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/src/main/res/values-night-v31/themes.xml b/android/app/src/main/res/values-night-v31/themes.xml index b26199a98ad73..dcc81e49e5eb5 100644 --- a/android/app/src/main/res/values-night-v31/themes.xml +++ b/android/app/src/main/res/values-night-v31/themes.xml @@ -6,6 +6,6 @@ #212121 #212121 - + @drawable/ic_launcher_foreground From 5b79688b3e660f617b1ddc9c79eb83e77b284779 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 8 Apr 2024 12:42:29 -0400 Subject: [PATCH 4/9] Update README to reflect name change This also includes some content changes to reflect the current status of features and functionality. --- README.md | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index dc1fb0a679539..695a894a33f74 100644 --- a/README.md +++ b/README.md @@ -21,21 +21,24 @@ An open source YouTube player built with privacy in mind.

WebsiteBlogDocumentationFAQDiscussions


-FreeTube Cordova is an open source YouTube player built with privacy in mind. Use YouTube without advertisements and prevent Google from tracking you with their cookies and JavaScript. -Available for Android and as a PWA. FreeTube Cordova is a fork of [FreeTube](https://www.github.com/FreeTubeApp). -FreeTube Cordova is currently in Beta. While it should work well for most users, there are still bugs and missing features that need to be addressed. +FreeTube Android is an open source YouTube player built with privacy in mind. Use YouTube without advertisements and prevent Google from tracking you with their cookies and JavaScript. +Available as an APK and as a PWA (progressive web app). FreeTube Android is a fork of [FreeTube](https://www.github.com/FreeTubeApp). + +> [!NOTE] +> FreeTube Android is currently in Beta. While it should work well for most users, there are still bugs and missing features that need to be addressed. +

Get it on IzzyOnDroid

-

Download FreeTubeCordova

+

Download FreeTube Android


## How does it work? -FreeTube Cordova uses the [Invidious API](https://github.com/iv-org/invidious) to serve data and videos. No official YouTube APIs are used to obtain data. Your subscriptions and history are stored locally on your device and are never sent out. +The APK uses a built in extractor to grab and serve data / videos, and can optionally use the [Invidious API](https://github.com/iv-org/invidious). The PWA *only* uses the [Invidious API](https://github.com/iv-org/invidious). No official YouTube APIs are used to obtain data. Your subscriptions and history are stored locally on your device and are never sent out. ## Features * Watch videos without ads @@ -50,8 +53,6 @@ FreeTube Cordova uses the [Invidious API](https://github.com/iv-org/invidious) t * Most popular videos page based on the set Invidious instance * SponsorBlock * Full Theme support -* Multiple windows -* Mini Player (Picture-in-Picture) * Keyboard shortcuts * Option to show only family friendly content * Show/hide functionality or elements within the app using the distraction free settings @@ -61,15 +62,6 @@ Go to [FreeTube's Documentation](https://docs.freetubeapp.io/) if you'd like to ## Screenshots watching video trending videos subscription feed -## How to install - -There is a deployed PWA (progressive web app) available here: - -[https://marmadilemanteater.github.io/freetube/#/](https://marmadilemanteater.github.io/freetube/#/) - -There is an APK which can be downloaded here: - -[https://github.com/MarmadileManteater/FreeTubeCordova/releases](https://github.com/MarmadileManteater/FreeTubeCordova/releases) ### Automated Builds (Nightly / Weekly) Builds are automatically created from changes to our development branch via [GitHub Actions](https://github.com/MarmadileManteater/FreeTubeCordova/actions/workflows/buildCordova.yml). @@ -77,14 +69,16 @@ Builds are automatically created from changes to our development branch via [Git The first build with a green check mark is the latest build. You will need to have a GitHub account to download these builds. ## How to build and test -### Commands for the Android APK +### Commands for the APK ```bash # πŸ“¦ Packs the project using `webpack.android.config.js` yarn pack:android # 🚧 for development yarn pack:android:dev ``` -### Commands for the PWA (progressive web app) +> [!NOTE] +> These commands only build the assets necessary for the project located in `android/` to be built. In order to obtain a complete build, you will need to build the project located in `android/` with `gradle`. +### Commands for the PWA ```bash # πŸ› Debugs the project using `webpack.web.config.js` yarn dev:web @@ -126,13 +120,13 @@ before sending your pull request. Translation status -If you'd like to localize FreeTubeCordova, please send submissions to [FreeTube's weblate](https://hosted.weblate.org/engage/free-tube/). +If you'd like to localize FreeTube Android, please send submissions to [FreeTube's weblate](https://hosted.weblate.org/engage/free-tube/). ## Contact If you ever have any questions, feel free to make an issue here on GitHub. ## Upstream Donations -If you enjoy using FreeTubeCordova, you're welcome to leave a donation using the following methods to support upstream development and maintenance. +If you enjoy using FreeTube Android, you're welcome to leave a donation using the following methods to support upstream development and maintenance. * [FreeTube on Liberapay](https://liberapay.com/FreeTube) From bae3380ac32f56f4e415559b85ae5e318002f8f7 Mon Sep 17 00:00:00 2001 From: Emma Date: Mon, 8 Apr 2024 12:53:51 -0400 Subject: [PATCH 5/9] Remove some leftover dead cordova specific code --- _scripts/CordovaPlugin.js | 50 ---------------- _scripts/cordova-build.js | 60 ------------------- .../{releaseCordova.js => releaseAndroid.js} | 0 .../cordova-settings/cordova-settings.js | 26 -------- .../cordova-settings/cordova-settings.vue | 24 -------- 5 files changed, 160 deletions(-) delete mode 100644 _scripts/CordovaPlugin.js delete mode 100644 _scripts/cordova-build.js rename _scripts/{releaseCordova.js => releaseAndroid.js} (100%) delete mode 100644 src/renderer/components/cordova-settings/cordova-settings.js delete mode 100644 src/renderer/components/cordova-settings/cordova-settings.vue diff --git a/_scripts/CordovaPlugin.js b/_scripts/CordovaPlugin.js deleted file mode 100644 index e03014ae30f28..0000000000000 --- a/_scripts/CordovaPlugin.js +++ /dev/null @@ -1,50 +0,0 @@ - -// #region Imports -const { mkdir, writeFile, readFile } = require('fs/promises') -const fse = require('fs-extra') -const path = require('path') -const util = require('util') -const copy = util.promisify(fse.cp) -const exists = fse.existsSync -const { execWithLiveOutput } = require('./helpers') -// #endregion - -class CordovaPlugin { - apply(compiler) { - compiler.hooks.afterDone.tap('CordovaPlugin', async (afterDone) => { - const wwwRoot = afterDone.compilation.options.output.path - const outputDirectory = path.join(wwwRoot, '..') - const configXML = await require('../src/cordova/config.xml.js') - const packageJSON = require('../src/cordova/package') - - if (!exists(path.join(outputDirectory, 'node_modules'))) { - await writeFile(path.join(outputDirectory, 'package.json'), JSON.stringify(packageJSON, null, 2)) - await writeFile(path.join(outputDirectory, 'config.xml'), configXML.string) - // Copy the icons into the cordova directory - await mkdir(path.join(outputDirectory, 'res')) - await mkdir(path.join(outputDirectory, 'res', 'icon')) - await copy(path.join(__dirname, '..', '_icons', '.icon-set'), path.join(outputDirectory, 'res', 'icon', 'android'), { recursive: true, force: true }) - await copy(path.join(__dirname, '..', '_icons', 'icon.svg'), path.join(outputDirectory, 'res', 'icon', 'android', 'background.xml')) - // These next commands require the environment to be development - const environment = process.env.NODE_ENV - process.env.NODE_ENV = 'development' - // Install all of the cordova plugins - await execWithLiveOutput(`cd ${outputDirectory} && yarn install`) - // Restore the platform specific data - await execWithLiveOutput(`cd ${outputDirectory} && yarn restore`) - const manifestXML = path.join(outputDirectory, 'platforms/android/app/src/main/AndroidManifest.xml') - const manifestString = (await readFile(manifestXML)).toString() - .replaceAll('', '') - .replaceAll('', '') - await writeFile(manifestXML, manifestString) - - process.env.NODE_ENV = environment - } else { - await copy(path.join(__dirname, '..', '_icons', '.icon-set'), path.join(outputDirectory, 'res', 'icon', 'android'), { recursive: true, force: true }) - await copy(path.join(__dirname, '..', '_icons', 'icon.svg'), path.join(outputDirectory, 'res', 'icon', 'android', 'background.xml')) - } - }) - } -} - -module.exports = CordovaPlugin diff --git a/_scripts/cordova-build.js b/_scripts/cordova-build.js deleted file mode 100644 index 042cae9ae91f5..0000000000000 --- a/_scripts/cordova-build.js +++ /dev/null @@ -1,60 +0,0 @@ -const { writeFile, copyFile, stat } = require('fs/promises') -const { move } = require('fs-extra') -const path = require('path') -const pkg = require('../package.json') -const exec = require('./helpers').execWithLiveOutput -;(async () => { - const log = (message, level = 'INFO') => { - // πŸ€·β€β™€οΈ idk if there is a better way to implement logging here - // eslint-disable-next-line - console.log(`(${new Date().toISOString()})[${level}]: ${message}`) - } - const distDirectory = 'dist/cordova' - try { - await stat(distDirectory) - } catch { - log(`The dist directory \`${distDirectory}\` cannot be found. This build *will* fail. \`pack:cordova\` did not complete.`, 'WARN') - } - let apkName = `${pkg.name}-${pkg.version}.apk` - let keystorePath = null - let keystorePassphrase = null - let release = false - const args = Array.from(process.argv) - if (args.indexOf('--release') !== -1) { - release = true - args.splice(args.indexOf('--release'), 1) - } - if (args.length > 2) { - apkName = args[2] - } - if (args.length > 3) { - keystorePath = args[3] - } - if (args.length > 4) { - keystorePassphrase = args[4] - } - - let buildArguments = '' - if (keystorePassphrase !== null) { - // the apk needs to be signed - buildArguments = `--stacktrace --buildConfig --warning-mode-all ${release ? '--release' : ''}` - await move(keystorePath, path.join(distDirectory, 'freetubecordova.keystore')) - const buildJSON = { - android: {} - } - buildJSON.android[release ? 'release' : 'debug'] = { - keystore: './freetubecordova.keystore', - storePassword: keystorePassphrase, - alias: 'freetubecordova', - password: keystorePassphrase, - keystoreType: 'jks' - } - await writeFile(path.join(distDirectory, 'build.json'), JSON.stringify(buildJSON, null, 4)) - } - // πŸƒβ€β™€οΈ Run the apk build - log(`Building apk file for ${release ? 'release' : 'development'}`) - await exec(`cd ${distDirectory} && npx cordova build android ${buildArguments}`) - // πŸ“‹ Copy the apk to the build dir - log('Copying apk file to build directory') - await copyFile(path.join(distDirectory, 'platforms/android/app/build/outputs/apk/debug/app-debug.apk'), path.join(distDirectory, '..', apkName)) -})() diff --git a/_scripts/releaseCordova.js b/_scripts/releaseAndroid.js similarity index 100% rename from _scripts/releaseCordova.js rename to _scripts/releaseAndroid.js diff --git a/src/renderer/components/cordova-settings/cordova-settings.js b/src/renderer/components/cordova-settings/cordova-settings.js deleted file mode 100644 index c664727bc6f5f..0000000000000 --- a/src/renderer/components/cordova-settings/cordova-settings.js +++ /dev/null @@ -1,26 +0,0 @@ -import { defineComponent } from 'vue' -import { mapActions } from 'vuex' -import FtSettingsSection from '../ft-settings-section/ft-settings-section.vue' -import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue' - -export default defineComponent({ - name: 'CordovaSettings', - components: { - 'ft-settings-section': FtSettingsSection, - 'ft-toggle-switch': FtToggleSwitch - }, - computed: { - getDisableBackgroundModeNotification: function () { - return this.$store.getters.getDisableBackgroundModeNotification - }, - getShowThumbnailInMediaControls: function () { - return this.$store.getters.getShowThumbnailInMediaControls - } - }, - methods: { - ...mapActions([ - 'updateDisableBackgroundModeNotification', - 'updateShowThumbnailInMediaControls' - ]) - } -}) diff --git a/src/renderer/components/cordova-settings/cordova-settings.vue b/src/renderer/components/cordova-settings/cordova-settings.vue deleted file mode 100644 index 1664ec0552f04..0000000000000 --- a/src/renderer/components/cordova-settings/cordova-settings.vue +++ /dev/null @@ -1,24 +0,0 @@ - - -