diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index f53ef97..abc2d0d 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -12,6 +12,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: 'recursive' - name: Set up JDK 17 uses: actions/setup-java@v4 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cccd131 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "app/src/main/assets/ifv"] + path = app/src/main/assets/ifv + url = https://github.com/banocean/ifv diff --git a/app/build.gradle b/app/build.gradle index 06bedb6..28c2007 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,6 +48,7 @@ dependencies { implementation libs.androidx.material3 implementation libs.androidx.coordinatorlayout implementation libs.material + implementation libs.androidx.browser testImplementation libs.junit androidTestImplementation libs.androidx.junit androidTestImplementation libs.androidx.espresso.core diff --git a/app/src/main/assets/autoLogin/efeb.js b/app/src/main/assets/autoLogin/efeb.js index 382279d..3348294 100644 --- a/app/src/main/assets/autoLogin/efeb.js +++ b/app/src/main/assets/autoLogin/efeb.js @@ -7,8 +7,8 @@ function fillLoginForm() { const triedLoggingIn = sessionStorage.getItem('triedLoggingIn'); browser.storage.local.get().then((result) => { - const login = result.Login; - const haslo = result.Haslo; + const login = result?.Login; + const haslo = result?.Haslo; if (login !== undefined && haslo !== undefined && triedLoggingIn === null) { loginField.value = login; diff --git a/app/src/main/assets/autoLogin/loader.css b/app/src/main/assets/autoLogin/loader.css deleted file mode 100644 index 4186197..0000000 --- a/app/src/main/assets/autoLogin/loader.css +++ /dev/null @@ -1,37 +0,0 @@ -.loader { - width: 45px; - aspect-ratio: 1; - --c: no-repeat linear-gradient(#ca2c2a 0 0); - background: var(--c) 0% 50%, var(--c) 50% 50%, var(--c) 100% 50%; - background-size: 20% 100%; - animation: l1 1s infinite linear; -} -.loader-holder { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - background: rgba(0, 0, 0, 0.7); - z-index: 9999; -} -@keyframes l1 { - 0% { - background-size: 20% 100%, 20% 100%, 20% 100%; - } - 33% { - background-size: 20% 10%, 20% 100%, 20% 100%; - } - 50% { - background-size: 20% 100%, 20% 10%, 20% 100%; - } - 66% { - background-size: 20% 100%, 20% 100%, 20% 10%; - } - 100% { - background-size: 20% 100%, 20% 100%, 20% 100%; - } -} diff --git a/app/src/main/assets/autoLogin/loading.js b/app/src/main/assets/autoLogin/loading.js index 37c25e0..b047641 100644 --- a/app/src/main/assets/autoLogin/loading.js +++ b/app/src/main/assets/autoLogin/loading.js @@ -1,11 +1,57 @@ -const loaderHolder = document.createElement('div'); -loaderHolder.className = 'loader-holder'; -document.body.appendChild(loaderHolder); +showLoader(); -const loader = document.createElement('div'); -loader.className = 'loader'; -loaderHolder.appendChild(loader); +function showLoader() { + const style = document.createElement('style'); + style.textContent = ` + .loader { + width: 45px; + aspect-ratio: 1; + --c: no-repeat linear-gradient(#ca2c2a 0 0); + background: var(--c) 0% 50%, var(--c) 50% 50%, var(--c) 100% 50%; + background-size: 20% 100%; + animation: l1 1s infinite linear; + } + .loader-holder { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background: rgba(0, 0, 0, 0.7); + z-index: 9999; + } + @keyframes l1 { + 0% { + background-size: 20% 100%, 20% 100%, 20% 100%; + } + 33% { + background-size: 20% 10%, 20% 100%, 20% 100%; + } + 50% { + background-size: 20% 100%, 20% 10%, 20% 100%; + } + 66% { + background-size: 20% 100%, 20% 100%, 20% 10%; + } + 100% { + background-size: 20% 100%, 20% 100%, 20% 100%; + } + } +`; + (document.head || document.documentElement).appendChild(style); -addEventListener('load', () => { - document.body.removeChild(loaderHolder); -}) \ No newline at end of file + const loaderHolder = document.createElement('div'); + loaderHolder.className = 'loader-holder'; + const loader = document.createElement('div'); + loader.className = 'loader'; + loaderHolder.appendChild(loader); + + (document.body || document.documentElement).appendChild(loaderHolder); + + window.addEventListener('load', () => { + loaderHolder.remove(); + }); +} \ No newline at end of file diff --git a/app/src/main/assets/autoLogin/manifest.json b/app/src/main/assets/autoLogin/manifest.json index c77d8f1..dc72c1f 100644 --- a/app/src/main/assets/autoLogin/manifest.json +++ b/app/src/main/assets/autoLogin/manifest.json @@ -21,25 +21,23 @@ "content_scripts": [ { "js": ["loading.js"], - "css": ["loader.css"], "matches": [ "*://eduvulcan.pl/logowanie", "*://eduvulcan.pl/", - "*://dziennik-uczen.vulcan.net.pl/*/LoginEndpoint.aspx" + "*://dziennik-logowanie.vulcan.net.pl/*/Account/Logon*" ], - "run_at": "document_end" + "run_at": "document_start" }, { "js": ["prometeusz.js"], - "matches": [ - "*://eduvulcan.pl/logowanie", - "*://eduvulcan.pl/" - ], + "matches": ["*://eduvulcan.pl/logowanie", "*://eduvulcan.pl/"], "run_at": "document_end" }, { "js": ["efeb.js"], - "matches": ["*://dziennik-uczen.vulcan.net.pl/*/LoginEndpoint.aspx"], + "matches": [ + "*://dziennik-logowanie.vulcan.net.pl/*/Account/Logon*" + ], "run_at": "document_end" }, { @@ -47,7 +45,8 @@ "matches": [ "*://eduvulcan.pl/wylogowanie", "*://dziennik-uczen.vulcan.net.pl/*/nie-wiem-jaki-endpoint" - ] + ], + "run_at": "document_start" } ] } diff --git a/app/src/main/assets/autoLogin/prometeusz.js b/app/src/main/assets/autoLogin/prometeusz.js index de590ae..5723f0e 100644 --- a/app/src/main/assets/autoLogin/prometeusz.js +++ b/app/src/main/assets/autoLogin/prometeusz.js @@ -11,14 +11,14 @@ function fillLoginForm() { const triedLoggingIn = sessionStorage.getItem('triedLoggingIn'); browser.storage.local.get().then((result) => { - const alias = result.Alias; - const password = result.Password; + const alias = result?.Alias; + const password = result?.Password; if (alias !== undefined && password !== undefined && triedLoggingIn === null) { aliasField.value = alias; passwordField.value = password; loginButton.click(); - sessionStorage.setItem("triedLoggingIn", "1" ); + sessionStorage.setItem("triedLoggingIn", "1"); } else { if (triedLoggingIn === "1") { document.querySelectorAll('.message-error').forEach(e => { diff --git a/app/src/main/assets/ifv b/app/src/main/assets/ifv new file mode 160000 index 0000000..d0c3546 --- /dev/null +++ b/app/src/main/assets/ifv @@ -0,0 +1 @@ +Subproject commit d0c3546540ad42b9c1c67ff6fc094102bb5ba48d diff --git a/app/src/main/assets/ifv/LICENSE b/app/src/main/assets/ifv/LICENSE deleted file mode 100644 index 11b7226..0000000 --- a/app/src/main/assets/ifv/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 BanOcean - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/app/src/main/assets/ifv/apply.js b/app/src/main/assets/ifv/apply.js deleted file mode 100644 index a4b3c5a..0000000 --- a/app/src/main/assets/ifv/apply.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @typedef {Object} Patch - * @property {string} name - The name of the patch. - * @property {string} description - The description of the patch. - * @property {Object} files - The files to be injected. - * @property {string[]} [files.css] - An array of CSS file names (optional). - * @property {string[]} [files.js] - An array of JS file names (optional). - */ - -/** @returns {Promise} */ -const fetchPatches = async () => { - const patchesResponse = await fetch(chrome.runtime.getURL("patches.json")); - return await patchesResponse.json(); -}; - -const getConfig = async () => - (await chrome.storage.sync.get("options"))?.options ?? {}; - -chrome.storage.onChanged.addListener((changes, namespace) => { - if ( - !changes.options?.oldValue || - JSON.stringify(changes.options?.oldValue) === - JSON.stringify(changes.options?.newValue) - ) - return; - if (namespace !== "sync") return; - window.location.reload(); -}); - -const getPatchesFiles = (patches, config) => { - return [ - ...new Set( - patches - .flatMap((patch) => { - const result = []; - if (config[patch.name].enable) { - if (patch.files?.js?.length) - result.push( - patch.files.js.map((file) => `patches/${file}`), - ); - if ( - (!patch.allowedHostsCss || - patch.allowedHostsCss.includes( - window.location.hostname, - )) && - patch.files?.css?.length - ) { - result.push( - patch.files.css.map( - (file) => `patches/${file}`, - ), - ); - } - } - return result; - }) - .flat(), - ), - ]; -}; - -async function run() { - let config = await getConfig(); - const patches = await fetchPatches(); - - patches.forEach((patch) => { - if (config[patch.name] !== undefined) return; - config[patch.name] = { description: patch.description, enable: true }; - }); - - chrome.storage.sync.set({ options: config }); - - for (const filePath of getPatchesFiles(patches, config)) { - const element = document.createElement( - filePath.endsWith(".js") ? "script" : "link", - ); - element.setAttribute( - filePath.endsWith(".js") ? "src" : "href", - chrome.runtime.getURL(filePath), - ); - if (filePath.endsWith(".css")) - element.setAttribute("rel", "stylesheet"); - else { - element.setAttribute("type", "module"); - element.classList.add("injected-script"); - } - document.head.appendChild(element); - } -} - -run(); diff --git a/app/src/main/assets/ifv/assets/add to chrome.svg b/app/src/main/assets/ifv/assets/add to chrome.svg deleted file mode 100644 index 2d08902..0000000 --- a/app/src/main/assets/ifv/assets/add to chrome.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/assets/ifv/assets/add to firefox.svg b/app/src/main/assets/ifv/assets/add to firefox.svg deleted file mode 100644 index cb1c188..0000000 --- a/app/src/main/assets/ifv/assets/add to firefox.svg +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/assets/ifv/assets/discord.svg b/app/src/main/assets/ifv/assets/discord.svg deleted file mode 100644 index 7f9a31f..0000000 --- a/app/src/main/assets/ifv/assets/discord.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/github.svg b/app/src/main/assets/ifv/assets/github.svg deleted file mode 100644 index d5e6491..0000000 --- a/app/src/main/assets/ifv/assets/github.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/calendar_clock_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/calendar_clock_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 3db8225..0000000 --- a/app/src/main/assets/ifv/assets/icons/calendar_clock_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/chevron_left_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/chevron_left_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index cdd942c..0000000 --- a/app/src/main/assets/ifv/assets/icons/chevron_left_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/chevron_right_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/chevron_right_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 0603448..0000000 --- a/app/src/main/assets/ifv/assets/icons/chevron_right_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/counter_6_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/counter_6_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index d845664..0000000 --- a/app/src/main/assets/ifv/assets/icons/counter_6_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/dashboard_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/dashboard_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 16b7d0a..0000000 --- a/app/src/main/assets/ifv/assets/icons/dashboard_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/event_available_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/event_available_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 5363d44..0000000 --- a/app/src/main/assets/ifv/assets/icons/event_available_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/keyboard_backspace_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/keyboard_backspace_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index b4ef999..0000000 --- a/app/src/main/assets/ifv/assets/icons/keyboard_backspace_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/menu_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/menu_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 702a828..0000000 --- a/app/src/main/assets/ifv/assets/icons/menu_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/unfold_less_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/unfold_less_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index d9d41fe..0000000 --- a/app/src/main/assets/ifv/assets/icons/unfold_less_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/icons/unfold_more_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/app/src/main/assets/ifv/assets/icons/unfold_more_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index 8abaf5e..0000000 --- a/app/src/main/assets/ifv/assets/icons/unfold_more_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/assets/ifv/assets/logo/logo-128-blue.png b/app/src/main/assets/ifv/assets/logo/logo-128-blue.png deleted file mode 100644 index f82c65e..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-128-blue.png and /dev/null differ diff --git a/app/src/main/assets/ifv/assets/logo/logo-128-red.png b/app/src/main/assets/ifv/assets/logo/logo-128-red.png deleted file mode 100644 index 6de072c..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-128-red.png and /dev/null differ diff --git a/app/src/main/assets/ifv/assets/logo/logo-192-blue.png b/app/src/main/assets/ifv/assets/logo/logo-192-blue.png deleted file mode 100644 index 8b15f6b..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-192-blue.png and /dev/null differ diff --git a/app/src/main/assets/ifv/assets/logo/logo-192-red.png b/app/src/main/assets/ifv/assets/logo/logo-192-red.png deleted file mode 100644 index ee39cc4..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-192-red.png and /dev/null differ diff --git a/app/src/main/assets/ifv/assets/logo/logo-512-blue.png b/app/src/main/assets/ifv/assets/logo/logo-512-blue.png deleted file mode 100644 index 00accc6..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-512-blue.png and /dev/null differ diff --git a/app/src/main/assets/ifv/assets/logo/logo-512-red.png b/app/src/main/assets/ifv/assets/logo/logo-512-red.png deleted file mode 100644 index 22389e1..0000000 Binary files a/app/src/main/assets/ifv/assets/logo/logo-512-red.png and /dev/null differ diff --git a/app/src/main/assets/ifv/execute.js b/app/src/main/assets/ifv/execute.js deleted file mode 100644 index f686481..0000000 --- a/app/src/main/assets/ifv/execute.js +++ /dev/null @@ -1,46 +0,0 @@ -const modules = []; -let loadedScripts = 0; - -const isEverythingLoaded = () => - document.querySelectorAll(".injected-script").length === loadedScripts; - -window.appendModule = (...args) => { - modules.push(...args); - loadedScripts++; - if (isEverythingLoaded()) execute(); -}; - -const execute = () => { - if (!modules.length) - console.warn( - "Script tried executing before all files loaded or all patches are disabled", - ); - - const isFirstRun = !window.iWasThere; // :) - window.iWasThere = true; - - for (const { onlyOnReloads, doesRunHere, isLoaded, run } of modules) { - if (onlyOnReloads && !isFirstRun) continue; - if (doesRunHere !== undefined && !doesRunHere()) continue; - - if (!isLoaded || isLoaded()) run(); - else { - const observer = new MutationObserver((mutationsList, observer) => { - if (!isLoaded()) return; - observer.disconnect(); - run(); - }); - observer.observe(document.body, { - subtree: true, - childList: true, - }); - } - } -}; - -window.history.pushState = new Proxy(window.history.pushState, { - apply: (target, a, args) => { - target.apply(a, args); - if (modules.length !== 0 && isEverythingLoaded()) execute(); - }, -}); diff --git a/app/src/main/assets/ifv/manifest.json b/app/src/main/assets/ifv/manifest.json deleted file mode 100644 index 413415b..0000000 --- a/app/src/main/assets/ifv/manifest.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "manifest_version": 3, - "description": "Poprawia uciążliwe elementy stron usług eduVULCAN oraz Dziennik Vulcan", - "version": "0.3", - "name": "Improvements for Vulcan", - - "permissions": ["storage"], - "host_permissions": [ - "*://dziennik-uczen.vulcan.net.pl/*", - "*://dziennik-wiadomosci.vulcan.net.pl/*", - "*://uczen.eduvulcan.pl/*", - "*://wiadomosci.eduvulcan.pl/*", - "*://dziennik-logowanie.vulcan.net.pl/*", - "*://eduvulcan.pl/*" - ], - - "browser_specific_settings": { - "gecko": { - "id": "j.skup.test@gmail.com", - "strict_min_version": "128.0" - } - }, - - "web_accessible_resources": [ - { - "resources": ["patches/*", "patches.json"], - "matches": [ - "*://dziennik-uczen.vulcan.net.pl/*", - "*://dziennik-wiadomosci.vulcan.net.pl/*", - "*://uczen.eduvulcan.pl/*", - "*://wiadomosci.eduvulcan.pl/*", - "*://dziennik-logowanie.vulcan.net.pl/*", - "*://eduvulcan.pl/*" - ] - } - ], - "content_scripts": [ - { - "js": ["execute.js"], - "matches": [ - "*://dziennik-uczen.vulcan.net.pl/*", - "*://dziennik-wiadomosci.vulcan.net.pl/*", - "*://uczen.eduvulcan.pl/*", - "*://wiadomosci.eduvulcan.pl/*", - "*://dziennik-logowanie.vulcan.net.pl/*", - "*://eduvulcan.pl/*" - ], - "world": "MAIN" - }, - { - "js": ["apply.js"], - "matches": [ - "*://dziennik-uczen.vulcan.net.pl/*", - "*://dziennik-wiadomosci.vulcan.net.pl/*", - "*://uczen.eduvulcan.pl/*", - "*://wiadomosci.eduvulcan.pl/*", - "*://dziennik-logowanie.vulcan.net.pl/*", - "*://eduvulcan.pl/*" - ] - } - ], - "action": { - "default_popup": "popup/index.html" - }, - - "icons": { - "128": "assets/logo/logo-128-red.png", - "192": "assets/logo/logo-192-red.png", - "512": "assets/logo/logo-512-red.png" - } -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches.json b/app/src/main/assets/ifv/patches.json deleted file mode 100644 index f075b2f..0000000 --- a/app/src/main/assets/ifv/patches.json +++ /dev/null @@ -1,182 +0,0 @@ -[ - { - "name": "Change close button icon", - "description": "Replaces close buttons with back buttons to indicate more accurately what action it corresponds to. (mobile only)", - "files": { - "css": ["arrows.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl", "wiadomosci.eduvulcan.pl", "dziennik-wiadomosci.vulcan.net.pl"] - }, - { - "name": "Move messages button", - "description": "Moves messages button to header. (mobile only)", - "files": { - "js": ["messagesButton.js"] - } - }, - { - "name": "Hide subjects with no grades", - "description": "Hides subjects without any grades.", - "files": { - "js": ["hideSubjectsWithNoGrades/finalGrades.js"], - "css": ["hideSubjectsWithNoGrades/normalGrades.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Hide empty exam results", - "description": "Hides exam results instead of showing no data. (mobile only)", - "files": { - "css": ["hideEmptyExamResults.css"] - } - }, - { - "name": "Hide footer", - "description": "Hides footer. (mobile only)", - "files": { - "css": ["hideFooter.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl", "wiadomosci.eduvulcan.pl", "dziennik-wiadomosci.vulcan.net.pl"] - }, - { - "name": "Hide WCAG", - "description": "Hide WCAG buttons.", - "files": { - "css": ["hideWCAG.css"] - } - }, - { - "name": "Align Detailed Grades Button", - "description": "Aligns detailed grades button with other buttons.", - "files": { - "css": ["alignDetailedGradesButton.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Hide Tutors From Board", - "description": "Hides tutors from board.", - "files": { - "css": ["hideTutorsFromBoard.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Display Full Name", - "description": "Shows the user's name under the nickname. (desktop only)", - - "files": { - "js": ["displayFullName.js"] - } - }, - { - "name": "Redirect To Board", - "description": "Redirects to board after login.", - "files": { - "js": ["redirectToBoard/script.js"], - "css": ["redirectToBoard/styles.css"] - }, - "allowedHostsCss": [ - "uczen.eduvulcan.pl", - "wiadomosci.eduvulcan.pl", - "dziennik-uczen.vulcan.net.pl", - "dziennik-wiadomosci.vulcan.net.pl" - ] - }, - { - "name": "Auto redirect to login page in eduVulcan", - "description": "Auto redirect to login page in eduVulcan.", - "files": { - "js": ["redirectToEVLogin.js"] - } - }, - { - "name": "Auto redirect to login page in Dziennik Vulcan", - "description": "Auto redirect to login page in Dziennik Vulcan.", - "files": { - "js": ["redirectToDVLogin.js"] - } - }, - { - "name": "Hide unneeded tiles in eduVulcan home", - "description": "Hides eduVulcan app download links tile, eduVulcan banner and ribbon.", - "files": { - "css": ["cleanUpEduVulcanHome.css"] - }, - "allowedHostsCss": ["eduvulcan.pl"] - }, - { - "name": "Hide Help On Dashboard", - "description": "Hides \"Do you need help\" tile.", - "files": { - "css": ["hideHelpOnDashboard.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "PWA Support", - "description": "Gives ability to install page as PWA.", - "files": { - "js": ["pwa.js"] - } - }, - { - "name": "Attendance statistics in separate tab", - "description": "Makes attendance page more readable by moving statistics to separate tab.", - "files": { - "css": ["attendance/styles.css"], - "js": ["attendance/tabs.js"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Reload on resize", - "description": "Reloads page while changing between desktop and mobile layouts.", - "files": { - "js": ["fixResizing.js"] - } - }, - { - "name": "Mobile Navigation", - "description": "Replaces aside with more readable bottom navigation bar designed. (mobile only)", - "files": { - "css": ["newMobileNavbar/styles.css"], - "js": ["newMobileNavbar/index.js", "newMobileNavbar/highlights.js"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Hide weekends in monthly calendars", - "description": "Hides weekends in monthly calendars in timetable, exams and homework views.", - "files": { - "css": ["hideWeekends.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl"] - }, - { - "name": "Login and password together", - "description": "Show login and password inputs together on login page.", - "files": { - "js": ["loginPasswordTogether/script.js"], - "css": ["loginPasswordTogether/styles.css"] - }, - "allowedHostsCss": ["eduvulcan.pl", "dziennik-logowanie.vulcan.net.pl"] - }, - { - "name": "Move user options to header", - "description": "Moves user avatar to header that opens dropdown with user options. (mobile only)", - "files": { - "js": ["moveUserOptionsToHeader/script.js"], - "css": ["moveUserOptionsToHeader/styles.css"] - }, - "allowedHostsCss": ["uczen.eduvulcan.pl", "dziennik-uczen.vulcan.net.pl", "wiadomosci.eduvulcan.pl", "dziennik-wiadomosci.vulcan.net.pl"] - }, - { - "name": "Resigned timetable", - "description": "Changes styles and navigation on timetable page. (mobile only)", - "files": { - "js": ["newTimetable/script.js"], - "css": ["newTimetable/styles.css", "apis/bottomDateSelector/styles.css"] - } - } -] \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/alignDetailedGradesButton.css b/app/src/main/assets/ifv/patches/alignDetailedGradesButton.css deleted file mode 100644 index 358c681..0000000 --- a/app/src/main/assets/ifv/patches/alignDetailedGradesButton.css +++ /dev/null @@ -1,3 +0,0 @@ -.grades__subject { - justify-content: space-between; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/apis/aside.js b/app/src/main/assets/ifv/patches/apis/aside.js deleted file mode 100644 index 8d8ee24..0000000 --- a/app/src/main/assets/ifv/patches/apis/aside.js +++ /dev/null @@ -1,42 +0,0 @@ -import { waitForRender } from "./waitForElement.js"; - -let asideReads = 0; - -const getAsideElement = async () => { - if (window.asideMode === "hidden" && document.querySelector("aside")) { - return document.querySelector("aside"); - } - - asideReads++; - if (!document.querySelector("aside")) - document.querySelector(".header__hamburger__icon button").click(); - await waitForRender(() => document.querySelector("aside")); - document.querySelector("aside").classList.add("hideAside"); - return document.querySelector("aside"); -}; - -const closeAside = () => { - const closeButton = document.querySelector("aside .close-button"); - if (window.asideMode !== "hidden") { - asideReads--; - if (closeButton && asideReads <= 0) closeButton.click(); - document.querySelector("aside")?.classList?.remove("hideAside"); - } -}; - -export const executeActionOnAside = async (fn) => { - const aside = await getAsideElement(); - await fn(aside) - if (!document.querySelector("aside") && window.asideMode === "hidden") { - document.querySelector(".header__hamburger__icon button").click(); - } else asideReads--; -} - -export const clickOnAside = (selector) => executeActionOnAside((aside) => aside.querySelector(selector)?.click()); - -export const getFromAside = async (fn) => { - const aside = await getAsideElement(); - const result = await fn(aside); - closeAside(); - return result; -}; diff --git a/app/src/main/assets/ifv/patches/apis/bottomDateSelector/index.js b/app/src/main/assets/ifv/patches/apis/bottomDateSelector/index.js deleted file mode 100644 index 7acbe6c..0000000 --- a/app/src/main/assets/ifv/patches/apis/bottomDateSelector/index.js +++ /dev/null @@ -1,217 +0,0 @@ -import { waitForRender } from "../waitForElement.js"; - -const dayNames = [ - "poniedziałek", - "wtorek", - "środa", - "czwartek", - "piątek", - "sobota", - "niedziela", -]; - -const getWeekStartingMonday = (i) => (i === 0 ? 6 : i - 1); - -const getWeek = (date) => { - const DAY = 24 * 60 * 60 * 1000; - const firstDay = new Date(`${date.getFullYear()}-01-01`); - return Math.floor((date.getTime() - firstDay.getTime()) / DAY / 7); -}; - -const isSameWeek = (date, comparedDate) => - getWeek(date) === getWeek(comparedDate); - -const updateReactInput = (input, value) => { - const setValue = Object.getOwnPropertyDescriptor( - Object.getPrototypeOf(input), - "value", - ).set; - const event = new Event("input", { bubbles: true }); - - setValue.call(input, value); - input.dispatchEvent(event); -}; - -export class SelectorRenderer { - constructor(renderContentFn) { - this.renderContent = renderContentFn; - - - this.#render().then(() => console.debug("Rendered date selector")); - } - - #createSelector(dayName) { - const element = document.createElement("div"); - element.innerHTML = ` - -
- - - -
- `; - - const dayDisplay = element.querySelector("span"); - dayDisplay.innerText = dayName; - dayDisplay.addEventListener("click", () => - element.querySelector("input").showPicker(), - ); - - const datePicker = element.querySelector("input"); - datePicker.addEventListener("change", () => - this.#setDay(datePicker.value, datePicker.valueAsDate), - ); - - element - .querySelector("img:first-of-type") - .addEventListener("click", () => this.#setSiblingDay(-1)); - element - .querySelector("img:last-of-type") - .addEventListener("click", () => this.#setSiblingDay(1)); - element.classList.add("date-selector"); - - return element; - } - - #updateSelectorDate(name) { - document.querySelector(".date-selector span").innerText = name; - } - - #getDaysDropdowns() { - return Array.from( - document.querySelectorAll(".app__content .MuiPaper-root"), - ).map((element) => ({ - element, - note: element.querySelector(".plan-zajec__accordion__wolne") - ?.innerText, - day: element.querySelector(".MuiAccordionSummary-content > h2") - ?.innerText, - })); - } - - #isDayListLoaded() { - return !document.querySelector(".spinner") && this.#isWeekChanged(); - } - - #isWeekChanged() { - return ( - !this.firstDayName || - document.querySelector( - ".app__content .MuiPaper-root .MuiAccordionSummary-content > h2", - )?.innerText !== this.firstDayName - ); - } - - async #setDay(value, valueDate) { - if ( - !isSameWeek( - document.querySelector(".week-selector input").valueAsDate, - valueDate, - ) - ) { - this.#setChecking(); - - if (!value || !valueDate) return; - updateReactInput( - document.querySelector(".week-selector input"), - value, - ); - - await waitForRender(() => this.#isDayListLoaded()); - } - - this.currentWeekDay = Math.min( - getWeekStartingMonday(valueDate.getDay()), - this.cachedWeek.length - 1, - ); - await this.#render(); - } - - async #setupAutoRender() { - if (this.observer) return; - this.observer = new MutationObserver(async () => { - const content = await this.renderContent( - this.cachedWeek[this.currentWeekDay], - ); - content.classList.add("day-content"); - document.querySelector(".day-content").replaceWith(content); - }); - - this.observer.observe( - document.querySelector( - ".content-container__tab-subheader:has(.week-selector) + div", - ), - { - childList: true, - subtree: true, - }, - ); - } - - async #render() { - let replaceable = document.querySelector(".day-content"); - if (!replaceable) { - replaceable = document.createElement("div"); - document - .querySelector("section.app__content .mobile__frame") - .appendChild(replaceable); - } - - this.cachedWeek = this.#getDaysDropdowns(); - - if (this.currentWeekDay === undefined) { - const today = new Date() - const day = getWeekStartingMonday(today.getDay()) - this.currentWeekDay = this.cachedWeek.findIndex((timetableDay) => (timetableDay.day || "-, ").split(", ")[0].toLowerCase() === dayNames[day]); - } - - const content = await this.renderContent( - this.cachedWeek[this.currentWeekDay], - ); - content.classList.add("day-content"); - replaceable.replaceWith(content); - - if (document.querySelector(".date-selector")) { - this.#updateSelectorDate(this.cachedWeek[this.currentWeekDay].day); - } else - document - .querySelector("section.app__content .mobile__frame") - .appendChild( - this.#createSelector( - this.cachedWeek[this.currentWeekDay].day, - ), - ); - - this.#setupAutoRender(); - } - - #setChecking() { - this.firstDayName = this.cachedWeek[0].day; - } - - async #setSiblingDay(direction = 1) { - this.#setChecking(); - document.querySelector("#root").scroll(0, 0); - - const target = this.currentWeekDay + direction; - if (target >= this.cachedWeek.length || target < 0) { - if (target < 0) { - this.currentWeekDay = 4; - document - .querySelector(".week-selector > button:first-of-type") - .click(); - } else { - this.currentWeekDay = 0; - document - .querySelector(".week-selector > button:last-of-type") - .click(); - } - - await waitForRender(() => this.#isDayListLoaded()); - } else { - this.currentWeekDay = target; - } - - await this.#render(); - } -} diff --git a/app/src/main/assets/ifv/patches/apis/bottomDateSelector/styles.css b/app/src/main/assets/ifv/patches/apis/bottomDateSelector/styles.css deleted file mode 100644 index 553bb8f..0000000 --- a/app/src/main/assets/ifv/patches/apis/bottomDateSelector/styles.css +++ /dev/null @@ -1,37 +0,0 @@ -.date-selector > div { - height: 40px; - position: fixed; - margin-bottom: var(--bottom-navbar-height); - bottom: 0; - width: 100vw; - left: 0; - display: flex; - justify-content: space-between; - background: var(--background-navigation); - border-top: 2px solid #e5e7e9; - z-index: 100; - align-items: center; -} - -.date-selector > input { - display: none; -} - -div#root:has(.date-selector) { - height: calc(100svh - 60px - var(--bottom-navbar-height) - 40px); -} - -.date-selector > div > img { - filter: invert(0.8); - height: 35px; - cursor: pointer; -} - -.date-selector > div > span { - font-size: 15px; - cursor: pointer; -} - -body:has(.date-selector):not(:has(.modal)) .bottom-navigation-bar { - border-top: 0 !important; -} diff --git a/app/src/main/assets/ifv/patches/apis/getUserData.js b/app/src/main/assets/ifv/patches/apis/getUserData.js deleted file mode 100644 index 7d129c4..0000000 --- a/app/src/main/assets/ifv/patches/apis/getUserData.js +++ /dev/null @@ -1,28 +0,0 @@ -import { waitForRender } from "./waitForElement.js"; -import { getFromAside } from "./aside.js"; - -export const getUserData = async () => { - return await getFromAside(async () => { - await waitForRender( - () => - document.querySelector( - window.location.hostname.includes("wiadomosci") - ? ".account__name span" - : ".side_important-text.side_student", - ) && document.querySelector(".user div:nth-child(2)"), - ); - - return { - fullName: window.location.hostname.includes("wiadomosci") - ? document - .querySelector(".account__name span") - ?.firstChild?.textContent?.split(" ") - .reverse() - .join(" ") - : document.querySelector(".side_important-text.side_student") - ?.textContent, - username: document.querySelector(".user div:nth-child(2)").lastChild - .textContent, - }; - }); -}; diff --git a/app/src/main/assets/ifv/patches/apis/waitForElement.js b/app/src/main/assets/ifv/patches/apis/waitForElement.js deleted file mode 100644 index b20b636..0000000 --- a/app/src/main/assets/ifv/patches/apis/waitForElement.js +++ /dev/null @@ -1,15 +0,0 @@ -export const waitForRender = async (fn, target = document.body) => { - let resolve; - const wait = new Promise((r) => (resolve = r)); - const observer = new MutationObserver((mutations, observer) => { - if (!fn()) return; - resolve(); - observer.disconnect(); - }); - observer.observe(target, { subtree: true, childList: true }); - - const lastTry = fn(); - if (!lastTry) { - await wait; - } -}; diff --git a/app/src/main/assets/ifv/patches/arrows.css b/app/src/main/assets/ifv/patches/arrows.css deleted file mode 100644 index 993f7e5..0000000 --- a/app/src/main/assets/ifv/patches/arrows.css +++ /dev/null @@ -1,51 +0,0 @@ -@media screen and (max-width: 1023px) { - .modal__header { - font-family: - "WorkSans", - Graphik, - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - Helvetica, - Arial, - sans-serif, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol" !important; - background: white !important; - border-bottom: 2px solid #e5e7e9 !important; - min-height: 60px !important; - color: black !important; - } - - .modal__title { - padding: 17.5px 48px !important; - } - - .close-button:not(aside .close-button) { - background-color: white !important; - box-shadow: none !important; - position: absolute !important; - top: calc((60px - 40px) / 2) !important; - cursor: pointer; - padding: 0 !important; - margin: 0 0 0 10px !important; - border: none !important; - width: 40px !important; - height: 40px !important; - } - - .close-button:not(aside .close-button) > span:first-of-type { - display: none !important; - } - - .close-button:not(aside .close-button) > span:last-of-type { - content: url("https://raw.githubusercontent.com/banocean/ifv/main/assets/icons/keyboard_backspace_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg"); - filter: invert(0.8); - height: 40px; - } - - .close-button:not(aside .close-button) > span > svg { - display: none !important; - } -} diff --git a/app/src/main/assets/ifv/patches/attendance/styles.css b/app/src/main/assets/ifv/patches/attendance/styles.css deleted file mode 100644 index 0710de3..0000000 --- a/app/src/main/assets/ifv/patches/attendance/styles.css +++ /dev/null @@ -1,23 +0,0 @@ -.attendance-tabs > button:disabled { - opacity: 50%; -} - -.attendance-tabs > button:first-of-type { - margin-right: 10px; -} - -.tabsview.stats > div:first-of-type { - display: none !important; -} - -.tabsview.stats > .tabsview__tabs > div > div > div:not(:last-of-type) { - display: none; -} - -.tabsview.attendance-init:not(.stats) > .tabsview__tabs > div > div > div:last-of-type { - display: none; -} - -.tabsview.attendance-init > div:first-of-type { - margin-top: 10px; -} diff --git a/app/src/main/assets/ifv/patches/attendance/tabs.js b/app/src/main/assets/ifv/patches/attendance/tabs.js deleted file mode 100644 index 006e278..0000000 --- a/app/src/main/assets/ifv/patches/attendance/tabs.js +++ /dev/null @@ -1,47 +0,0 @@ -const selector = document.createElement("div") -selector.innerHTML = - ''; -selector.classList.add("attendance-tabs") - -const createSelector = () => { - document.querySelector("h1").replaceWith(selector) - changeStatsVisibility(false) -} - -const changeStatsVisibility = (isStatsVisible) => { - const mainStats = document.querySelector(".content-container:has(.statistics)") - mainStats.style.display = isStatsVisible ? "block" : "none" - const element = document.querySelector(".tabsview") - element.classList.add("attendance-init") - if (isStatsVisible) element.classList.add("stats") - else element.classList.remove("stats") -} - -selector.querySelector("button:first-of-type").addEventListener("click", () => { - changeStatsVisibility(false) - - selector.querySelector("button:first-of-type").disabled = true - selector.querySelector("button:last-of-type").disabled = false -}) - -selector.querySelector("button:last-of-type").addEventListener("click", () => { - changeStatsVisibility(true) - - selector.querySelector("button:first-of-type").disabled = false - selector.querySelector("button:last-of-type").disabled = true -}) - -const isAttendancePage = () => window.location.pathname.endsWith("frekwencja") - -const isRendered = () => - !!document.querySelector(".content-container:has(.statistics)") - && !!document.querySelector(".tabsview") - && !!document.querySelector("h1") - - -window.appendModule({ - isLoaded: isRendered, - run: createSelector, - onlyOnReloads: false, - doesRunHere: isAttendancePage -}) diff --git a/app/src/main/assets/ifv/patches/cleanUpEduVulcanHome.css b/app/src/main/assets/ifv/patches/cleanUpEduVulcanHome.css deleted file mode 100644 index f700777..0000000 --- a/app/src/main/assets/ifv/patches/cleanUpEduVulcanHome.css +++ /dev/null @@ -1,24 +0,0 @@ -/* app download links, eduvulcan banner, maziaj */ -.box-app, .carousel-area, .ribbon-bg { - display: none !important; -} - -.part-business-content-bottom { - padding-left: 0 !important; -} - -.main-content { - flex-direction: column; - flex: inherit !important; -} - -.part-constant, .part-business { - flex: 0 !important; - padding: 0 !important; -} - -.part-business { order: 2 !important; } - -.header-part-2 { - min-width: inherit !important; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/displayFullName.js b/app/src/main/assets/ifv/patches/displayFullName.js deleted file mode 100644 index 4b1a5bc..0000000 --- a/app/src/main/assets/ifv/patches/displayFullName.js +++ /dev/null @@ -1,43 +0,0 @@ -const isMessagesPage = () => window.location.hostname.match( - /(dziennik-)?wiadomosci.*/, -); - -function getStudentData() { - return isMessagesPage() - ? document - .querySelector(".account__name span") - ?.firstChild?.textContent?.split(" ") - .reverse() - .join(" ") - : document.querySelector(".side_student")?.firstChild?.textContent; -} - -function displayFullName() { - const studentData = getStudentData(); - - if (!studentData) return; - - const studentNameSpan = document.createElement("span"); - studentNameSpan.style = "font-size: 20px;"; - studentNameSpan.innerHTML = `${studentData}`; - - const usernameContainer = document.querySelector( - ".user div:nth-of-type(2)", - ); - usernameContainer.style = - "display: flex; flex-direction: column; font-size: 16px;"; - - usernameContainer.insertBefore( - studentNameSpan, - usernameContainer.firstChild, - ); -} - -window.appendModule({ - isLoaded: () => document.querySelector( - `.${isMessagesPage() ? "account__name span" : "side_student"}`, - ), - onlyOnReloads: true, - run: displayFullName, - doesRunHere: () => !!window.location.hostname.match(/^(dziennik-)?(wiadomosci|uczen).*/) -}) diff --git a/app/src/main/assets/ifv/patches/fixResizing.js b/app/src/main/assets/ifv/patches/fixResizing.js deleted file mode 100644 index 2016c3c..0000000 --- a/app/src/main/assets/ifv/patches/fixResizing.js +++ /dev/null @@ -1,13 +0,0 @@ -const startingWidth = window.innerWidth - -const startListening = () => { - addEventListener("resize", () => { - if (startingWidth < 1024 !== window.innerWidth < 1024) window.location.reload() - }); -} - -window.appendModule({ - run: startListening, - onlyOnReloads: true, - doesRunHere: () => window.location.hostname !== "eduvulcan.pl" -}) diff --git a/app/src/main/assets/ifv/patches/hideEmptyExamResults.css b/app/src/main/assets/ifv/patches/hideEmptyExamResults.css deleted file mode 100644 index a515548..0000000 --- a/app/src/main/assets/ifv/patches/hideEmptyExamResults.css +++ /dev/null @@ -1,9 +0,0 @@ -.accordion__full-width__one-item:has(#panel-content-egzaminy td[colspan="3"]) { - display: none !important; -} - - -main .app__content:has(.accordion__full-width__one-item #panel-content-egzaminy td[colspan="3"]) .content-container.content-container__pure > div:nth-child(2) { - border-bottom-left-radius: 10px; - border-bottom-right-radius: 10px; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/hideFooter.css b/app/src/main/assets/ifv/patches/hideFooter.css deleted file mode 100644 index c355dff..0000000 --- a/app/src/main/assets/ifv/patches/hideFooter.css +++ /dev/null @@ -1,5 +0,0 @@ -@media screen and (max-width: 1023px) { - .app__footer__container { - display: none; - } -} diff --git a/app/src/main/assets/ifv/patches/hideHelpOnDashboard.css b/app/src/main/assets/ifv/patches/hideHelpOnDashboard.css deleted file mode 100644 index 7041090..0000000 --- a/app/src/main/assets/ifv/patches/hideHelpOnDashboard.css +++ /dev/null @@ -1,3 +0,0 @@ -#kafel-pomoc-pomigracyjna { - display: none !important; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/finalGrades.js b/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/finalGrades.js deleted file mode 100644 index 5ccb30f..0000000 --- a/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/finalGrades.js +++ /dev/null @@ -1,62 +0,0 @@ -import { waitForRender } from "../apis/waitForElement.js"; - -const SEMESTERS = 2; -const renderVisibilityButtons = () => { - for (let i = 0; i < SEMESTERS; i++) { - hideEmptyFinalGradesInfo(i); - } -}; - -const getSemestersContainer = () => - document.querySelector( - "section > section > .mobile__frame > .content-container", - ).children; -const getRowValue = (node) => - node?.querySelector(".info-text > span")?.innerText?.trim(); - -const hideEmptyFinalGradesInfo = async (i) => { - await waitForRender( - () => getSemestersContainer()[i].querySelector("article"), - document.querySelector( - "section > section > .mobile__frame > .content-container", - ), - ); - const container = getSemestersContainer()[i]; - const subjects = container.querySelectorAll("article"); - for (const subject of subjects) { - const finalGrades = subject.querySelector( - ".tile__content:last-of-type", - ); - const predictedFinalGrade = finalGrades.children[0]; - const finalGrade = finalGrades.children[1]; - - const predictedFinalGradeValue = getRowValue(predictedFinalGrade); - const finalGradeValue = getRowValue(finalGrade); - - if (predictedFinalGrade && !predictedFinalGradeValue) - predictedFinalGrade.style.display = "none"; - if (finalGrade && !finalGradeValue) { - if (predictedFinalGrade) - predictedFinalGrade.style.borderBottom = "none"; - finalGrade.style.display = "none"; - } - - if (!finalGradeValue && !predictedFinalGradeValue) { - finalGrades.style.display = "none"; - subject.querySelector( - ".tile__content.border-b-1", - ).style.borderBottom = "none"; - } - } -}; - -window.appendModule({ - run: renderVisibilityButtons, - onlyOnReloads: false, - doesRunHere: () => - window.location.pathname.endsWith("oceny") && window.innerWidth < 1024, - isLoaded: () => - document.querySelector( - "section > section > .mobile__frame > .content-container", - ), -}); diff --git a/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/normalGrades.css b/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/normalGrades.css deleted file mode 100644 index 28d2267..0000000 --- a/app/src/main/assets/ifv/patches/hideSubjectsWithNoGrades/normalGrades.css +++ /dev/null @@ -1,7 +0,0 @@ -article.grades__box:has(.tile__content:first-of-type:empty) { - display: none !important; -} - -tbody.p-datatable-tbody > tr:has(.wider--oceny:empty) { - display: none !important; -} diff --git a/app/src/main/assets/ifv/patches/hideTutorsFromBoard.css b/app/src/main/assets/ifv/patches/hideTutorsFromBoard.css deleted file mode 100644 index 0903ea0..0000000 --- a/app/src/main/assets/ifv/patches/hideTutorsFromBoard.css +++ /dev/null @@ -1,3 +0,0 @@ -.tile:has(.tile__content .tile__teachers) { - display: none !important; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/hideWCAG.css b/app/src/main/assets/ifv/patches/hideWCAG.css deleted file mode 100644 index 15785a9..0000000 --- a/app/src/main/assets/ifv/patches/hideWCAG.css +++ /dev/null @@ -1,3 +0,0 @@ -.wcag-mobile, .wcag-tools, .wcag-controls { - display: none !important; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/hideWeekends.css b/app/src/main/assets/ifv/patches/hideWeekends.css deleted file mode 100644 index ce1912f..0000000 --- a/app/src/main/assets/ifv/patches/hideWeekends.css +++ /dev/null @@ -1,32 +0,0 @@ -.plan-scheduler__body-cell:nth-of-type(6), -.plan-scheduler__body-cell:nth-of-type(7), -.plan-scheduler__header-cell:nth-of-type(6), -.plan-scheduler__header-cell:nth-of-type(7), -.scheduler-simple__header-cell:nth-of-type(6), -.scheduler-simple__header-cell:nth-of-type(7), -.scheduler-simple__body-cell:nth-of-type(6), -.scheduler-simple__body-cell:nth-of-type(7), -.scheduler__body-cell:nth-of-type(6), -.scheduler__body-cell:nth-of-type(7), -.scheduler__header-cell:nth-of-type(6), -.scheduler__header-cell:nth-of-type(7), -.frequency-scheduler__body-cell:nth-of-type(6), -.frequency-scheduler__body-cell:nth-of-type(7), -.frequency-scheduler__header-cell:nth-of-type(6), -.frequency-scheduler__header-cell:nth-of-type(7) { - display: none !important; -} - -.plan-scheduler-cell__unavailable > div, -.scheduler-simple-cell--disabled > div, -.frequency-scheduler-cell--unavailable > div { - min-height: 0 !important; - padding: 0 !important; -} - -.plan-scheduler-cell__unavailable, -.scheduler-simple-cell--disabled, -.frequency-scheduler-cell--unavailable { - padding: 0 !important; - margin: 0 !important; -} diff --git a/app/src/main/assets/ifv/patches/loginPasswordTogether/script.js b/app/src/main/assets/ifv/patches/loginPasswordTogether/script.js deleted file mode 100644 index c0cbba7..0000000 --- a/app/src/main/assets/ifv/patches/loginPasswordTogether/script.js +++ /dev/null @@ -1,43 +0,0 @@ -function setAutocomplete() { - document.querySelector("#Login")?.setAttribute("autocomplete", "username"); - document - .querySelector("#Haslo") - ?.setAttribute("autocomplete", "current-password"); -} - -function hideBtNext() { - document.querySelector("#btNext").remove(); -} - -function moveEVLinks() { - const linksEl = document.querySelector("#wizard1 > div > .flex-row:has(a)"); - document.querySelector("#wizard2").appendChild(linksEl); -} - -function swapLoginInput() { - const wizard2 = document.querySelector("#wizard2"); - wizard2.parentElement.insertBefore( - document.querySelector("#wizard1"), - wizard2, - ); - // Force firefox to check inputs again - const centerBox = document.querySelector(".center-box"); - centerBox.innerHTML = centerBox.innerHTML; -} - -function fixLoginPage() { - setAutocomplete(); - hideBtNext(); - if (window.location.hostname === "eduvulcan.pl") moveEVLinks(); - swapLoginInput(); -} - -window.appendModule({ - isLoaded: () => document.querySelector("#Haslo"), - onlyOnReloads: true, - run: fixLoginPage, - doesRunHere: () => - ["eduvulcan.pl", "dziennik-logowanie.vulcan.net.pl"].includes( - window.location.hostname, - ), -}); diff --git a/app/src/main/assets/ifv/patches/loginPasswordTogether/styles.css b/app/src/main/assets/ifv/patches/loginPasswordTogether/styles.css deleted file mode 100644 index fff6f90..0000000 --- a/app/src/main/assets/ifv/patches/loginPasswordTogether/styles.css +++ /dev/null @@ -1,20 +0,0 @@ -#wizard1 { - order: 2; - display: block !important; -} - -.form-focused-subtitle, -.form-subtitle, -#wizard1 > .flex-col.form-gap.form-margin, -#wizard1 > .flex-col.gap-3.my-2 { - display: none !important; -} - -#wizard2 { - order: 3; - display: block !important; -} - -#btPrev { - display: none; -} diff --git a/app/src/main/assets/ifv/patches/messagesButton.js b/app/src/main/assets/ifv/patches/messagesButton.js deleted file mode 100644 index 815acf7..0000000 --- a/app/src/main/assets/ifv/patches/messagesButton.js +++ /dev/null @@ -1,33 +0,0 @@ -import { waitForRender } from "./apis/waitForElement.js"; -import { getFromAside } from "./apis/aside.js"; - -async function move() { - const inner = await getFromAside( - async () => { - await waitForRender(() => document.querySelector(".messages")) - return document.querySelector(".messages")?.innerHTML - } - ) - - const messages = document.createElement("div"); - messages.innerHTML = inner; - messages.style.float = "right"; - messages.style.padding = "20px"; - messages.style.marginLeft = "auto"; - messages.querySelector( - ".MuiBadge-anchorOriginTopRightRectangle", - ).style.transitionDuration = "0ms"; - - document - .querySelector(".header_logo_tools-container") - .appendChild(messages); -} - -window.appendModule({ - run: move, - doesRunHere: () => - window.location.hostname.match(/^(dziennik-)?(uczen).*/) && - window.innerWidth < 1024, - onlyOnReloads: true, - isLoaded: () => !!document.querySelector(".header__hamburger__icon") -}); diff --git a/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/script.js b/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/script.js deleted file mode 100644 index 13ba31f..0000000 --- a/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/script.js +++ /dev/null @@ -1,92 +0,0 @@ -import { waitForRender } from "../apis/waitForElement.js"; -import { executeActionOnAside, getFromAside } from "../apis/aside.js"; -import { getUserData } from "../apis/getUserData.js"; - -const toggleModal = () => { - document.querySelector(".modal-background").classList.toggle("active"); - document.querySelector(".modal-user").classList.toggle("active"); -}; - -const moveUserOptionsToHeader = async () => { - const userLinks = await getFromAside(async () => { - const user = document.querySelector(".user"); - if (user) { - user.click(); - await waitForRender(() => - document.querySelector(".user__links a"), - ); - return document.querySelectorAll(".user__links a"); - } - }); - const userData = await getUserData(); - - const modalBackground = document.createElement("div"); - const modalElement = document.createElement("div"); - - modalBackground.classList.add("modal-background"); - modalElement.classList.add("modal-user"); - - const userDataElement = document.createElement("div"); - userDataElement.classList.add("modal-data"); - - const userAvatar = document.createElement("div"); - userAvatar.innerHTML = `${userData.fullName[0]}`; - userAvatar.classList.add("user-avatar"); - userDataElement.appendChild(userAvatar.cloneNode(true)); - - const nameElement = document.createElement("div"); - nameElement.classList.add("modal-name"); - nameElement.innerHTML = `${userData?.fullName}${userData?.username}`; - userDataElement.appendChild(nameElement); - - modalElement.appendChild(userDataElement); - - userLinks.forEach((link, i) => { - const linkContainer = document.createElement("div"); - linkContainer.classList.add("modal-link-container"); - - const linkText = document.createElement("span"); - linkText.innerHTML = link.textContent; - - linkText.addEventListener("click", () => { - executeActionOnAside(async () => { - document.querySelector(".user").click(); - await waitForRender(() => document.querySelector(".user__links")); - document.querySelectorAll(".user__links a")[i].click() - }) - toggleModal(); - }); - - linkContainer.appendChild(linkText); - modalElement.appendChild(linkContainer); - }); - - const backButtonContainer = document.createElement("div"); - backButtonContainer.classList.add("modal-back-container"); - const backButton = document.createElement("span"); - backButton.classList.add("modal-cancel"); - backButton.innerHTML = "Anuluj"; - backButtonContainer.appendChild(backButton); - modalElement.appendChild(backButtonContainer); - - modalBackground.addEventListener("click", toggleModal); - backButton.addEventListener("click", toggleModal); - userAvatar.addEventListener("click", toggleModal); - - document.body.appendChild(modalElement); - document.body.appendChild(modalBackground); - document - .querySelector(".header_logo_tools_user-wrapper") - .appendChild(userAvatar); -}; - -window.appendModule({ - isLoaded: () => - document.querySelector(".header__logo-product")?.firstChild && - document.querySelector(".header__hamburger__icon button"), - onlyOnReloads: true, - run: moveUserOptionsToHeader, - doesRunHere: () => - !!window.location.hostname.match(/^(dziennik-)?(wiadomosci|uczen).*/) && - window.innerWidth < 1024, -}); diff --git a/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/styles.css b/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/styles.css deleted file mode 100644 index 4289542..0000000 --- a/app/src/main/assets/ifv/patches/moveUserOptionsToHeader/styles.css +++ /dev/null @@ -1,123 +0,0 @@ -@media screen and (max-width: 1023px) { - .user__section, - div:has(.user__links__conatainer) { - display: none !important; - } - - .app.hideAside aside { - display: none !important; - } - - .header_logo_tools_user-wrapper img { - width: 45px; - height: 45px; - margin-right: 10px; - cursor: pointer; - } - - .modal-background { - display: none; - position: absolute; - top: 0; - left: 0; - width: 100vw; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - z-index: 9999; - } - - .modal-background.active { - display: block !important; - } - - .modal-user { - display: none; - top: 50%; - left: 50%; - position: absolute; - overflow: hidden; - transform: translate(-50%, -50%); - - width: 80vw; - max-width: 400px; - height: min-content !important; - max-height: min-content !important; - border-radius: 10px; - background-color: #fff; - z-index: 10000; - padding: 10px; - } - - .modal-user.active { - display: block !important; - } - - .modal-data { - display: flex; - align-items: center; - gap: 10px; - padding: 10px 20px; - margin-bottom: 10px; - } - - .modal-name { - display: flex; - flex-direction: column; - padding-left: none; - gap: 5px; - } - - .modal-link-container, - .modal-back-container { - display: flex; - align-items: center; - padding: 10px 20px; - cursor: pointer; - } - - .modal-back-container { - justify-content: flex-end; - } - - .modal-link-container span { - padding: 0; - font-size: 1.2rem; - font-weight: 500; - text-decoration: none; - color: #3d4455; - } - - .modal-cancel { - text-align: right; - color: #e33f4a; - font-size: 1.2rem; - font-weight: 500; - cursor: pointer; - } - - .header__logo-product > img { - width: auto !important; - } - - header.app__header { - height: 60px; - } - - body.blue .user-avatar { - background: #38817f !important; - color: #ffffff; - } - - .user-avatar { - background: #f8d6d8; - height: 40px; - width: 40px; - border-radius: 50%; - margin-right: 16px; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - font-size: 1.8rem; - } -} diff --git a/app/src/main/assets/ifv/patches/newMobileNavbar/highlights.js b/app/src/main/assets/ifv/patches/newMobileNavbar/highlights.js deleted file mode 100644 index 4b131c1..0000000 --- a/app/src/main/assets/ifv/patches/newMobileNavbar/highlights.js +++ /dev/null @@ -1,23 +0,0 @@ -export const setHighlights = () => { - let i; - if (document.querySelector(".more-popup").style.display === "block") i = 4 - else if (window.location.pathname.endsWith("tablica")) i = 0 - else if (window.location.pathname.endsWith("oceny")) i = 1 - else if (window.location.pathname.endsWith("frekwencja")) i = 2 - else if (window.location.pathname.endsWith("planZajec")) i = 3 - - const buttons = Array.from(document.querySelector(".bottom-navigation-bar").children) - for (let j = 0; j < buttons.length; j++) { - const button = buttons[j] - const img = button.querySelector("div > img"); - if (i === j) img.classList.add("highlight") - else img.classList.remove("highlight") - } -} - -window.appendModule({ - run: setHighlights, - onlyOnReloads: false, - isLoaded: () => document.querySelector(".bottom-navigation-bar")?.children?.length, - doesRunHere: () => window.location.hostname.match(/^(dziennik-)?(uczen).*/) && window.innerWidth < 1024, -}) \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/newMobileNavbar/index.js b/app/src/main/assets/ifv/patches/newMobileNavbar/index.js deleted file mode 100644 index c6306d5..0000000 --- a/app/src/main/assets/ifv/patches/newMobileNavbar/index.js +++ /dev/null @@ -1,145 +0,0 @@ -import { getFromAside } from "../apis/aside.js"; -import { waitForRender } from "../apis/waitForElement.js"; -import { setHighlights } from "./highlights.js"; - -if (window.location.hostname.match(/^(dziennik-)?(uczen).*/)) window.asideMode = "hidden" - -const getPages = (selector = "aside > section > .MuiList-root > ul") => { - if (!document.querySelector("aside")) return [] - return Array.from( - document.querySelector(selector).children - ).map((item) => { - const isDirectLink = item.classList.contains("MuiListItem-gutters") - const icon = getComputedStyle( - isDirectLink ? item : item.querySelector("div > button"), ":before" - ).getPropertyValue("content"); - const name = item.querySelector( - isDirectLink ? "a" : ".accordion__title__content" - )?.innerText - - const items = isDirectLink ? undefined : - Array.from(item.querySelector(".items").children) - - return { - type: isDirectLink ? 1 : 2, - element: item, - items, - icon, - name - } - }) -} - -const BACK_ICON_URL = "https://raw.githubusercontent.com/banocean/ifv/new-navbar/assets/icons/keyboard_backspace_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg" - -const navIcons = { - "tablica": "dashboard", - "oceny": "counter_6", - "frekwencja": "event_available", - "planZajec": "calendar_clock" -} - -const run = async () => { - const nav = document.createElement("nav") - nav.classList.add("bottom-navigation-bar") - - const more = document.createElement("div") - more.classList.add("more-popup") - more.classList.add("list-modal") - more.innerHTML = `

