Compare commits

..

1 commit

Author SHA1 Message Date
ce6c0fb270 Update README.md 2025-04-03 17:43:56 +00:00
30 changed files with 12 additions and 2899 deletions

4
.gitignore vendored
View file

@ -90,6 +90,7 @@ out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
@ -129,6 +130,3 @@ out
.yarn/install-state.gz
.pnp.*
# Mock hiding
public/mock/*
!public/mock/notice.txt

View file

@ -1,3 +0,0 @@
{
"recommendations": ["Vue.volar"]
}

1105
Bridge-mock-APIs.d.ts vendored

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
# SpringBoard-like
# BLHS
Bridge Launcher Home Screens I made for myself but published for no reason
A Brige Launcher Project inspired by SpringBoard, iOS default launcher,
# How to install
1. **Go to Branches** -> (select any EXCEPT `template`)
2. **Go to Release**
3. **Download** the source code `.zip` file
4. **Unarchive** the downloaded `.zip` file into any directory
> Note: You only need `dist` folder from there, you can safely delete everything else
5. **Open Bridge Launcher** and go to settings to **choose the `dist` folder from unarchived the `.zip` file as the Project Folder**
# Screenshots
*none because still in development*
# Customizing dock apps
1. Open [Dock.vue](src/components/Dock.vue)
2. On your phone (or dev env), select the *invisible* text below the icon's label name. Copy it fully.
> Note: Thats the **Package name** of the app you want to pin on the dock
3. Put the wanted app's package name instead of the default one
# License
[MIT](LICENSE)

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
dist/bundle.zip vendored

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

65
dist/error.svg vendored
View file

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="150 240 165 165"
version="1.1"
id="svg2"
sodipodi:docname="dotgrid-25G10-623290.svg"
width="165"
height="165"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="false"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:clip-to-page="false"
inkscape:antialias-rendering="true"
showborder="true"
inkscape:zoom="3.608628"
inkscape:cx="47.38643"
inkscape:cy="80.501509"
inkscape:window-width="1920"
inkscape:window-height="1014"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<!-- Filled triangle -->
<path
stroke-width="15.0001"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#ff8888"
fill="#ff8888"
d="M 157.49952,389.99997 H 307.50049 L 232.5,254.99926 Z"
id="path1" />
<path
stroke-width="15"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#000000"
fill="none"
d="m 232.49948,283.49921 v 60"
id="path2" />
<circle
cx="232.56358"
cy="371.59991"
stroke="rgb(255,136,136)"
stroke-width="7.50004"
fill="rgb(0,0,0)"
id="circle2"
style="fill:#000000;fill-opacity:1;stroke:none"
r="7.5" />
<!-- Vertical line -->
<!-- Circle below the vertical line -->
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

14
dist/index.html vendored
View file

@ -1,14 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SpringBoard</title>
<script type="module" crossorigin src="/assets/index-mum_jNSN.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-_sk3xYAV.css">
</head>
<body style="background-color:transparent;">
<div id="app"></div>
</body>
</html>

1
dist/vite.svg vendored
View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

1
dist/vue.svg vendored
View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

View file

@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SpringBoard</title>
</head>
<body style="background-color:transparent;">
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View file

@ -1,29 +0,0 @@
{
"name": "blhs",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && rm -rf dist/mock",
"preview": "vite preview",
"zip": "zip -r dist/bundle.zip dist/"
},
"dependencies": {
"@bridgelauncher/api-mock": "^0.1.0",
"bootstrap-icons": "^1.11.3",
"fuzzy": "^0.1.3",
"vue": "^3.5.13"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"sass": "^1.86.2",
"vite": "^6.2.0"
},
"packageManager": "pnpm@10.6.1+sha512.40ee09af407fa9fbb5fbfb8e1cb40fbb74c0af0c3e10e9224d7b53c7658528615b2c92450e74cfad91e3a2dcafe3ce4050d80bda71d757756d2ce2b66213e9a3",
"pnpm": {
"onlyBuiltDependencies": [
"@parcel/watcher"
]
}
}

1033
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="150 240 165 165"
version="1.1"
id="svg2"
sodipodi:docname="dotgrid-25G10-623290.svg"
width="165"
height="165"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="false"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:clip-to-page="false"
inkscape:antialias-rendering="true"
showborder="true"
inkscape:zoom="3.608628"
inkscape:cx="47.38643"
inkscape:cy="80.501509"
inkscape:window-width="1920"
inkscape:window-height="1014"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<!-- Filled triangle -->
<path
stroke-width="15.0001"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#ff8888"
fill="#ff8888"
d="M 157.49952,389.99997 H 307.50049 L 232.5,254.99926 Z"
id="path1" />
<path
stroke-width="15"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#000000"
fill="none"
d="m 232.49948,283.49921 v 60"
id="path2" />
<circle
cx="232.56358"
cy="371.59991"
stroke="rgb(255,136,136)"
stroke-width="7.50004"
fill="rgb(0,0,0)"
id="circle2"
style="fill:#000000;fill-opacity:1;stroke:none"
r="7.5" />
<!-- Vertical line -->
<!-- Circle below the vertical line -->
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,9 +0,0 @@
This is the mock folder, put your `icons` folder and `apps.json` in the folder where this file is located
How to obtain? (you may ask)
1. Open Bridge Launcher
2. Open it's Settings
3. Scroll down to 'development'
4. Click 'Export'
5. Select any path
6. Transfer the needed files (`icons` folder and `apps.json`) here

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

View file

@ -1,57 +0,0 @@
<template>
<div id="applist-wrapper">
<Suspense>
<template #default>
<div id="applist">
<div class="applist-page" v-for="(page, index) in paginatedApps" :key="index">
<AppIcon v-for="app in page" :key="app.packageName" :packageName="app.packageName" :label="app.label" />
</div>
<div class="applist-page" v-if="paginatedApps.length > 0">
<Settings></Settings>
</div>
</div>
</template>
</Suspense>
</div>
<div id="dock-wrapper">
<Search></Search>
<Dock></Dock>
</div>
</template>
<script setup>
import { ref, computed, onUnmounted } from 'vue';
import AppIcon from './components/AppIcon.vue';
import Dock from './components/Dock.vue';
import Search from './components/Search.vue';
import Settings from './components/Settings.vue';
const apps = ref([])
async function loadApps() {
const resp = await fetch(Bridge.getAppsURL())
const data = await resp.json()
apps.value = data.apps.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))
window.springboard.apps = apps.value;
}
loadApps()
let lastUpdate = 0;
function updateApps() {
const now = performance.now();
if (now - lastUpdate >= 100) {
loadApps();
lastUpdate = now;
}
requestAnimationFrame(updateApps);
}
updateApps();
const itemsPerPage = 4 * 6;
const paginatedApps = computed(() => {
return Array(Math.ceil(apps.value.length / itemsPerPage)).fill().map((_, index) => {
return apps.value.slice(index * itemsPerPage, (index + 1) * itemsPerPage);
});
})
</script>

View file

@ -1,99 +0,0 @@
<script setup>
import { defineProps, ref } from 'vue'
const props = defineProps({
packageName: {
type: String,
required: true,
},
label: {
type: String,
required: false,
default: "UNSETLABEL"
},
hideLabel: {
type: Boolean,
required: false,
}
})
let darkLabel
if (Bridge.getSystemNightMode() == 'yes') {
darkLabel = true;
} else {
darkLabel = false;
}
const icon = ref('');
icon.value = await Bridge.getDefaultAppIconURL(props.packageName);
const label = ref('')
if (props.label.length >= 12) {
label.value = `${props.label.slice(0, 12 - 3).trim()}...`;
} else {
label.value = props.label;
}
function handleClick() {
Bridge.requestLaunchApp(props.packageName);
}
async function loadIcon() {
const iconsrc = await Bridge.getDefaultAppIconURL(props.packageName);
const img = new Image();
img.src = iconsrc;
img.onload = () => {
icon.value = iconsrc;
};
img.onerror = () => {
if (icon.value != '/error.svg') icon.value = '/error.svg';
setTimeout(loadIcon, 100);
};
}
loadIcon();
</script>
<template>
<div
class="app-icon"
@click="handleClick()"
:style="{ '--label-color': darkLabel ? '#000000' : '#ffffff' }"
>
<img :src="icon" :alt="label" class="app-image">
<span v-if="!props.hideLabel" class="app-label">{{ label }}</span>
<span v-if="!props.hideLabel" class="app-package">{{ props.packageName }}</span>
</div>
</template>
<style scoped>
.app-icon {
display: flex;
align-items: center;
flex-direction: column;
width: max-content;
height: max-content;
.app-icon > *:nth-child(n+2) {
padding-bottom: 10px;
}
}
.app-image {
width: 14vw;
height: auto;
border-radius: 12px;
}
.app-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 10pt;
color: var(--label-color);
}
.app-package {
font-size: 1px;
color: #00000000;
}
</style>

View file

@ -1,14 +0,0 @@
<script setup>
import AppIcon from './AppIcon.vue'
</script>
<template>
<Suspense>
<div id="dock">
<AppIcon packageName="app.revenge" :hideLabel="true"/>
<AppIcon packageName="com.radolyn.ayugram" :hideLabel="true"/>
<AppIcon packageName="org.mozilla.fennec_fdroid" :hideLabel="true"/>
<AppIcon packageName="org.akanework.gramophone" :hideLabel="true"/>
</div>
</Suspense>
</template>

View file

@ -1,152 +0,0 @@
<template>
<Suspense>
<div id="search_background">
<div class="section" id="search_results">
<AppIcon
v-for="(app, index) in filteredApps"
:key="app.packageName || index"
:packageName="app.packageName"
:label="app.label"
/>
</div>
</div>
</Suspense>
<div id="search_maindiv">
<input
type="text"
@focus="openSearch"
placeholder="Search"
>
<i class="bi bi-x-circle"></i>
</div>
</template>
<script setup>
import { ref } from 'vue';
import fuzzy from 'fuzzy';
import AppIcon from './AppIcon.vue';
const filteredApps = ref([]);
function openSearch() {
const inputElement = document.querySelector('#search_maindiv input');
const backgroundElement = document.querySelector('#search_background');
function handleInput() {
const value = inputElement.value.toString();
const apps = window.springboard.apps || [];
const searchList = apps.map(app => app.label);
const results = fuzzy.filter(value, searchList);
filteredApps.value = results
.slice(0, 8)
.map(result => apps[result.index]);
}
if (!inputElement.hasAttribute('data-added')) {
inputElement.addEventListener('input', handleInput);
inputElement.addEventListener('blur', async () => {
await new Promise(resolve => setTimeout(resolve, 100));
inputElement.value = '';
backgroundElement.style.opacity = '0';
backgroundElement.style.pointerEvents = 'none';
inputElement.removeEventListener('input', handleInput);
filteredApps.value = [];
inputElement.removeAttribute('data-added');
});
inputElement.setAttribute('data-added', 'true');
}
backgroundElement.style.opacity = '1';
backgroundElement.style.pointerEvents = 'all';
}
</script>
<style lang="scss" scoped>
@import 'bootstrap-icons/font/bootstrap-icons.css';
#search_results {
scroll-snap-align: center;
display: grid;
grid-template-columns: repeat(4, 25%);
grid-template-rows: repeat(2, 50%);
place-items: center;
align-items: start;
}
#search_background {
position: fixed;
opacity: 0;
pointer-events: none;
z-index: 99;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.25);
padding: 5%;
transition: opacity 0.25s ease-in-out;
}
#search_maindiv {
z-index: 999;
width: 25% !important;
border: none;
border: 1px solid white;
border-radius: 300px;
padding: 2% 4%;
background-color: rgba(0,0,0,0.25);
color: white;
margin-bottom: 3%;
display: flex;
transition: all 0.1s ease-in-out;
&:has(input:focus) {
transition: all 0.25s ease-in-out;
transform:translateY(-550%);
width: 80% !important;
& > i {
transition: all 0.5s ease-in-out;
opacity: 0.5;
pointer-events: all;
width: max-content;
}
& > input {
text-align: left;
}
}
&:has(input:not(:placeholder-shown)) {
& > i {
opacity: 1 !important;
}
}
}
input {
background-color: transparent;
border: none;
outline: none;
color: white;
width: 100% !important;
text-align: center;
&::placeholder {
color: white;
}
&:focus {
&::placeholder {
color: transparent;
}
}
}
i {
position: relative;
right: 0;
opacity: 0.0;
transition: all 0.25s ease-in-out;
pointer-events: none;
width: 0;
color: white !important;
}
</style>

View file

@ -1,72 +0,0 @@
<script setup>
import { ref } from 'vue';
function toggleBridgeButton() {
console.log('Changed Bridge Button visibility to...')
if (Bridge.getBridgeButtonVisibility() == 'shown') {
Bridge.requestSetBridgeButtonVisibility('hidden');
console.log('hidden');
} else {
Bridge.requestSetBridgeButtonVisibility('shown');
console.log('shown');
}
}
function toggleSystemWallpapers() {
console.log('Changed draw system wallpapers to...')
if (Bridge.getDrawSystemWallpaperBehindWebViewEnabled()) {
Bridge.requestSetDrawSystemWallpaperBehindWebViewEnabled(false);
document.body.style.backgroundColor = '';
console.log('false');
} else {
Bridge.requestSetDrawSystemWallpaperBehindWebViewEnabled(true);
console.log('true');
document.body.style.backgroundColor = 'transparent';
}
}
function toggleOverscrolling() {
console.log('Changed overscrolling effect to...')
if (Bridge.getOverscrollEffects == 'default') {
Bridge.requestSetOverscrollEffects('none');
console.log('none');
} else {
Bridge.requestSetOverscrollEffects('default');
console.log('default');
}
}
function openBridgeAppDrawer() {
Bridge.requestOpenBridgeAppDrawer();
}
function reloadWindow() {
window.location.reload();
}
</script>
<template>
<div class="section">
<button class="ui-button" @click="toggleBridgeButton()">Toggle Bridge button</button>
<button class="ui-button" @click="openBridgeAppDrawer()">Open Bridge App Drawer</button>
<button class="ui-button" @click="toggleSystemWallpapers()">Toggle system wallpaper visibility</button>
<button class="ui-button" @click="toggleOverscrolling()">Toggle overscrolling</button>
<button class="ui-button" @click="reloadWindow()">Reload</button>
<br>
<small style="font-size:xx-small;">Everything else can be configured through Bridge's Settings</small>
</div>
<div class="section" style="display:flex;flex-direction:column;align-items: center;">
<span style="width:max-content;">Made with</span>
<div style="display:flex;justify-content:space-around;width:100%;">
<img src="/vite.svg">
<img src="/vue.svg">
<img src="/com.tored.bridgelauncher.png" alt="Bridge">
</div>
</div>
</template>
<style scoped>
img {
width: 15%;
height: auto;
}
</style>

View file

@ -1,20 +0,0 @@
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import { BridgeMock } from '@bridgelauncher/api-mock';
if (!window.Bridge) {
window.Bridge = new BridgeMock({
appsUrl: '/mock/apps.json',
makeGetDefaultIconUrl: (packageName) => `/mock/icons/default/${packageName}.png`,
});
}
Bridge.requestSetBridgeTheme('system');
window.springboard = {
apps: [],
labelColor: 'ffffff'
}
createApp(App).mount('#app')

View file

@ -1,90 +0,0 @@
body {
margin: 0;
padding: 0;
background-color: #808080;
}
* {
box-sizing: border-box;
}
#applist {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-snap-stop: always;
}
#applist-wrapper {
width: 100%;
}
.applist-page {
scroll-snap-align: center;
display: grid;
grid-template-columns: repeat(4, 25%);
grid-template-rows: repeat(5, 20%);
place-items: center;
align-items: start;
min-width: 100vw;
max-width: 100vw;
width: 100vw;
padding-bottom: 25%;
padding-top: 5%;
& > *:not(.section) {
width: auto;
margin-bottom: 5%;
display: flex;
flex-direction: column;
align-items: center;
}
&:has(.section) {
display: flex;
flex-direction: column;
align-items: center;
padding: 5%;
gap: 5%;
}
}
#dock-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 5%;
}
#dock {
padding: 5%;
gap: 15px;
border-radius: 24px;
background-color: rgba(0,0,0,0.25);
border: 1px solid white;
display: flex;
justify-content: center;
width: 100%;
}
.section {
padding: 5%;
border-radius: 15px;
background-color: rgba(0,0,0,0.5);
border: 1px solid white;
width: 100%;
color: white;
}
.ui-button {
border: none;
border: 1px solid white;
border-radius: 6px;
padding: 2%;
background-color: rgba(0,0,0,0.5);
color: white;
margin: 1%;
}

View file

@ -1,19 +0,0 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import sass from 'sass';
// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
sass: {
implementation: sass,
},
},
},
build: {
outDir: 'dist',
emptyOutDir: true,
},
})