Merge branch 'main' of https://github.com/Frontesque/VueTube into main
Before Width: | Height: | Size: 192 KiB |
Before Width: | Height: | Size: 312 KiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 299 KiB |
Before Width: | Height: | Size: 1.0 MiB |
|
@ -29,7 +29,11 @@
|
|||
{{ title.text }}
|
||||
</div>
|
||||
|
||||
<div class="grey--text caption" v-text="parseBottom(video)" />
|
||||
<div
|
||||
class="caption background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="parseBottom(video)"
|
||||
/>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-card>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<v-card
|
||||
class="entry gridVideoRenderer accent"
|
||||
class="entry gridVideoRenderer background"
|
||||
:to="`/watch?v=${video.videoId}`"
|
||||
flat
|
||||
>
|
||||
|
@ -52,7 +52,11 @@
|
|||
{{ title.text }}
|
||||
</div>
|
||||
|
||||
<div class="grey--text caption" v-text="parseBottom(video)" />
|
||||
<div
|
||||
class="background--text caption"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="parseBottom(video)"
|
||||
/>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-card>
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="content">
|
||||
<v-btn class="pausePlay" text @click="playing = !playing">
|
||||
<v-icon size="5em" color="white">mdi-{{ playing ? "pause" : "play" }}</v-icon>
|
||||
</v-btn>
|
||||
<div @click="toggleControls()" class="content" :style="showControls ? 'background: rgba(0, 0, 0, 0.5);' : '' ">
|
||||
|
||||
<scrubber class="scrubber" :duration="duration" :endDuration="endDuration" />
|
||||
<div v-show="showControls">
|
||||
<v-btn class="pausePlay" text @click="playing = !playing">
|
||||
<v-icon size="5em" color="white">mdi-{{ playing ? "pause" : "play" }}</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<scrubber class="scrubber" :duration="duration" :endDuration="endDuration" />
|
||||
</div>
|
||||
|
||||
<video
|
||||
ref="player"
|
||||
autoplay
|
||||
:src="vidSrc"
|
||||
width="100%"
|
||||
style="max-height: 50vh"
|
||||
|
@ -43,7 +45,8 @@ export default {
|
|||
vidSrc: null,
|
||||
|
||||
//--- Player State Information ---//
|
||||
playing: true,
|
||||
showControls: false,
|
||||
playing: false,
|
||||
duration: 0,
|
||||
endDuration: 0,
|
||||
};
|
||||
|
@ -79,6 +82,11 @@ export default {
|
|||
this.duration = player.currentTime;
|
||||
this.endDuration = player.duration;
|
||||
},
|
||||
|
||||
toggleControls() {
|
||||
this.showControls = !this.showControls;
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -97,7 +105,6 @@ export default {
|
|||
.content:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
v-if="
|
||||
render.separatorDetails && render.separatorDetails.hasBottomSeparator
|
||||
"
|
||||
class="separator-bottom grey"
|
||||
class="separator-bottom background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-4' : 'darken-4'"
|
||||
:style="{ height: render.separatorDetails.height + 'px' }"
|
||||
></div>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
></component>
|
||||
<div
|
||||
v-if="render.separator && render.separator.hasBottomSeparator"
|
||||
class="separator-bottom grey"
|
||||
class="separator-bottom background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-4' : 'darken-4'"
|
||||
:style="{ height: render.separator.height + 'px' }"
|
||||
></div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<v-bottom-navigation
|
||||
v-model="tabSelection"
|
||||
shift
|
||||
class="bottomNav py-4 accent"
|
||||
class="bottomNav py-4 transparent"
|
||||
>
|
||||
<v-btn
|
||||
v-for="(item, i) in tabs"
|
||||
|
@ -14,8 +14,20 @@
|
|||
>
|
||||
<span v-text="item.name" />
|
||||
<v-icon
|
||||
:color="tabSelection == i ? 'primary' : 'grey'"
|
||||
:class="tabSelection == i ? 'tab primary lighten-2' : ''"
|
||||
:color="
|
||||
tabSelection == i
|
||||
? 'primary'
|
||||
: $vuetify.theme.dark
|
||||
? 'background lighten-4'
|
||||
: 'background darken-4'
|
||||
"
|
||||
:class="
|
||||
tabSelection == i
|
||||
? $vuetify.theme.dark
|
||||
? 'tab primary darken-4'
|
||||
: 'tab primary lighten-4'
|
||||
: ''
|
||||
"
|
||||
v-text="item.icon"
|
||||
/>
|
||||
<!--
|
||||
|
@ -56,12 +68,12 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.bottomNav {
|
||||
/* ios gesture nav */
|
||||
bottom: env(safe-area-inset-bottom) !important;
|
||||
box-shadow: none !important;
|
||||
height: 4rem !important;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
padding: 0 !important;
|
||||
z-index: 99999;
|
||||
position: fixed;
|
||||
}
|
||||
.navButton {
|
||||
width: 25vw !important;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<template>
|
||||
<v-card
|
||||
class="entry gridVideoRenderer accent"
|
||||
class="entry gridVideoRenderer background"
|
||||
:to="`/watch?v=${video.videoId}`"
|
||||
flat
|
||||
>
|
||||
<div style="position: relative" class="thumbnail-container">
|
||||
<v-img
|
||||
v-if="video.thumbnail"
|
||||
:aspect-ratio="16 / 9"
|
||||
:src="
|
||||
$youtube.getThumbnail(
|
||||
|
@ -16,6 +17,7 @@
|
|||
"
|
||||
/>
|
||||
<div
|
||||
v-if="video.thumbnailOverlays"
|
||||
class="videoRuntimeFloat"
|
||||
:class="
|
||||
'style-' +
|
||||
|
@ -31,7 +33,7 @@
|
|||
<div id="details">
|
||||
<a
|
||||
:href="
|
||||
this.$rendererUtils.getNavigationEndpoints(
|
||||
$rendererUtils.getNavigationEndpoints(
|
||||
video.shortBylineText.runs[0].navigationEndpoint
|
||||
)
|
||||
"
|
||||
|
@ -52,7 +54,11 @@
|
|||
{{ title.text }}
|
||||
</div>
|
||||
|
||||
<div class="grey--text caption" v-text="parseBottom(video)" />
|
||||
<div
|
||||
class="background--text text--lighten-5 caption"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="parseBottom(video)"
|
||||
/>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-card>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<template>
|
||||
<v-card
|
||||
style="height: 4rem !important; display: flex; box-shadow: none !important"
|
||||
color="accent"
|
||||
class="topNav rounded-0 pa-3"
|
||||
class="rounded-0 pa-3 topNav transparent"
|
||||
>
|
||||
<h3 v-show="!search" class="my-auto ml-4" v-text="page" />
|
||||
|
||||
|
@ -22,7 +21,10 @@
|
|||
dense
|
||||
flat
|
||||
label="Search"
|
||||
class="searchBar"
|
||||
style="margin-top: 1px"
|
||||
:background-color="
|
||||
$vuetify.theme.dark ? 'background lighten-1' : 'background darken-1'
|
||||
"
|
||||
@input="$emit('text-changed', text)"
|
||||
@keyup.enter="$emit('search-btn', text)"
|
||||
/>
|
||||
|
@ -30,6 +32,7 @@
|
|||
<v-spacer v-if="!search" />
|
||||
|
||||
<v-btn
|
||||
v-if="!search"
|
||||
v-show="page == 'Home'"
|
||||
icon
|
||||
tile
|
||||
|
@ -100,18 +103,13 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.topNav {
|
||||
/* ios notch */
|
||||
top: env(safe-area-inset-top) !important;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
/*border-radius: 0 0 1em 1em !important;*/
|
||||
}
|
||||
.topNavSearch {
|
||||
margin-bottom: -10em;
|
||||
margin-left: 2em;
|
||||
/*transform: translateY(-2.5%);*/
|
||||
}
|
||||
.searchBar {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// this is an loading animation for videos
|
||||
<template>
|
||||
<div>
|
||||
<v-skeleton-loader
|
||||
v-for="i in 10"
|
||||
:key="i"
|
||||
type="image, list-item-avatar-two-line"
|
||||
/>
|
||||
<v-sheet color="background" v-for="i in 10" :key="i">
|
||||
<v-skeleton-loader type="image, list-item-avatar-two-line" />
|
||||
</v-sheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-app v-show="stateLoaded" style="background: black !important">
|
||||
<v-app style="background: transparent !important">
|
||||
<topNavigation
|
||||
:search="search"
|
||||
:page="page"
|
||||
|
@ -9,16 +9,11 @@
|
|||
@scroll-to-top="$refs.pgscroll.scrollTop = 0"
|
||||
/>
|
||||
|
||||
<div class="accent" style="height: 100%; margin-top: 4rem">
|
||||
<div style="height: 100%; margin-top: 4rem">
|
||||
<div
|
||||
v-show="!search"
|
||||
class="background"
|
||||
style="
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 8rem);
|
||||
transition-duration: 0.3s;
|
||||
transition-property: border-radius;
|
||||
"
|
||||
class="scrollcontainer"
|
||||
style="overflow: hidden; height: calc(100vh - 8rem)"
|
||||
:style="{
|
||||
borderRadius: `${roundTweak / 2}rem`,
|
||||
}"
|
||||
|
@ -26,20 +21,14 @@
|
|||
<!-- element above removes artifacting from things like v-ripple by -->
|
||||
<!-- scrollbox below must be a standalone div -->
|
||||
<div ref="pgscroll" class="scroll-y" style="height: 100%">
|
||||
<nuxt v-show="!search" />
|
||||
<nuxt />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="search"
|
||||
class="accent"
|
||||
style="
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 4rem);
|
||||
transition-duration: 0.3s;
|
||||
transition-property: border-radius;
|
||||
"
|
||||
class="scrollcontainer"
|
||||
style="overflow: hidden; height: calc(100vh - 4rem)"
|
||||
>
|
||||
<div class="scroll-y" style="height: 100%">
|
||||
<div v-if="search" style="min-width: 180px">
|
||||
|
@ -52,7 +41,7 @@
|
|||
text
|
||||
tile
|
||||
dense
|
||||
class="info--text searchButton text-left text-capitalize"
|
||||
class="searchButton text-left text-capitalize"
|
||||
@click="youtubeSearch(item)"
|
||||
>
|
||||
<v-icon class="mr-5">mdi-magnify</v-icon>
|
||||
|
@ -78,7 +67,6 @@ export default {
|
|||
data: () => ({
|
||||
search: false,
|
||||
response: [],
|
||||
stateLoaded: false,
|
||||
}),
|
||||
|
||||
computed: {
|
||||
|
@ -104,13 +92,7 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
// initializes UI tweaks to the saved state
|
||||
this.$store.commit("tweaks/initTweaks");
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.stateLoaded = true;
|
||||
//--- Back Button Listener ---//
|
||||
CapacitorApp.addListener("backButton", ({ canGoBack }) => {
|
||||
//--- Back Closes Search ---//
|
||||
|
@ -179,13 +161,21 @@ export default {
|
|||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
.scrollcontainer {
|
||||
overflow: hidden;
|
||||
/* ios notch & gesture nav */
|
||||
padding: env(safe-area-inset-top) env(safe-area-inset-right)
|
||||
env(safe-area-inset-bottom) env(safe-area-inset-left) !important;
|
||||
}
|
||||
|
||||
.scroll-y {
|
||||
overflow-y: scroll !important; /* has to be scroll, not auto */
|
||||
overflow-x: hidden !important;
|
||||
-webkit-overflow-scrolling: touch !important;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
background: black;
|
||||
background: var(--v-background-base);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-app>
|
||||
<v-app style="background: transparent !important">
|
||||
<nuxt />
|
||||
</v-app>
|
||||
</template>
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
<v-app>
|
||||
<center>
|
||||
<v-icon size="100">mdi-alert-circle</v-icon>
|
||||
<h1 class="grey--text">An error occured!</h1>
|
||||
<h1
|
||||
class="background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
An error occured!
|
||||
</h1>
|
||||
<v-btn to="/">Reload Application</v-btn>
|
||||
<v-btn to="/logs">Show Logs</v-btn>
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import colors from "vuetify/es5/util/colors";
|
||||
/**** Front's Notes / Don't Remove ****
|
||||
* Data Storage:
|
||||
* localStorage.setItem("key", data)
|
||||
|
@ -36,7 +35,11 @@ export default {
|
|||
},
|
||||
meta: [
|
||||
{ charset: "utf-8" },
|
||||
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||
{
|
||||
name: "viewport",
|
||||
content:
|
||||
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover",
|
||||
},
|
||||
{ name: "format-detection", content: "telephone=no" },
|
||||
],
|
||||
},
|
||||
|
@ -51,26 +54,18 @@ export default {
|
|||
customVariables: ["~/assets/variables.scss"],
|
||||
treeShake: true,
|
||||
theme: {
|
||||
dark: false,
|
||||
options: { customProperties: true },
|
||||
dark: true,
|
||||
options: {
|
||||
customProperties: true,
|
||||
},
|
||||
themes: {
|
||||
light: {
|
||||
primary: {
|
||||
base: colors.red.lighten2,
|
||||
lighten2: colors.red.lighten4,
|
||||
},
|
||||
background: "#fff",
|
||||
accent: "#fff",
|
||||
info: "#000",
|
||||
primary: "#E57373",
|
||||
background: "#ffffff",
|
||||
},
|
||||
dark: {
|
||||
primary: {
|
||||
base: colors.red.darken2,
|
||||
lighten2: "#533",
|
||||
},
|
||||
background: "#333",
|
||||
accent: "#222",
|
||||
info: "#fff",
|
||||
primary: "#B71C1C",
|
||||
background: "#000000",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
<center class="container">
|
||||
<v-img
|
||||
src="/icon.svg"
|
||||
width="10em"
|
||||
style="margin-bottom: 1em"
|
||||
width="10rem"
|
||||
height="10rem"
|
||||
class="intro"
|
||||
:class="$vuetify.theme.dark ? '' : 'invert'"
|
||||
/>
|
||||
<v-progress-circular size="50" indeterminate color="primary" />
|
||||
<div style="height: 5rem" />
|
||||
<v-progress-linear rounded height="8" indeterminate color="primary" />
|
||||
<div class="pt-2">{{ progressMsg }}...</div>
|
||||
</center>
|
||||
</template>
|
||||
|
||||
|
@ -14,46 +17,38 @@
|
|||
export default {
|
||||
layout: "empty",
|
||||
|
||||
//--- Hide Splash Screen ---//
|
||||
async beforeCreate() {
|
||||
const { SplashScreen } = await require("@capacitor/splash-screen"); // This has to be imported here, otherwise NUXT won't import the package because its so early in the lifecycle -Front
|
||||
await SplashScreen.hide();
|
||||
},
|
||||
//--- End Hide Splash Screen ---//
|
||||
|
||||
data: () => ({
|
||||
progressMsg: "Fetching the API",
|
||||
}),
|
||||
async mounted() {
|
||||
//--- Theme Loader Moved From '~/layouts/default.vue' (because this only needs to be run once) -Front ---//
|
||||
setTimeout(() => {
|
||||
//Set timeout is required to make it load properly... dont ask me why -Front
|
||||
const darkTheme = localStorage.getItem("darkTheme");
|
||||
if (darkTheme == "true") {
|
||||
this.$vuetify.theme.dark = darkTheme;
|
||||
//this.$vuetube.statusBar.setDark(); //Not needed unless setLight() is used below -Front
|
||||
this.$vuetube.statusBar.setBackground(
|
||||
this.$vuetify.theme.themes.dark.accent
|
||||
this.$store.commit("tweaks/initTweaks");
|
||||
const theming = new Promise((resolve) =>
|
||||
// Set timeout is required for $vuetify.theme... dont ask me why -Front
|
||||
setTimeout(() => {
|
||||
this.$vuetify.theme.dark = JSON.parse(localStorage.getItem("darkTheme")) === true;
|
||||
if (localStorage.getItem("primaryDark") != null)
|
||||
this.$vuetify.theme.themes.dark.primary = localStorage.getItem("primaryDark");
|
||||
if (localStorage.getItem("primaryLight") != null)
|
||||
this.$vuetify.theme.themes.light.primary = localStorage.getItem("primaryLight");
|
||||
if (localStorage.getItem("backgroundDark") != null)
|
||||
this.$vuetify.theme.themes.dark.background = localStorage.getItem("backgroundDark");
|
||||
if (localStorage.getItem("backgroundLight") != null)
|
||||
this.$vuetify.theme.themes.light.background = localStorage.getItem("backgroundLight");
|
||||
this.$vuetube.navigationBar.setTheme(
|
||||
this.$vuetify.theme.currentTheme.background,
|
||||
!this.$vuetify.theme.dark
|
||||
);
|
||||
|
||||
const isOled = localStorage.getItem("isOled");
|
||||
|
||||
if (isOled == "true") {
|
||||
(this.$vuetify.theme.themes.dark.accent = "#000"),
|
||||
(this.$vuetify.theme.themes.dark.accent = "#000"),
|
||||
(this.$vuetify.theme.themes.dark.background = "#000");
|
||||
} else {
|
||||
(this.$vuetify.theme.themes.dark.accent = "#222"),
|
||||
(this.$vuetify.theme.themes.dark.accent = "#222"),
|
||||
(this.$vuetify.theme.themes.dark.background = "#333");
|
||||
}
|
||||
} else {
|
||||
//this.$vuetube.statusBar.setLight() //Looks weird -Front
|
||||
this.$vuetube.statusBar.setBackground(
|
||||
this.$vuetify.theme.themes.light.accent
|
||||
this.$vuetube.statusBar.setTheme(
|
||||
this.$vuetify.theme.currentTheme.background,
|
||||
this.$vuetify.theme.dark
|
||||
);
|
||||
}
|
||||
}, 0);
|
||||
//-----------------------------------------------------------------------------------------------------------//
|
||||
resolve();
|
||||
}, 0)
|
||||
);
|
||||
|
||||
await theming;
|
||||
await this.$youtube.getAPI();
|
||||
this.progressMsg = "Navigating Home";
|
||||
this.$router.push(`/${localStorage.getItem("startPage") || "home"}`);
|
||||
},
|
||||
};
|
||||
|
@ -61,12 +56,46 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.container {
|
||||
padding-top: 3em;
|
||||
display: block;
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -80%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.intro {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
transition-property: opacity, transform;
|
||||
animation: bounce 0.66s ease infinite alternate;
|
||||
}
|
||||
/* triangles aren't very good at spinning :c */
|
||||
@keyframes bounce {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* reduced-motion animations */
|
||||
@media (prefers-reduced-motion) {
|
||||
.intro {
|
||||
opacity: 0;
|
||||
transform: scale(1);
|
||||
transition-property: opacity, transform;
|
||||
animation: fadein 0.5s ease 1 forwards;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
<template>
|
||||
<center>
|
||||
<center class="px-4">
|
||||
<v-img
|
||||
contain
|
||||
style="margin-top: 5em; max-width: 80%; max-height: 15em"
|
||||
src="/dev.svg"
|
||||
/>
|
||||
<h1 class="grey--text">Page Under Construction</h1>
|
||||
<p class="grey--text">Please read the VueTube FAQ for more information.</p>
|
||||
<h2
|
||||
class="background--text mt-4"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
Page Under Construction
|
||||
</h2>
|
||||
<p
|
||||
class="background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
Please read the VueTube FAQ for more information.
|
||||
</p>
|
||||
</center>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
|
||||
<!-- Top Notice -->
|
||||
<center style="margin: 2em;">
|
||||
<h1>VueTube Registry</h1>
|
||||
<v-alert text outlined type="warning">
|
||||
ONLY TOUCH THIS IF YOU KNOW WHAT YOU ARE DOING!<br>
|
||||
MESSING WITH SETTINGS MAY CAUSE YOUR APP TO BREAK!
|
||||
</v-alert>
|
||||
</center>
|
||||
|
||||
<!-- Registry List Loader -->
|
||||
<v-list-item v-for="(item, index) in keys" :key="index">
|
||||
<v-card class="card rounded-lg" :class="$vuetify.theme.dark ? 'background lighten-1' : 'background darken-1'">
|
||||
<v-card-title v-text="item.key" />
|
||||
<v-card-text v-text="item.value" />
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn text class="actionButton" disabled><v-icon color="primary">mdi-pencil</v-icon></v-btn>
|
||||
<v-btn text class="actionButton" @click="confirmDelete(item)"><v-icon color="error">mdi-delete</v-icon></v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Delete Entry Dialog -->
|
||||
<v-dialog v-model="deleteDialog" width="500">
|
||||
|
||||
<v-card :class="$vuetify.theme.dark ? 'background lighten-1' : 'background darken-1'">
|
||||
<v-card-title class="text-h5">Confirm Delete</v-card-title>
|
||||
|
||||
<v-card-text>Are you sure that you want to delete <span class="highlight" v-text="selectedKey" />?</v-card-text>
|
||||
|
||||
<v-alert text outlined type="warning" style="margin: 0 2em 2em; 2em;">Deleting random keys may cause the app to break!</v-alert>
|
||||
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" text @click="deleteDialog = false">No</v-btn>
|
||||
<v-btn color="primary" text @click="deleteKey()">Yes</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keys: [],
|
||||
|
||||
selectedKey: null,
|
||||
deleteDialog: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.syncRegistry();
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
syncRegistry() {
|
||||
this.keys = [];
|
||||
const localStorageKeys = Object.keys(localStorage)
|
||||
for (const i in localStorageKeys) {
|
||||
const key = localStorageKeys[i];
|
||||
const keyValue = localStorage.getItem(key);
|
||||
this.keys.push({key: key, value: keyValue});
|
||||
}
|
||||
},
|
||||
|
||||
confirmDelete(item) {
|
||||
this.selectedKey = item.key;
|
||||
this.deleteDialog = true;
|
||||
},
|
||||
deleteKey() {
|
||||
this.deleteDialog = false;
|
||||
localStorage.removeItem(this.selectedKey);
|
||||
this.syncRegistry();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card {
|
||||
margin: 1em;
|
||||
width: 100%;
|
||||
}
|
||||
.actionButton {
|
||||
min-width: 1em !important;
|
||||
}
|
||||
.highlight {
|
||||
background: #999;
|
||||
border-radius: 5px;
|
||||
padding: 0.25em;
|
||||
}
|
||||
</style>
|
|
@ -1,20 +1,28 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-list-item v-for="(item, index) in logs" :key="index">
|
||||
<v-card class="card">
|
||||
<v-card
|
||||
class="card background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
flat
|
||||
>
|
||||
<v-card-title>
|
||||
<v-chip v-if="item.error" outlined class="errorChip" color="error"
|
||||
>Error</v-chip
|
||||
>
|
||||
{{ item.name }}
|
||||
<span
|
||||
class="date"
|
||||
class="date background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="`• ${new Date(item.time).toLocaleString()}`"
|
||||
/>
|
||||
</v-card-title>
|
||||
|
||||
<v-expansion-panels>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel
|
||||
class="background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
>
|
||||
<v-expansion-panel-header>More</v-expansion-panel-header>
|
||||
<v-expansion-panel-content class="logContent" v-text="item.data" />
|
||||
</v-expansion-panel>
|
||||
|
@ -33,7 +41,6 @@
|
|||
margin: 0.4em;
|
||||
font-size: 0.75em;
|
||||
transform: translateY(5%);
|
||||
color: #999;
|
||||
}
|
||||
.errorChip {
|
||||
margin-right: 0.5em;
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
<template>
|
||||
<div class="mainContainer pt-1">
|
||||
<v-card class="pb-5">
|
||||
<v-card
|
||||
flat
|
||||
class="pb-5 background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
>
|
||||
<v-card-title>Default Page</v-card-title>
|
||||
<v-card-text>
|
||||
<v-select
|
||||
v-model="page"
|
||||
background-color="background"
|
||||
:items="pages"
|
||||
label="Default Page"
|
||||
solo
|
||||
|
|
|
@ -1,122 +1,224 @@
|
|||
<template>
|
||||
<div class="py-1">
|
||||
<v-card class="pb-5">
|
||||
<v-card-title>Global Base Color</v-card-title>
|
||||
<v-row class="ml-3 mr-6">
|
||||
<section class="row">
|
||||
<v-switch
|
||||
v-model="$vuetify.theme.dark"
|
||||
label="Dark Theme"
|
||||
hint="Bravo Six, Going Dark."
|
||||
persistent-hint
|
||||
inset
|
||||
@click="saveTheme($vuetify.theme.dark)"
|
||||
/>
|
||||
</section>
|
||||
<v-btn
|
||||
v-if="$vuetify.theme.dark"
|
||||
text
|
||||
tile
|
||||
class="white--text black"
|
||||
@click="amoled"
|
||||
<client-only>
|
||||
<div class="d-flex flex-column justify-end" style="min-height: 100%">
|
||||
<!-- ----------------------------------------------Background Colors------------------------ -->
|
||||
<v-radio-group v-model="$vuetify.theme.currentTheme.background">
|
||||
<div
|
||||
class="d-flex flex-row px-6 no-wrap"
|
||||
style="max-width: 100%; overflow-x: auto"
|
||||
>
|
||||
{{
|
||||
$vuetify.theme.themes.dark.background === "#000" ? "LCD" : "OLED"
|
||||
}}
|
||||
<v-icon
|
||||
:size="
|
||||
$vuetify.theme.themes.dark.background === '#000'
|
||||
? '.5rem'
|
||||
: '.9rem'
|
||||
"
|
||||
class="ml-2"
|
||||
>mdi-brightness-2</v-icon
|
||||
<div
|
||||
v-for="background in $vuetify.theme.dark
|
||||
? backgroundsDark
|
||||
: backgroundsLight"
|
||||
:key="background.color"
|
||||
class="text-center"
|
||||
>
|
||||
</v-btn>
|
||||
</v-row>
|
||||
</v-card>
|
||||
|
||||
<v-card class="pb-5">
|
||||
<v-card-title>Accent Color</v-card-title>
|
||||
<v-card-text>
|
||||
<v-alert color="primary" dense outlined type="warning"
|
||||
>NOTE: This doesn't save after closing the app (yet)</v-alert
|
||||
<v-radio
|
||||
color="primary"
|
||||
active-class="px-6 border-primary"
|
||||
style="transition-duration: 0.3s"
|
||||
:style="{
|
||||
background: background.color,
|
||||
border: '2px solid ' + background.color,
|
||||
}"
|
||||
class="py-4 px-4 ma-2 rounded-lg"
|
||||
:value="background.color"
|
||||
/>
|
||||
{{ background.name }}
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<v-radio
|
||||
color="primary"
|
||||
active-class="px-6 border-primary primary"
|
||||
style="transition-duration: 0.3s"
|
||||
:style="{
|
||||
background: $vuetify.theme.dark
|
||||
? 'var(--v-primary-darken4) !important'
|
||||
: 'var(--v-primary-lighten4) !important',
|
||||
border: $vuetify.theme.dark
|
||||
? '2px solid var(--v-primary-darken4)'
|
||||
: '2px solid var(--v-primary-lighten4)',
|
||||
}"
|
||||
class="py-4 px-4 ma-2 rounded-lg"
|
||||
:value="
|
||||
$vuetify.theme.dark ? experimentalDark : experimentalLight
|
||||
"
|
||||
/>
|
||||
Adaptive
|
||||
</div>
|
||||
</div>
|
||||
</v-radio-group>
|
||||
<!-- ----------------------------------------------Primary Colors------------------------ -->
|
||||
<v-radio-group v-model="$vuetify.theme.currentTheme.primary" class="mx-2">
|
||||
<div
|
||||
class="d-flex flex-row px-6 py-2 no-wrap align-center"
|
||||
style="max-width: 100%; overflow-x: auto; margin-top: -1.5rem"
|
||||
>
|
||||
<v-color-picker
|
||||
v-model="accentColor"
|
||||
dot-size="5"
|
||||
hide-mode-switch
|
||||
mode="hexa"
|
||||
<v-radio
|
||||
v-for="color in $vuetify.theme.dark ? primaryDark : primaryLight"
|
||||
:key="color"
|
||||
color="background"
|
||||
on-icon="mdi-check"
|
||||
:light="$vuetify.theme.dark"
|
||||
:dark="!$vuetify.theme.dark"
|
||||
active-class="border-primary"
|
||||
style="transition-duration: 0.3s"
|
||||
:style="{
|
||||
background: color,
|
||||
border: '2px solid ' + color,
|
||||
}"
|
||||
class="mr-2 my-auto rounded-xl"
|
||||
:value="color"
|
||||
/>
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
width="300"
|
||||
content-class="background rounded-lg"
|
||||
>
|
||||
<template #activator="{ on, attrs }">
|
||||
<v-btn
|
||||
icon
|
||||
class="background"
|
||||
style="height: 1.75rem; width: 1.75rem"
|
||||
:class="$vuetify.theme.dark ? 'lighten-2' : 'darken-2'"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-color-picker
|
||||
v-model="$vuetify.theme.currentTheme.primary"
|
||||
style="min-width: 100%"
|
||||
class="background"
|
||||
hide-mode-switch
|
||||
dot-size="50"
|
||||
mode="hexa"
|
||||
flat
|
||||
/>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</v-radio-group>
|
||||
<!-- ----------------------------------------------Mode Switch------------------------ -->
|
||||
<v-card
|
||||
flat
|
||||
class="d-flex flex-row justify-between mx-8 mb-4 px-4 background rounded-lg"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
@click="
|
||||
($vuetify.theme.dark = !$vuetify.theme.dark),
|
||||
$vuetube.haptics.hapticsImpactLight(1)
|
||||
"
|
||||
>
|
||||
<div class="my-auto">
|
||||
<div>Dark Mode</div>
|
||||
<div
|
||||
class="background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
style="font-size: 0.75rem; margin-top: -0.25rem !important"
|
||||
>
|
||||
Bravo Six, Going Dark.
|
||||
</div>
|
||||
</div>
|
||||
<v-spacer />
|
||||
<v-switch
|
||||
v-model="$vuetify.theme.dark"
|
||||
style="pointer-events: none"
|
||||
persistent-hint
|
||||
inset
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</client-only>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
accentColor: "#ffffff",
|
||||
primaryLight: ["#E57373", "#8b5f37", "#016a49", "#34495E"],
|
||||
primaryDark: [
|
||||
"#B71C1C",
|
||||
"#FFBBFF",
|
||||
"#AAAFFF",
|
||||
"#AAFFFF",
|
||||
"#7CD6AF",
|
||||
"#FEC89B",
|
||||
],
|
||||
backgroundsDark: [
|
||||
{ name: "Dark", color: "#181818" },
|
||||
{ name: "Black", color: "#000000" },
|
||||
],
|
||||
backgroundsLight: [{ name: "Normal", color: "#ffffff" }],
|
||||
experimentalLight: "",
|
||||
experimentalDark: "",
|
||||
dialog: false,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
accentColor: function (val) {
|
||||
this.$vuetify.theme.currentTheme.primary.base = val;
|
||||
let primaryAlt = this.$vuetube.hexToRgb(val);
|
||||
|
||||
let rgbEdit = 130; //Light Mode
|
||||
if (localStorage.getItem("darkTheme") === "true") rgbEdit = -80; //Dark Mode
|
||||
|
||||
for (const i in primaryAlt) {
|
||||
primaryAlt[i] = primaryAlt[i] + rgbEdit; //Amount To Lighten By
|
||||
if (primaryAlt[i] > 255) primaryAlt[i] = 255;
|
||||
if (primaryAlt[i] < 0) primaryAlt[i] = 0;
|
||||
// also triggers background and primary watcher, unless primary colors match
|
||||
"$vuetify.theme.dark"(value) {
|
||||
localStorage.setItem("darkTheme", value);
|
||||
},
|
||||
"$vuetify.theme.currentTheme.background"(value) {
|
||||
this.$vuetify.theme.dark
|
||||
? localStorage.setItem("backgroundDark", value)
|
||||
: localStorage.setItem("backgroundLight", value);
|
||||
this.$vuetube.statusBar.setTheme(value, this.$vuetify.theme.dark);
|
||||
this.$vuetube.navigationBar.setTheme(value, !this.$vuetify.theme.dark);
|
||||
},
|
||||
"$vuetify.theme.currentTheme.primary"(value) {
|
||||
if (value != undefined) {
|
||||
this.$vuetify.theme.dark
|
||||
? localStorage.setItem("primaryDark", value)
|
||||
: localStorage.setItem("primaryLight", value);
|
||||
let tempD = this.experimentalDark;
|
||||
let tempL = this.experimentalLight;
|
||||
this.adapt();
|
||||
if (this.$vuetify.theme.currentTheme.background === tempD)
|
||||
this.$vuetify.theme.currentTheme.background = this.experimentalDark;
|
||||
if (this.$vuetify.theme.currentTheme.background === tempL)
|
||||
this.$vuetify.theme.currentTheme.background = this.experimentalLight;
|
||||
}
|
||||
|
||||
primaryAlt = this.$vuetube.rgbToHex(
|
||||
primaryAlt.r,
|
||||
primaryAlt.g,
|
||||
primaryAlt.b
|
||||
);
|
||||
|
||||
this.$vuetify.theme.currentTheme.primary.lighten2 = primaryAlt;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.accentColor = this.$vuetify.theme.themes.dark.primary.base;
|
||||
beforeMount() {
|
||||
this.adapt();
|
||||
},
|
||||
|
||||
methods: {
|
||||
amoled() {
|
||||
this.$vuetify.theme.themes.dark.background === "#000"
|
||||
? ((this.$vuetify.theme.themes.dark.accent = "#222"),
|
||||
(this.$vuetify.theme.themes.dark.accent = "#222"),
|
||||
(this.$vuetify.theme.themes.dark.background = "#333"),
|
||||
localStorage.setItem("isOled", false))
|
||||
: ((this.$vuetify.theme.themes.dark.accent = "#000"),
|
||||
(this.$vuetify.theme.themes.dark.accent = "#000"),
|
||||
(this.$vuetify.theme.themes.dark.background = "#000"),
|
||||
localStorage.setItem("isOled", true));
|
||||
},
|
||||
saveTheme(isDark) {
|
||||
this.$vuetube.statusBar.setBackground(
|
||||
this.$vuetify.theme.currentTheme.accent
|
||||
adapt() {
|
||||
let hexD = getComputedStyle(document.documentElement).getPropertyValue(
|
||||
"--v-primary-darken4"
|
||||
);
|
||||
localStorage.setItem("darkTheme", isDark);
|
||||
let hexL = getComputedStyle(document.documentElement).getPropertyValue(
|
||||
"--v-primary-lighten4"
|
||||
);
|
||||
// the menace above returns a hex string with A SPACE " " in front of it, that's why substring(1)
|
||||
// the SPACE " " is stored as part of the CSS variable itself to be used for chaining
|
||||
this.experimentalDark = hexD.substring(1).toUpperCase();
|
||||
this.experimentalLight = hexL.substring(1).toUpperCase();
|
||||
setTimeout(() => {
|
||||
if (
|
||||
this.$vuetify.theme.currentTheme.background ==
|
||||
hexD.substring(1).toUpperCase()
|
||||
)
|
||||
this.$vuetify.theme.currentTheme.background = this.experimentalDark;
|
||||
if (
|
||||
this.$vuetify.theme.currentTheme.background ==
|
||||
hexL.substring(1).toUpperCase()
|
||||
)
|
||||
this.$vuetify.theme.currentTheme.background = this.experimentalLight;
|
||||
}, 0);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.v-card {
|
||||
margin: 1em;
|
||||
<style>
|
||||
.border-primary {
|
||||
border: 2px solid var(--v-primary-base) !important;
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 0 1em 1em 1em;
|
||||
.v-input--selection-controls__input {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
<template>
|
||||
<div class="py-1">
|
||||
<v-card class="px-8 py-6 ma-4">
|
||||
<h3>Layout</h3>
|
||||
<v-switch class="mt-6" disabled label="Dense Navbars" />
|
||||
<v-switch disabled label="Disable Top Bar" />
|
||||
<!-- <v-switch class="mt-6" disabled label="Reverse (disabled)" /> -->
|
||||
</v-card>
|
||||
<v-card class="px-8 pt-6 ma-4">
|
||||
<h3>Rounded Corners</h3>
|
||||
<v-switch class="mt-6" disabled label="Reverse (disabled)" />
|
||||
<v-slider
|
||||
disabled
|
||||
class="mr-2"
|
||||
label="Outer (disabled)"
|
||||
:max="4"
|
||||
step="1"
|
||||
thumb-size="64"
|
||||
></v-slider>
|
||||
<div class="d-flex flex-column justify-end" style="min-height: 100%">
|
||||
<v-card
|
||||
flat
|
||||
class="px-6 ma-4 mt-2 background"
|
||||
style="transition-duration: 0.3s; transition-property: border-radius"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
:style="{
|
||||
borderRadius: `${roundTweak / 2}rem`,
|
||||
}"
|
||||
>
|
||||
<h3 class="mt-5">Rounded Corners</h3>
|
||||
<div
|
||||
class="background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
applies to only a few elements for now
|
||||
</div>
|
||||
<!-- TODO: outer radius -->
|
||||
<!-- TODO: Dense Navbar -->
|
||||
<!-- TODO: Disable Top Bar -->
|
||||
<!-- TODO: Top and Bottom bar color selection -->
|
||||
<v-slider
|
||||
v-model="roundTweak"
|
||||
class="mr-2"
|
||||
class="mr-2 mt-5"
|
||||
label="Inner"
|
||||
:max="4"
|
||||
step="1"
|
||||
thumb-size="64"
|
||||
@input="$vuetube.haptics.hapticsImpactLight(0)"
|
||||
>
|
||||
<template #thumb-label="{ value }">
|
||||
<div
|
||||
class="pa-4 white text-red red-text red--text"
|
||||
class="pa-4 background text-red red-text red--text"
|
||||
:style="{ borderRadius: value * 3 + 'px !important' }"
|
||||
></div>
|
||||
</template>
|
||||
|
|
|
@ -1,26 +1,51 @@
|
|||
<template>
|
||||
<div class="py-2">
|
||||
<v-list-item v-for="(item, index) in commits" :key="index" class="my-1">
|
||||
<v-card class="card my-2">
|
||||
<v-card
|
||||
flat
|
||||
class="card my-2 background"
|
||||
:class="$vuetify.theme.dark ? 'lighten-1' : 'darken-1'"
|
||||
>
|
||||
<v-card-title style="padding: 0 0.25em 0 0.75em">
|
||||
{{ item.author ? item.author.login : item.commit.author.name }}
|
||||
<span class="subtitle" v-text="`• ${item.sha.substring(0, 7)}`" />
|
||||
<span
|
||||
class="subtitle background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="`• ${item.sha.substring(0, 7)}`"
|
||||
/>
|
||||
<v-spacer />
|
||||
<v-chip v-if="index == 0" outlined class="tags" color="orange"
|
||||
>Latest</v-chip
|
||||
<v-chip
|
||||
v-if="index == 0"
|
||||
class="tags"
|
||||
color="orange"
|
||||
style="
|
||||
border-radius: 0.5rem;
|
||||
border: 2px var(--v-oragnge-base);
|
||||
margin-top: -1.5rem;
|
||||
margin-right: -0.5rem;
|
||||
"
|
||||
>
|
||||
Latest
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="item.sha == installedVersion"
|
||||
outlined
|
||||
class="tags"
|
||||
color="green"
|
||||
style="
|
||||
border-radius: 0.5rem;
|
||||
border: 2px var(--v-green-base);
|
||||
margin-top: -1.5rem;
|
||||
margin-right: -0.5rem;
|
||||
"
|
||||
>
|
||||
>Installed</v-chip
|
||||
>
|
||||
</v-card-title>
|
||||
|
||||
<div style="margin-left: 1em">
|
||||
<div
|
||||
class="date"
|
||||
class="date background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
v-text="new Date(item.commit.committer.date).toLocaleString()"
|
||||
/>
|
||||
{{ item.commit.message }}
|
||||
|
@ -28,12 +53,12 @@
|
|||
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn @click="openExternal(item)"
|
||||
><v-icon class="btn-icon">mdi-github</v-icon>View</v-btn
|
||||
>
|
||||
<v-btn disabled @click="install(item)"
|
||||
><v-icon class="btn-icon">mdi-download</v-icon>Install</v-btn
|
||||
>
|
||||
<v-btn @click="openExternal(item)" class="background">
|
||||
<v-icon class="btn-icon">mdi-github</v-icon>View
|
||||
</v-btn>
|
||||
<v-btn disabled @click="install(item)">
|
||||
<v-icon class="btn-icon">mdi-download</v-icon>Install
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-list-item>
|
||||
|
@ -48,10 +73,8 @@
|
|||
margin: 0.4em;
|
||||
font-size: 0.75em;
|
||||
transform: translateY(5%);
|
||||
color: #999;
|
||||
}
|
||||
.date {
|
||||
color: #999;
|
||||
transform: translateY(-40%);
|
||||
}
|
||||
.btn-icon {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="accent">
|
||||
<div class="background">
|
||||
<!-- Video Loading Animation -->
|
||||
<vid-load-renderer v-if="renderer.length <= 0" />
|
||||
<sectionListRenderer :render="renderer" />
|
||||
|
|
|
@ -53,6 +53,8 @@ export default {
|
|||
},
|
||||
{ name: "Logs", icon: "mdi-text-box-outline", to: "/mods/logs" },
|
||||
{ name: "About", icon: "mdi-information-outline", to: "/mods/about" },
|
||||
|
||||
/* Developer Settings, Don't Remove // Included in all releases for users to mess with if they feel comfortable enough */ { name: "", icon: "", to: "/mods/developer" },
|
||||
],
|
||||
};
|
||||
},
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
<template>
|
||||
<center>
|
||||
<center class="px-4">
|
||||
<v-img
|
||||
contain
|
||||
style="margin-top: 5em; max-width: 80%; max-height: 15em"
|
||||
src="/dev.svg"
|
||||
/>
|
||||
<h1 class="grey--text">Page Under Construction</h1>
|
||||
<p class="grey--text">Please read the VueTube FAQ for more information.</p>
|
||||
<h2
|
||||
class="background--text mt-4"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
Page Under Construction
|
||||
</h2>
|
||||
<p
|
||||
class="background--text"
|
||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||
>
|
||||
Please read the VueTube FAQ for more information.
|
||||
</p>
|
||||
</center>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<div class="accent">
|
||||
|
||||
<div class="background">
|
||||
<!-- Stock Player -->
|
||||
<videoPlayer :vid-src="vidSrc" />
|
||||
<videoPlayer
|
||||
style="position: sticky; top: 0; z-index: 696969"
|
||||
:vid-src="vidSrc"
|
||||
/>
|
||||
|
||||
<!-- VueTube Player V1 -->
|
||||
<!-- <VTPlayerV1 :sources="sources" v-if="sources.length > 0" />-->
|
||||
|
||||
|
||||
|
||||
<v-card v-if="loaded" class="ml-2 mr-2 accent" flat>
|
||||
<v-card v-if="loaded" class="ml-2 mr-2 background" flat>
|
||||
<v-card-title
|
||||
class="mt-2"
|
||||
style="
|
||||
|
@ -65,7 +65,7 @@
|
|||
|
||||
<!-- <v-bottom-sheet
|
||||
v-model="showMore"
|
||||
color="accent"
|
||||
color="background"
|
||||
style="z-index: 9999999"
|
||||
>
|
||||
<v-sheet style="padding: 1em">
|
||||
|
@ -78,7 +78,7 @@
|
|||
</div>
|
||||
</v-sheet>
|
||||
</v-bottom-sheet> -->
|
||||
<!-- <v-bottom-sheet v-model="share" color="accent" style="z-index: 9999999">
|
||||
<!-- <v-bottom-sheet v-model="share" color="background" style="z-index: 9999999">
|
||||
<v-sheet style="padding: 1em">
|
||||
<div class="scroll-y">
|
||||
{{ description }}
|
||||
|
@ -95,7 +95,7 @@
|
|||
import { Share } from "@capacitor/share";
|
||||
import ShelfRenderer from "~/components/SectionRenderers/shelfRenderer.vue";
|
||||
import VidLoadRenderer from "~/components/vidLoadRenderer.vue";
|
||||
import SlimVideoDescriptionRenderer from '~/components/UtilRenderers/slimVideoDescriptionRenderer.vue';
|
||||
import SlimVideoDescriptionRenderer from "~/components/UtilRenderers/slimVideoDescriptionRenderer.vue";
|
||||
|
||||
export default {
|
||||
components: { ShelfRenderer, VidLoadRenderer, SlimVideoDescriptionRenderer },
|
||||
|
|
|
@ -4,6 +4,7 @@ import { StatusBar, Style } from "@capacitor/status-bar";
|
|||
import { NavigationBar } from "@hugotomazi/capacitor-navigation-bar";
|
||||
import constants from "./constants";
|
||||
import { hexToRgb, rgbToHex } from "./utils";
|
||||
import { Haptics, ImpactStyle } from "@capacitor/haptics";
|
||||
|
||||
const module = {
|
||||
//--- Get GitHub Commits ---//
|
||||
|
@ -37,6 +38,21 @@ const module = {
|
|||
});
|
||||
},
|
||||
|
||||
haptics: {
|
||||
async hapticsImpactHeavy(x) {
|
||||
await Haptics.impact({ style: ImpactStyle.Heavy, duration: x });
|
||||
},
|
||||
async hapticsImpactMedium(x) {
|
||||
await Haptics.impact({ style: ImpactStyle.Medium, duration: x });
|
||||
},
|
||||
async hapticsImpactLight(x) {
|
||||
await Haptics.impact({ style: ImpactStyle.Light, duration: x });
|
||||
},
|
||||
async hapticsVibrate(x) {
|
||||
await Haptics.vibrate(x);
|
||||
},
|
||||
},
|
||||
|
||||
statusBar: {
|
||||
async hide() {
|
||||
return await StatusBar.hide();
|
||||
|
@ -54,7 +70,13 @@ const module = {
|
|||
return StatusBar.setOverlaysWebView({ overlay: true });
|
||||
},
|
||||
async setBackground(color) {
|
||||
return await StatusBar.setBackgroundColor({ color: color });
|
||||
return await StatusBar.setBackgroundColor({ color });
|
||||
},
|
||||
async setTheme(color, dark) {
|
||||
dark
|
||||
? StatusBar.setStyle({ style: Style.Dark })
|
||||
: StatusBar.setStyle({ style: Style.Light });
|
||||
StatusBar.setBackgroundColor({ color });
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -65,6 +87,12 @@ const module = {
|
|||
async show() {
|
||||
return await NavigationBar.show();
|
||||
},
|
||||
async setTheme(color, darkButtons) {
|
||||
return await NavigationBar.setColor({ color, darkButtons });
|
||||
},
|
||||
async setTransparent() {
|
||||
return NavigationBar.setTransparency({ isTransparent: true });
|
||||
},
|
||||
},
|
||||
|
||||
hexToRgb(hex) {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="$USER_HOME$/.android/avd/Pixel_5_API_31.avd" />
|
||||
<value value="$USER_HOME$/.android/avd/Pixel_3a_API_31_arm64-v8a.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2022-03-23T18:18:11.698053Z" />
|
||||
<timeTargetWasSelectedWithDropDown value="2022-03-31T22:44:20.197073Z" />
|
||||
</component>
|
||||
</project>
|
|
@ -13,6 +13,7 @@ dependencies {
|
|||
implementation project(':capacitor-app')
|
||||
implementation project(':capacitor-browser')
|
||||
implementation project(':capacitor-device')
|
||||
implementation project(':capacitor-haptics')
|
||||
implementation project(':capacitor-share')
|
||||
implementation project(':capacitor-splash-screen')
|
||||
implementation project(':capacitor-status-bar')
|
||||
|
|
|
@ -7,19 +7,20 @@
|
|||
"hostname": "youtube.com",
|
||||
"androidScheme": "https"
|
||||
},
|
||||
"android": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"ios": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"plugins": {
|
||||
"SplashScreen": {
|
||||
"launchShowDuration": 0,
|
||||
"launchAutoHide": true,
|
||||
"backgroundColor": "#111111",
|
||||
"androidSplashResourceName": "splash",
|
||||
"androidScaleType": "CENTER_CROP",
|
||||
"androidSpinnerStyle": "large",
|
||||
"iosSpinnerStyle": "small",
|
||||
"spinnerColor": "#999999",
|
||||
"showSpinner": false,
|
||||
"backgroundColor": "#000000",
|
||||
"splashFullScreen": false,
|
||||
"splashImmersive": false
|
||||
"splashImmersive": false,
|
||||
"launchAutoHide": true,
|
||||
"showSpinner": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
"pkg": "@capacitor/device",
|
||||
"classpath": "com.capacitorjs.plugins.device.DevicePlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/haptics",
|
||||
"classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/share",
|
||||
"classpath": "com.capacitorjs.plugins.share.SharePlugin"
|
||||
|
|
|
@ -14,6 +14,9 @@ project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/
|
|||
include ':capacitor-device'
|
||||
project(':capacitor-device').projectDir = new File('../node_modules/@capacitor/device/android')
|
||||
|
||||
include ':capacitor-haptics'
|
||||
project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')
|
||||
|
||||
include ':capacitor-share'
|
||||
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
|
||||
|
||||
|
|
|
@ -9,20 +9,21 @@
|
|||
"androidScheme": "https"
|
||||
},
|
||||
|
||||
"android": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"ios": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
|
||||
"plugins": {
|
||||
"SplashScreen": {
|
||||
"launchShowDuration": 0,
|
||||
"launchAutoHide": true,
|
||||
"backgroundColor": "#111111",
|
||||
"androidSplashResourceName": "splash",
|
||||
"androidScaleType": "CENTER_CROP",
|
||||
"androidSpinnerStyle": "large",
|
||||
"iosSpinnerStyle": "small",
|
||||
"spinnerColor": "#999999",
|
||||
"showSpinner": false,
|
||||
"backgroundColor": "#000000",
|
||||
"splashFullScreen": false,
|
||||
"splashImmersive": false
|
||||
"splashImmersive": false,
|
||||
"launchAutoHide": true,
|
||||
"showSpinner": false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,19 +7,20 @@
|
|||
"hostname": "youtube.com",
|
||||
"androidScheme": "https"
|
||||
},
|
||||
"android": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"ios": {
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"plugins": {
|
||||
"SplashScreen": {
|
||||
"launchShowDuration": 0,
|
||||
"launchAutoHide": true,
|
||||
"backgroundColor": "#111111",
|
||||
"androidSplashResourceName": "splash",
|
||||
"androidScaleType": "CENTER_CROP",
|
||||
"androidSpinnerStyle": "large",
|
||||
"iosSpinnerStyle": "small",
|
||||
"spinnerColor": "#999999",
|
||||
"showSpinner": false,
|
||||
"backgroundColor": "#000000",
|
||||
"splashFullScreen": false,
|
||||
"splashImmersive": false
|
||||
"splashImmersive": false,
|
||||
"launchAutoHide": true,
|
||||
"showSpinner": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,15 @@ install! 'cocoapods', :disable_input_output_paths => true
|
|||
def capacitor_pods
|
||||
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
||||
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
||||
pod 'CapacitorCommunityHttp', :path => '..\..\node_modules\@capacitor-community\http'
|
||||
pod 'CapacitorApp', :path => '..\..\node_modules\@capacitor\app'
|
||||
pod 'CapacitorBrowser', :path => '..\..\node_modules\@capacitor\browser'
|
||||
pod 'CapacitorDevice', :path => '..\..\node_modules\@capacitor\device'
|
||||
pod 'CapacitorShare', :path => '..\..\node_modules\@capacitor\share'
|
||||
pod 'CapacitorSplashScreen', :path => '..\..\node_modules\@capacitor\splash-screen'
|
||||
pod 'CapacitorStatusBar', :path => '..\..\node_modules\@capacitor\status-bar'
|
||||
pod 'HugotomaziCapacitorNavigationBar', :path => '..\..\node_modules\@hugotomazi\capacitor-navigation-bar'
|
||||
pod 'CapacitorCommunityHttp', :path => '../../node_modules/@capacitor-community/http'
|
||||
pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
|
||||
pod 'CapacitorBrowser', :path => '../../node_modules/@capacitor/browser'
|
||||
pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device'
|
||||
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
||||
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
|
||||
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
||||
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
||||
pod 'HugotomaziCapacitorNavigationBar', :path => '../../node_modules/@hugotomazi/capacitor-navigation-bar'
|
||||
end
|
||||
|
||||
target 'App' do
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"@capacitor/cli": "^3.4.0",
|
||||
"@capacitor/core": "^3.4.0",
|
||||
"@capacitor/device": "^1.1.2",
|
||||
"@capacitor/haptics": "^1.1.4",
|
||||
"@capacitor/share": "^1.1.2",
|
||||
"@capacitor/splash-screen": "^1.2.2",
|
||||
"@capacitor/status-bar": "^1.0.8",
|
||||
|
|
|
@ -38,11 +38,7 @@ Well this has been thrown around on the Return Youtube Dislike discord server fo
|
|||
Also, YouTube Vanced just shut down
|
||||
|
||||
## Screenshots
|
||||
<img src="https://github.com/Frontesque/VueTube/raw/main/Icons/screenshots/home.PNG" alt="VueTube Home" width="400"/>
|
||||
|
||||
<img src="https://github.com/Frontesque/VueTube/raw/main/Icons/screenshots/search.PNG" alt="VueTube Search" width="400"/>
|
||||
|
||||
<img src="https://github.com/Frontesque/VueTube/raw/main/Icons/screenshots/watch.PNG" alt="VueTube Watch" width="400"/>
|
||||
[View on our website: https://vuetube.app/info/screenshots](https://vuetube.app/info/screenshots)
|
||||
|
||||
## Want to contribute?
|
||||
Please read our website on how to do so: https://vuetube.app/contributing
|
||||
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 131 KiB |
|
@ -9,7 +9,7 @@ function hot {
|
|||
while true; do
|
||||
b=`ls -lahR $* | grep -v 'node_modules'`
|
||||
# to avoid confusing myself with nested-if - it is a "short form" of doing a=$b; eval $script if $a != $b.
|
||||
[[ $a != $b ]] && a=$b && eval $script;
|
||||
[[ $a != $b ]] && a=$b && eval time $script;
|
||||
sleep .5;
|
||||
done
|
||||
fi
|
||||
|
|