Więcej

` - more.style.display = "none" - - more.querySelector("img").addEventListener("click", () => { - more.style.display = "none" - setHighlights() - }) - - await getFromAside(() => null) // We need aside to just load - await waitForRender(() => getPages().length > 1) - - const navPages = ["tablica", "oceny", "frekwencja", "planZajec"] - const pages = getPages() - for (const page of pages) { - const itemClass = Array.from(page.element.classList) - .find((c) => !["MuiListItem-root", "MuiListItem-gutters", "selected"].includes(c)) - const item = document.createElement("div") - - if (!navPages.includes(itemClass)) { - item.innerHTML = "
" - item.querySelector(".icon").style.content = page.icon - item.querySelector(".name").innerText = page.name - more.querySelector("div:last-of-type").appendChild(item) - } else { - item.innerHTML = `
` - item.querySelector("div:last-of-type").innerText = page.name - nav.appendChild(item) - } - - if (page.type === 1) { - item.addEventListener("click", () => { - document.querySelector(`.${itemClass} a`).click() - more.style.display = "none" - document.querySelector(".header__hamburger__icon button").click() - document.querySelector("div#root").scroll(0,0) - setHighlights() - }) - } else { - const detailedOptionsPage = document.createElement("div") - detailedOptionsPage.innerHTML = `

