Compare commits

..

No commits in common. "springboard-like" and "v1" have entirely different histories.

22 changed files with 60 additions and 449 deletions

Binary file not shown.

Binary file not shown.

1
dist/assets/index-Byzfhg1j.css vendored Normal file
View file

@ -0,0 +1 @@
body{margin:0;padding:0;box-sizing:border-box;background-color:gray}#applist{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-snap-stop:always}#applist-wrapper{width:100%}.applist-page{scroll-snap-align:start;display:flex;flex-direction:row;flex-wrap:wrap;min-width:100vw;justify-content:flex-start;align-content:flex-start;padding-bottom:10%;padding-top:5%}.applist-page>*{min-width:25%;margin-bottom:5%}#dock{padding:5%;margin:5%;gap:15px;border-radius:24px;background-color:#00000040;border:1px solid white;display:flex;justify-content:center;position:fixed;bottom:0;left:0;right:0}.section{padding:5%;margin:0 5% 5%;border-radius:15px;background-color:#00000040;border:1px solid white;width:100%}.ui-button{border:none;border:1px solid white;border-radius:6px;padding:2%;background-color:#00000080;color:#fff;margin:1%}.app-icon[data-v-fa001907]{display:flex;align-items:center;flex-direction:column;width:max-content;height:max-content}.app-icon .app-icon[data-v-fa001907]>*:nth-child(n+2){padding-bottom:10px}.app-image[data-v-fa001907]{width:60px;height:60px;border-radius:12px}.app-label[data-v-fa001907]{font-size:12px;color:var(--label-color)}.app-package[data-v-fa001907]{font-size:3px;color:#0000}

17
dist/assets/index-C4iP7xdQ.js vendored Normal file

File diff suppressed because one or more lines are too long

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

6
dist/index.html vendored
View file

@ -5,10 +5,10 @@
<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">
<script type="module" crossorigin src="/assets/index-C4iP7xdQ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Byzfhg1j.css">
</head>
<body style="background-color:transparent;">
<body>
<div id="app"></div>
</body>
</html>

View file

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SpringBoard</title>
</head>
<body style="background-color:transparent;">
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>

View file

@ -5,14 +5,11 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && rm -rf dist/mock",
"preview": "vite preview",
"zip": "zip -r dist/bundle.zip dist/"
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@bridgelauncher/api-mock": "^0.1.0",
"bootstrap-icons": "^1.11.3",
"fuzzy": "^0.1.3",
"vue": "^3.5.13"
},
"devDependencies": {

17
pnpm-lock.yaml generated
View file

@ -11,12 +11,6 @@ importers:
'@bridgelauncher/api-mock':
specifier: ^0.1.0
version: 0.1.0
bootstrap-icons:
specifier: ^1.11.3
version: 1.11.3
fuzzy:
specifier: ^0.1.3
version: 0.1.3
vue:
specifier: ^3.5.13
version: 3.5.13(typescript@5.8.2)
@ -430,9 +424,6 @@ packages:
'@vue/shared@3.5.13':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
bootstrap-icons@1.11.3:
resolution: {integrity: sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
@ -470,10 +461,6 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fuzzy@0.1.3:
resolution: {integrity: sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==}
engines: {node: '>= 0.6.0'}
immutable@5.1.1:
resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==}
@ -871,8 +858,6 @@ snapshots:
'@vue/shared@3.5.13': {}
bootstrap-icons@1.11.3: {}
braces@3.0.3:
dependencies:
fill-range: 7.1.1
@ -927,8 +912,6 @@ snapshots:
fsevents@2.3.3:
optional: true
fuzzy@0.1.3: {}
immutable@5.1.1: {}
is-extglob@2.1.1:

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

@ -13,17 +13,13 @@
</template>
</Suspense>
</div>
<div id="dock-wrapper">
<Search></Search>
<Dock></Dock>
</div>
<Dock></Dock>
</template>
<script setup>
import { ref, computed, onUnmounted } from 'vue';
import { ref, computed } 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([])
@ -32,22 +28,10 @@ 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) => {

View file

@ -1,6 +1,7 @@
<script setup>
import { defineProps, ref } from 'vue'
import { defineProps, ref, onMounted } from 'vue'
// Define component props
const props = defineProps({
packageName: {
type: String,
@ -23,12 +24,12 @@ if (Bridge.getSystemNightMode() == 'yes') {
} else {
darkLabel = false;
}
// Create a ref to hold the icon URL
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()}...`;
if (props.label.length >= 10) {
label.value = `${props.label.slice(0, 10 - 3).trim()}...`;
} else {
label.value = props.label;
}
@ -36,21 +37,6 @@ if (props.label.length >= 12) {
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>
@ -79,21 +65,18 @@ loadIcon();
}
.app-image {
width: 14vw;
height: auto;
width: 60px;
height: 60px;
border-radius: 12px;
}
.app-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 10pt;
font-size: 12px;
color: var(--label-color);
}
.app-package {
font-size: 1px;
font-size: 3px;
color: #00000000;
}
</style>

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,5 +1,4 @@
<script setup>
import { ref } from 'vue';
function toggleBridgeButton() {
console.log('Changed Bridge Button visibility to...')
if (Bridge.getBridgeButtonVisibility() == 'shown') {
@ -12,15 +11,13 @@ function toggleBridgeButton() {
}
function toggleSystemWallpapers() {
console.log('Changed draw system wallpapers to...')
console.log('Changed 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';
}
}
@ -41,7 +38,6 @@ function openBridgeAppDrawer() {
function reloadWindow() {
window.location.reload();
}
</script>
<template>
@ -52,21 +48,6 @@ function reloadWindow() {
<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>
<small style="font-size:xx-small;color:white">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>
</template>

View file

@ -12,9 +12,4 @@ if (!window.Bridge) {
Bridge.requestSetBridgeTheme('system');
window.springboard = {
apps: [],
labelColor: 'ffffff'
}
createApp(App).mount('#app')

View file

@ -1,11 +1,8 @@
body {
margin: 0;
padding: 0;
background-color: #808080;
}
* {
box-sizing: border-box;
background-color: #808080;
}
#applist {
@ -20,63 +17,44 @@ body {
}
.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 {
scroll-snap-align: start;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 5%;
flex-direction: row;
flex-wrap: wrap;
min-width: 100vw;
justify-content: flex-start;
align-content: flex-start;
padding-bottom: 10%;
padding-top: 5%;
& > * {
min-width: 25%; // 4 columns
margin-bottom: 5%;
}
}
#dock {
padding: 5%;
margin: 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%;
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
.section {
padding: 5%;
margin: 5%;
margin-top: 0;
border-radius: 15px;
background-color: rgba(0,0,0,0.5);
background-color: rgba(0,0,0,0.25);
border: 1px solid white;
width: 100%;
color: white;
width: 100%
}
.ui-button {

View file

@ -12,8 +12,4 @@ export default defineConfig({
},
},
},
build: {
outDir: 'dist',
emptyOutDir: true,
},
})