` - detailedOptionsPage.style.zIndex = "4002" - detailedOptionsPage.style.display = "none" - detailedOptionsPage.classList.add("list-modal") - - detailedOptionsPage.querySelector("h1").innerText = page.name - detailedOptionsPage.querySelector("img").addEventListener("click", () => { - detailedOptionsPage.style.display = "none" - }) - - for (let i = 0; i < page.items.length; i++) { - const option = page.items[i] - const element = document.createElement("div") - element.innerHTML = "
" - element.querySelector(".icon").style.content = page.icon - element.querySelector(".name").innerText = option.firstChild.innerText - element.addEventListener("click", () => { - Array.from(document.querySelectorAll(`.${itemClass} .items a`))[i].click() - detailedOptionsPage.style.display = "none" - more.style.display = "none" - document.querySelector(".header__hamburger__icon button").click() - document.querySelector("div#root").scroll(0,0) - }) - detailedOptionsPage.lastElementChild.appendChild(element) - } - - item.addEventListener("click", () => { - detailedOptionsPage.style.display = "block" - }) - - document.body.appendChild(detailedOptionsPage) - } - } - - const moreButton = document.createElement("div") - moreButton.innerHTML = ` -
- -
-
Więcej
- ` - moreButton.addEventListener("click", () => { - more.style.display = "block" - setHighlights() - }) - nav.appendChild(moreButton) - - document.body.appendChild(nav) - document.body.appendChild(more) -} - - -window.appendModule({ - run, - doesRunHere: () => window.location.hostname.match(/^(dziennik-)?(uczen).*/) && window.innerWidth < 1024, - onlyOnReloads: true, - isLoaded: () => !!document.querySelector(".header__hamburger__icon") -}) \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/newMobileNavbar/styles.css b/app/src/main/assets/ifv/patches/newMobileNavbar/styles.css deleted file mode 100644 index 05f8fef..0000000 --- a/app/src/main/assets/ifv/patches/newMobileNavbar/styles.css +++ /dev/null @@ -1,157 +0,0 @@ -:root { - --bottom-navbar-height: 70px; -} - -.list-modal { - height: 100svh; - width: 100%; - position: fixed; - top: 0; - left: 0; - z-index: 4000; - background: #eff2f7; - font-family: "WorkSans", Graphik, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -} - -.list-modal > div:first-of-type { - background: white; - border-bottom: 2px solid #e5e7e9; - height: 60px; - display: flex; - align-items: center; -} - -.list-modal > div:first-of-type > img { - margin-left: 10px; - position: absolute; - filter: invert(0.8); - top: calc((60px - 40px) / 2); - cursor: pointer; - height: 40px; -} - - -.list-modal > div:first-of-type > h1 { - width: 100%; - font-size: 1.8rem; - text-align: center; -} - -.list-modal > div:last-of-type { - overflow-y: auto; - height: calc(100svh - 60px - var(--bottom-navbar-height)); -} - -.list-modal > div:last-of-type > div { - display: flex; - color: black; - font-size: 1.6rem; - cursor: pointer; - padding-inline: 15px; - padding-block: 10px; - fill: black; - border-bottom: 1px solid #e5e7e9; - align-items: center; -} - -.list-modal > div:last-of-type > div > .icon { - filter: invert(0.8); - margin-right: 20px; -} - -.list-modal > div:last-of-type > div > .name { - display: flex; - align-content: center; -} - - - -@media screen and (max-width: 1023px) { - .modal { - width: 100vw !important; - height: calc(100svh - var(--bottom-navbar-height)) !important; - } - - .modal__footer { - background: none !important; - border-top: 0 !important - } - - aside, .header__hamburger__icon { - display: none !important; - } - - .app__aside__mobile + .app__main { - display: block !important; - } - - div#root { - overflow: auto; - height: calc(100svh - 60px - var(--bottom-navbar-height)); - top: 60px; - position: fixed; - } - - header.app__header { - position: fixed; - width: 100%; - top: 0; - } - - .bottom-navigation-bar { - border-top: 2px solid #e5e7e9; - background: white; - display: flex; - justify-content: space-around; - position: fixed; - top: calc(100svh - var(--bottom-navbar-height)); - height: var(--bottom-navbar-height); - width: 100%; - align-items: center; - z-index: 4002; - } - - .bottom-navigation-bar > div { - cursor: pointer; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - } - - .bottom-navigation-bar > div > div:has(img) { - padding-inline: 15px; - padding-block: 4px; - margin-bottom: 4px; - border-radius: 20px; - width: min-content; - display: flex; - align-items: center; - justify-content: center; - height: 40px; - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 300ms; - } - - .bottom-navigation-bar > div > div > img { - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 300ms; - height: 25px; - margin: 2px; - } - - .bottom-navigation-bar > div > div:has(img.highlight) { - font-family: "WorkSans", Graphik, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - background: var(--kolor-wcag); - } - - .bottom-navigation-bar > div > div > img:not(.highlight) { - filter: invert(1); - } -} - -main.app__main { - width: 100vw !important; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/newTimetable/script.js b/app/src/main/assets/ifv/patches/newTimetable/script.js deleted file mode 100644 index 47a985f..0000000 --- a/app/src/main/assets/ifv/patches/newTimetable/script.js +++ /dev/null @@ -1,189 +0,0 @@ -import { waitForRender } from "../apis/waitForElement.js"; -import { SelectorRenderer } from "../apis/bottomDateSelector/index.js"; - -const normalizeLesson = (lesson) => { - const hoursText = ( - lesson.querySelector( - ".position__lesson__hours, .conflicted--details--hours", - )?.innerText || " " - ).split(" "); - const startingHour = hoursText[0]; - const endingHour = hoursText[2]; - - const subjectText = - lesson - .querySelector(".position__lesson__subject") - ?.innerText?.split(/ Grupa-| \|/) || []; - - const annotationText = lesson.querySelector( - ".plan-position__adnotation-title", - )?.innerText; - - const type = lesson.classList.contains("cell--multi--conflicted") - ? "conflicted" - : lesson.querySelector(".zastepstwo") - ? "substitute" - : lesson.querySelector(".odwolane") - ? "canceled" - : annotationText - ? "unknown" - : "normal"; - - return { - originalElement: lesson, - type, - subject: subjectText[0], - group: subjectText[1], - teacher: lesson.querySelector(".position__lesson__teacher")?.innerText, - classroom: [ - ...(lesson.querySelector(".position__lesson__subject + span") - ?.innerText || ""), - ] - .filter((c) => !"()".includes(c)) - .join(""), - annotationText, - startingHour, - endingHour, - }; -}; -const mapDay = (element) => - Array.from( - element.querySelectorAll(".cell--single, .cell--multi--conflicted"), - ).map(normalizeLesson); - -const mapData = () => - Array.from(document.querySelectorAll(".app__content .MuiPaper-root")).map( - (element) => { - return { - note: element.querySelector(".plan-zajec__accordion__wolne") - ?.innerText, - day: element.querySelector(".MuiAccordionSummary-content > h2") - ?.innerText, - lessons: mapDay(element), - }; - }, - ); -const isOpened = (element) => - element.querySelector(".MuiCollapse-root")?.style?.height !== "0px"; - -const openAll = async () => { - const container = document.querySelectorAll(".app__content .MuiPaper-root"); - for (const element of container) { - if (!isOpened(element)) - element.querySelector(".accordion__full-width__header h2")?.click(); - await waitForRender(() => isOpened(element), element); - } -}; - -const mapStartingHours = (data) => { - const all = new Set(); - for (const day of data) - if (day.lessons) - for (const lesson of day.lessons) - if (lesson.startingHour) all.add(lesson.startingHour); - const result = [...all].sort(); - const [firstHour, firstMinutes] = (result[0] || "08:00").split(":"); - return Number(firstHour) <= 7 && Number(firstMinutes) <= 30 - ? result - : ["7:00", ...result]; -}; - -const getStartingHours = () => - JSON.parse(localStorage.getItem("startingHours") || "[]"); - -const renderDay = async (data) => { - await openAll(); - - if (!data.note) { - await waitForRender(() => - document.querySelector(".details-btn--position-r-bottom"), - ); - } - - const startingHours = getStartingHours(); - const lessons = mapDay(data.element); - const element = document.createElement("section"); - element.classList.add("timetable"); - - if (lessons.length < 1) { - const infoElement = document.createElement("div"); - infoElement.innerHTML = - "
Nie ma lekcji 😎
"; - if (data.note) - infoElement.querySelector("span:last-of-type").innerText = - data.note; - element.appendChild(infoElement); - } else { - for (const lesson of lessons) { - const lessonElement = document.createElement("div"); - lessonElement.innerHTML = ` -
${startingHours.findIndex((h) => h === lesson.startingHour)}
-
-
-
-
- `; - const lessonDataElement = lessonElement.querySelector(".data"); - - const timeContainer = lessonElement.querySelector(".info"); - timeContainer.firstElementChild.innerText = lesson.startingHour; - timeContainer.lastElementChild.innerText = lesson.endingHour; - - lessonElement.classList.add("lesson"); - lessonElement.classList.add(lesson.type); - - if (lesson.type === "conflicted") { - lessonDataElement.innerHTML = ` -
Wpisana jest więcej niż jedna lekcja
-
Kliknij, aby wyświetlić
- `; - } else { - lessonDataElement.innerHTML = `
`; - lessonDataElement.querySelector(".subject").innerText = - lesson.subject; - lessonDataElement.querySelector(".additional-info").innerText = - `${lesson.classroom} ${lesson.teacher?.split(" ")?.reverse()?.join(" ")}`; - } - - lessonElement.addEventListener("click", () => - lesson.originalElement.querySelector("button").click(), - ); - element.appendChild(lessonElement); - } - } - - return element; -}; - -const run = async () => { - document.querySelector( - "section.app__content .app__content__header", - ).style.display = "none"; - document.querySelector( - "section.app__content .mobile__frame > div", - ).style.display = "none"; - - await openAll(); - localStorage.setItem( - "startingHours", - JSON.stringify(mapStartingHours(mapData())), - ); - - new SelectorRenderer(renderDay); -}; - -const isLoaded = () => - document.querySelector(".app__content .MuiCollapse-root")?.style - ?.minHeight && - document.querySelector("section.app__content .mobile__frame .plan-zajec") && - !document.querySelector(".spinner") && - document.querySelector( - ".position__lesson__hours, .conflicted--details--hours", - ); - -window.appendModule({ - isLoaded, - onlyOnReloads: false, - run, - doesRunHere: () => window.location.pathname.endsWith("planZajec"), -}); diff --git a/app/src/main/assets/ifv/patches/newTimetable/styles.css b/app/src/main/assets/ifv/patches/newTimetable/styles.css deleted file mode 100644 index d60256c..0000000 --- a/app/src/main/assets/ifv/patches/newTimetable/styles.css +++ /dev/null @@ -1,111 +0,0 @@ -:root { - --background-primary: light-dark(white, #0b1517); - --background-navigation: light-dark(white, #152528); -} - -body { - color-scheme: only light; -} - -.app__main { - background: var(--background-primary) !important; - height: auto; -} - -.timetable { - padding: 0 !important; - margin-inline: 10px !important; -} - -.timetable:not(:has(.lesson)) { - display: flex; - justify-content: center; - align-items: center; - height: calc(100svh - 62px - 40px - 20px - var(--bottom-navbar-height)); - text-align: center; -} - -.timetable .no-lessons-title { - font-size: 24px; -} - -.timetable .lesson { - display: flex; - margin-bottom: 5px; - line-height: 16px; -} - -.lesson > div:first-of-type { - font-size: 30px; - display: flex; - align-items: center; - color: light-dark(#1b1b1f, #f5feff); - min-width: 18px; -} - -.lesson > article { - display: flex; - padding: 15px; - align-content: center; - border-radius: 10px; - width: 100%; - margin-left: 10px; - cursor: pointer; - background: light-dark(#efedf1, #192123); - overflow: hidden; -} - -.lesson .subject { - color: light-dark(#1b1b1f, #dbe4e7); - font-size: 13px; - overflow: hidden; - text-overflow: ellipsis; - text-wrap: nowrap !important; -} - -.lesson .data { - overflow: inherit; -} - -.lesson .info { - display: flex; - flex-direction: column; - margin-right: 10px; - color: #a1aaac; -} - -.lesson .additional-info { - color: #a1aaac; - font-size: smaller; -} - -.lesson.canceled > article { - background: light-dark(#f9dedc, #8c1d18); -} - -.lesson.canceled .subject { - text-decoration: line-through; - color: light-dark(#410e0b, #f9dedc); -} - -.lesson.canceled .info, -.lesson.canceled .additional-info { - color: light-dark(#784c4a, #d9a5a1); -} - -.lesson.canceled > div:first-of-type { - color: light-dark(#b3261e, #f2b8b5); -} - -.lesson.substitute > article { - background: light-dark(#e7e4bd, #65683c); -} - -.lesson.substitute .info, -.lesson.substitute .additional-info { - color: light-dark(#58574e, #b8bfb4); -} - -.lesson.substitute > div:first-of-type { - color: light-dark(#6d5e0f, #65683c); -} diff --git a/app/src/main/assets/ifv/patches/pwa.js b/app/src/main/assets/ifv/patches/pwa.js deleted file mode 100644 index 2e4987c..0000000 --- a/app/src/main/assets/ifv/patches/pwa.js +++ /dev/null @@ -1,35 +0,0 @@ -function injectWebManifest() { - const metaLink = document.createElement("link"); - - metaLink.setAttribute("rel", "manifest"); - metaLink.setAttribute("href", getManifestLink(window.location.hostname)); - - document.head.appendChild(metaLink); -} - -function getManifestLink(hostname) { - switch (hostname) { - case "eduvulcan.pl": - return "https://raw.githubusercontent.com/banocean/ifv/main/pwa/manifest-eduvulcan.json"; - case "uczen.eduvulcan.pl": - return `https://ifv-pwa.banocean.com/eduvulcan/${ - window.location.pathname.split("/")[1] - }`; - case "dziennik-uczen.vulcan.net.pl": - return `https://ifv-pwa.banocean.com/dziennik/${ - window.location.pathname.split("/")[1] - }`; - } -} - -window.appendModule({ - isLoaded: () => true, - onlyOnReloads: true, - run: injectWebManifest, - doesRunHere: () => - [ - "eduvulcan.pl", - "uczen.eduvulcan.pl", - "dziennik-uczen.vulcan.net.pl", - ].includes(window.location.hostname), -}); diff --git a/app/src/main/assets/ifv/patches/redirectToBoard/script.js b/app/src/main/assets/ifv/patches/redirectToBoard/script.js deleted file mode 100644 index 6e92be0..0000000 --- a/app/src/main/assets/ifv/patches/redirectToBoard/script.js +++ /dev/null @@ -1,33 +0,0 @@ -import { clickOnAside } from "../apis/aside.js"; - -const isEduVulcan = () => !window.location.hostname.startsWith("dziennik"); - -const getLogoElement = () => - document.querySelector(".header__logo-product")?.firstChild; - -function setUpRedirectToBoard() { - const logoElement = getLogoElement(); - if (!!window.location.hostname.match(/^(dziennik-)?wiadomosci.*/)) { - const url = `https://${window.location.hostname.replace( - "wiadomosci", - "uczen" - )}/${window.location.pathname.split("/")[1]}/App`; - - if (isEduVulcan()) logoElement.href = url; - else { - logoElement.onclick = () => (window.location.href = url); - logoElement.style = "cursor: pointer;"; - } - } else { - if (isEduVulcan()) logoElement.href = "javascript:void(0)"; - else logoElement.style = "cursor: pointer;"; - logoElement.addEventListener("click", () => clickOnAside(".tablica a")) - } -} - -window.appendModule({ - isLoaded: getLogoElement, - onlyOnReloads: true, - run: setUpRedirectToBoard, - doesRunHere: () => !!window.location.hostname.match(/^(dziennik-)?(wiadomosci|uczen).*/) -}) diff --git a/app/src/main/assets/ifv/patches/redirectToBoard/styles.css b/app/src/main/assets/ifv/patches/redirectToBoard/styles.css deleted file mode 100644 index dbddce5..0000000 --- a/app/src/main/assets/ifv/patches/redirectToBoard/styles.css +++ /dev/null @@ -1,3 +0,0 @@ -.app.hideAside aside { - display: none; -} \ No newline at end of file diff --git a/app/src/main/assets/ifv/patches/redirectToDVLogin.js b/app/src/main/assets/ifv/patches/redirectToDVLogin.js deleted file mode 100644 index 794431d..0000000 --- a/app/src/main/assets/ifv/patches/redirectToDVLogin.js +++ /dev/null @@ -1,26 +0,0 @@ -function redirectToLoginPage() { - window.location.pathname = `/${ - window.location.pathname.split("/")[1] - }/LoginEndpoint.aspx`; -} - -window.appendModule({ - onlyOnReloads: true, - run: redirectToLoginPage, - doesRunHere: () => - window.location.hostname === "dziennik-uczen.vulcan.net.pl" && - !window.location.pathname.split("/")[2], -}); - -const pathSegment = window.location.pathname.split("/")[1]; - -const targetSpan = document.querySelector( - ".input-components ~ .form-gap > span" -); - -if (targetSpan) { - const spanText = targetSpan.textContent; - const newText = spanText.slice(0, -1); - const additionalText = ` lub użyj innej metody logowania`; - targetSpan.innerHTML = `${newText}${additionalText}`; -} diff --git a/app/src/main/assets/ifv/patches/redirectToEVLogin.js b/app/src/main/assets/ifv/patches/redirectToEVLogin.js deleted file mode 100644 index 918edf3..0000000 --- a/app/src/main/assets/ifv/patches/redirectToEVLogin.js +++ /dev/null @@ -1,12 +0,0 @@ -function redirectToLoginPage() { - window.location.pathname = "/logowanie"; -} - -window.appendModule({ - onlyOnReloads: true, - run: redirectToLoginPage, - doesRunHere: () => - window.location.hostname === "eduvulcan.pl" - && window.location.pathname === "/" - && !!document.querySelector("#panelLoginButton") -}); diff --git a/app/src/main/assets/ifv/popup/index.html b/app/src/main/assets/ifv/popup/index.html deleted file mode 100644 index f0ee43c..0000000 --- a/app/src/main/assets/ifv/popup/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - -

Improvements for Vulcan

-

Changing any option below will refresh opened pages.
We are not affiliated, associated, authorized, endorsed by, or in any way officially connected with VULCAN sp. z o.o., or any of its subsidiaries or its affiliates.

-
- - - - diff --git a/app/src/main/assets/ifv/popup/main.js b/app/src/main/assets/ifv/popup/main.js deleted file mode 100644 index 8fc08c8..0000000 --- a/app/src/main/assets/ifv/popup/main.js +++ /dev/null @@ -1,41 +0,0 @@ -const fetchPatches = async () => { - const patchesResponse = await fetch(chrome.runtime.getURL("patches.json")); - return await patchesResponse.json(); -}; - -if (/\bMobile\b/.test(navigator.userAgent)) document.body.classList.add("mobile") - -document.addEventListener("DOMContentLoaded", async () => { - let config = (await chrome.storage.sync.get("options"))?.options ?? {}; - const patches = await fetchPatches(); - - patches.forEach((patch) => { - if (config[patch.name] !== undefined) return; - config[patch.name] = { description: patch.description, enable: true }; - }); - chrome.storage.sync.set({ options: config }); - - const optionsDOM = document.querySelector(".options"); - for (const [key, value] of Object.entries(config)) { - const option = document.createElement("label"); - option.innerHTML = ` -
-

${key}

-

${value.description}

-
-
- -
-
- `; - option.querySelector("input").id = key - optionsDOM.appendChild(option); - } - optionsDOM.addEventListener("change", async (e) => { - const target = e.target; - if (target.tagName === "INPUT") { - config[target.id].enable = target.checked; - await chrome.storage.sync.set({ options: config }); - } - }); -}); diff --git a/app/src/main/assets/ifv/popup/style.css b/app/src/main/assets/ifv/popup/style.css deleted file mode 100644 index 8ac08d1..0000000 --- a/app/src/main/assets/ifv/popup/style.css +++ /dev/null @@ -1,122 +0,0 @@ -body { - background: #18181b; - font-family: Cantarell, Arial, sans-serif; - color: white; - width: 350px; - padding: 10px; -} - -body.mobile { - width: 100% !important; -} - -/* Main */ - -h1 { - margin: 5px 0; - color: #fafafa; - text-align: center; -} - -h2 { - color: #d4d4d8; - font-size: small; - font-weight: normal; - text-align: center; -} - -.options { - display: flex; - flex-direction: column; - gap: 8px; -} - -/* Option */ - -label { - display: flex; - justify-content: space-between; - align-items: center; - margin: 2px 0; - padding: 10px; - border-radius: 7px; - background: #27272a; - gap: 10px; - cursor: pointer; -} - -label .desc { - margin: 5px 0 0 0; - font-size: 14px; - color: #a1a1aa; - line-height: 16px; -} - -label .title { - font-size: 15px; - color: #f4f4f5; - line-height: 18px; - font-weight: 500; - margin: 0; -} - -/* Toggle */ -/* https://uiverse.io/ClawHack1/itchy-bobcat-18 */ - -.toggle-wrapper { - position: relative; - display: inline-block; - width: 40px; - height: 24px; -} - -.toggle-wrapper .toggle-switch { - position: absolute; - top: 0; - left: 0; - width: 40px; - height: 24px; - background-color: #52525b; - border-radius: 34px; - cursor: pointer; - transition: background-color 0.3s; -} - -.toggle-wrapper .toggle-switch::before { - content: ""; - position: absolute; - width: 20px; - height: 20px; - border-radius: 50%; - top: 2px; - left: 2px; - background-color: #fff; - box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.3); - transition: transform 0.3s; -} - -.toggle-wrapper .toggle-input:checked + .toggle-switch::before { - transform: translateX(16px); -} - -.toggle-wrapper .toggle-input:checked + .toggle-switch { - background-color: #16a34a; -} - -.toggle-wrapper .toggle-input:checked + .toggle-switch::before { - transform: translateX(16px); -} - -/* Footer */ - -.footer { - padding: 10px; - display: flex; - justify-content: center; - align-items: center; - gap: 20px; -} - -.footer a { - color: #a1a1aa; -} diff --git a/app/src/main/assets/ifv/pwa/manifest-eduvulcan.json b/app/src/main/assets/ifv/pwa/manifest-eduvulcan.json deleted file mode 100644 index 95ff903..0000000 --- a/app/src/main/assets/ifv/pwa/manifest-eduvulcan.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "eduVULCAN", - "short_name": "eduVULCAN", - "start_url": "https://eduvulcan.pl/", - "display": "standalone", - "orientation": "portrait", - "background_color": "#006BD6", - "icons": [ - { - "src": "https://raw.githubusercontent.com/BanOcean/ifv/main/assets/logo/logo-128-blue.png", - "sizes": "128x128", - "type": "image/png" - }, - { - "src": "https://raw.githubusercontent.com/BanOcean/ifv/main/assets/logo/logo-192-blue.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "https://raw.githubusercontent.com/BanOcean/ifv/main/assets/logo/logo-512-blue.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "splash_pages": null, - "prefer-related-application": false - } \ No newline at end of file diff --git a/app/src/main/java/dev/andus/niedu/MainActivity.kt b/app/src/main/java/dev/andus/niedu/MainActivity.kt index 80ae5f5..fb1f924 100644 --- a/app/src/main/java/dev/andus/niedu/MainActivity.kt +++ b/app/src/main/java/dev/andus/niedu/MainActivity.kt @@ -1,8 +1,6 @@ package dev.andus.niedu import android.content.SharedPreferences -import android.content.Intent -import android.net.Uri import android.os.Bundle import org.mozilla.geckoview.GeckoRuntime import org.mozilla.geckoview.GeckoSession @@ -25,6 +23,7 @@ class MainActivity : AppCompatActivity() { private var baseUrl: String? = null private var symbol: String? = null private var journalType: String? = null + val navigationDelegate = MyNavigationDelegate(this) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -47,7 +46,7 @@ class MainActivity : AppCompatActivity() { showJournalTypeDialog() } - installIfv() + installExtensions() loadLoginPage() } @@ -62,31 +61,13 @@ class MainActivity : AppCompatActivity() { geckoSession = GeckoSession(settings) - geckoSession.contentDelegate = object : GeckoSession.ContentDelegate { - override fun onLoadRequest( - session: GeckoSession, - request: GeckoSession.ContentDelegate.LoadRequest - ): GeckoSession.ContentDelegate.LoadResponse? { - if (!request.isRedirect && request.uri != null) { - openInExternalBrowser(request.uri!!) - return GeckoSession.ContentDelegate.LoadResponse.CANCEL - } - return null - } - } + geckoSession.navigationDelegate = navigationDelegate geckoSession.open(runtime) geckoView.setSession(geckoSession) } - - - private fun openInExternalBrowser(url: String) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) - startActivity(intent) - } - - private fun installIfv() { + private fun installExtensions() { runtime.webExtensionController.ensureBuiltIn( "resource://android/assets/ifv/", "j.skup.test@gmail.com" @@ -183,4 +164,4 @@ class MainActivity : AppCompatActivity() { geckoSession.close() super.onDestroy() } -} +} \ No newline at end of file diff --git a/app/src/main/java/dev/andus/niedu/MyNavigationDelegate.kt b/app/src/main/java/dev/andus/niedu/MyNavigationDelegate.kt index 216b6ba..ead3aa8 100644 --- a/app/src/main/java/dev/andus/niedu/MyNavigationDelegate.kt +++ b/app/src/main/java/dev/andus/niedu/MyNavigationDelegate.kt @@ -1,13 +1,31 @@ package dev.andus.niedu +import android.content.Context +import android.net.Uri +import androidx.browser.customtabs.CustomTabsIntent +import org.mozilla.geckoview.AllowOrDeny +import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoSession +import org.mozilla.geckoview.GeckoSession.NavigationDelegate -class MyNavigationDelegate : GeckoSession.NavigationDelegate { +class MyNavigationDelegate(private val context: Context) : NavigationDelegate { var canGoBack: Boolean = false override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) { this.canGoBack = canGoBack } -} -val navigationDelegate = MyNavigationDelegate() \ No newline at end of file + override fun onLoadRequest(session: GeckoSession, request: NavigationDelegate.LoadRequest): GeckoResult { + if (request.target == NavigationDelegate.TARGET_WINDOW_NEW) { + var uri = request.uri + + val intent = CustomTabsIntent.Builder() + .setShowTitle(true) + .setUrlBarHidingEnabled(true) + .build() + intent.launchUrl(context, Uri.parse(uri)) + } + + return GeckoResult.fromValue(AllowOrDeny.ALLOW) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed351ea..bd90950 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] agp = "8.7.0" geckoview = "133.0.20241209150345" +andXbrowser = "1.8.0" kotlin = "2.0.0" coreKtx = "1.10.1" junit = "4.13.2" @@ -15,6 +16,7 @@ material = "1.12.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } geckoview = { module = "org.mozilla.geckoview:geckoview", version.ref = "geckoview" } +androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "andXbrowser" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }