v0.3.2
change: navigation bar app version link to home page. change: gif format $PostTile preview action will same as video format. new: gif format $PostTile will display format detail. change: navigation bar background change to transparency blur. change: searchbar selection list scrollbar width smaller.
This commit is contained in:
parent
1a6d0e580f
commit
6104d9003f
1
dist/assets/index-BfZu1R1a.js
vendored
Normal file
1
dist/assets/index-BfZu1R1a.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/index-C8Fnii2g.js
vendored
1
dist/assets/index-C8Fnii2g.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/index-CbgOs0Kp.css
vendored
1
dist/assets/index-CbgOs0Kp.css
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/index-qRel_iFf.css
vendored
Normal file
1
dist/assets/index-qRel_iFf.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
dist/index.html
vendored
4
dist/index.html
vendored
@ -7,8 +7,8 @@
|
|||||||
<title>Danbooru Viewer v0.2.5</title>
|
<title>Danbooru Viewer v0.2.5</title>
|
||||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||||
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
||||||
<script type="module" crossorigin src="/assets/index-C8Fnii2g.js"></script>
|
<script type="module" crossorigin src="/assets/index-BfZu1R1a.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CbgOs0Kp.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-qRel_iFf.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
43
index.scss
43
index.scss
@ -45,47 +45,56 @@ nav {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
background-color: var(--background-color);
|
background-color: color-mix(in srgb, var(--background-color) 70%, transparent);
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
|
||||||
div.title {
|
a.title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.4rem;
|
gap: 0.4rem;
|
||||||
a.booru-name {
|
|
||||||
color: var(--secondary-color);
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
h1 {
|
.booru-name {
|
||||||
|
color: var(--secondary-color);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
a.version {
|
.app {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
// border: 1px solid var(--secondary-color);
|
||||||
|
// padding: 0.2rem 0.4rem;
|
||||||
|
margin: 0;
|
||||||
|
gap: 0.4rem;
|
||||||
|
.version {
|
||||||
color: var(--background-color);
|
color: var(--background-color);
|
||||||
background-color: var(--secondary-color);
|
background-color: var(--secondary-color);
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
text-decoration: none;
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.app-name {
|
||||||
|
display: none;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--secondary-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button {
|
|
||||||
padding: 2px 4px;
|
|
||||||
border-radius: 0.4rem;
|
|
||||||
border: none;
|
|
||||||
}
|
}
|
||||||
div.searchbar {
|
div.searchbar {
|
||||||
padding: 0.4rem 10%;
|
padding: 0.4rem 10%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
background-color: var(--background-color);
|
background-color: color-mix(in srgb, var(--background-color-light) 30%, transparent);
|
||||||
border: 1px solid var(--primary-color-darker);
|
border: 1px solid var(--primary-color-darker);
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
color: var(--primary-color-dark);
|
color: var(--primary-color-dark);
|
||||||
|
transition: 0.3s all ease;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--background-color-light);
|
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,12 +103,12 @@ nav {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
ion-icon {
|
ion-icon {
|
||||||
background-color: var(--background-color);
|
// background-color: var(--background-color);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
padding: 0.4rem;
|
padding: 0.4rem;
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--background-color-lighter);
|
background-color: color-mix(in srgb, var(--background-color-lighter) 50%, transparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ion-icon.search {
|
ion-icon.search {
|
||||||
@ -120,12 +129,12 @@ nav {
|
|||||||
router {
|
router {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: var(--nav-height);
|
|
||||||
|
|
||||||
route {
|
route {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-inline: 10px;
|
padding-inline: 10px;
|
||||||
|
padding-top: var(--nav-height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "danbooru-viewer",
|
"name": "danbooru-viewer",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.3.1",
|
"version": "0.3.2",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
"vite": "^5.4.8"
|
"vite": "^5.4.8"
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
layout.post-grid {
|
layout.post-grid {
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { $Container, $State, $Video } from "elexis";
|
import { $Container, $Image, $State, $Video } from "elexis";
|
||||||
import type { Post } from "../../structure/Post";
|
import type { Post } from "../../structure/Post";
|
||||||
import { time } from "../../structure/Util";
|
import { time } from "../../structure/Util";
|
||||||
export class $PostTile extends $Container {
|
export class $PostTile extends $Container {
|
||||||
@ -8,7 +8,7 @@ export class $PostTile extends $Container {
|
|||||||
constructor(post: Post) {
|
constructor(post: Post) {
|
||||||
super('post-tile');
|
super('post-tile');
|
||||||
this.post = post;
|
this.post = post;
|
||||||
this.$video = this.post.isVideo ? $('video').width(this.post.image_width).height(this.post.image_height).disablePictureInPicture(true).loop(true).muted(true).hide(true) : null;
|
this.$video = this.post.isVideo ? $('video').width(this.post.image_width).height(this.post.image_height).disablePictureInPicture(true).loop(true).muted(true).hide(true).on('mousedown', (e) => e.preventDefault()) : null;
|
||||||
this.attribute('filetype', this.post.file_ext);
|
this.attribute('filetype', this.post.file_ext);
|
||||||
this.durationUpdate();
|
this.durationUpdate();
|
||||||
this.build();
|
this.build();
|
||||||
@ -32,33 +32,27 @@ export class $PostTile extends $Container {
|
|||||||
this.post.hasSound ? $('ion-icon').name('volume-medium-outline') : null,
|
this.post.hasSound ? $('ion-icon').name('volume-medium-outline') : null,
|
||||||
$('span').class('duration').content(this.duration$)
|
$('span').class('duration').content(this.duration$)
|
||||||
]) : null,
|
]) : null,
|
||||||
|
// Gif
|
||||||
|
this.post.isGif
|
||||||
|
? $('div').class('gif-detail').content([
|
||||||
|
$('span').content('GIF')
|
||||||
|
]) : null,
|
||||||
// Tile
|
// Tile
|
||||||
$('a').href(this.post.pathname).content(() => [
|
$('a').href(this.post.pathname).content(() => [
|
||||||
this.$video,
|
this.$video,
|
||||||
$('img').draggable(false).css({opacity: '0'}).width(this.post.image_width).height(this.post.image_height).src(this.post.previewURL).loading('lazy')
|
$('img').draggable(false).css({opacity: '0'}).width(this.post.image_width).height(this.post.image_height).src(this.post.previewURL).loading('lazy')
|
||||||
.on('mousedown', (e) => e.preventDefault())
|
.on('mousedown', (e) => e.preventDefault())
|
||||||
.once('load', (e, $img) => {
|
.once('load', (e, $img) => {
|
||||||
if (!this.post.isVideo) $img.src(this.post.previewURL);
|
$img
|
||||||
$img.animate({opacity: [0, 1]}, {duration: 300, fill: 'both'});
|
.src(this.post.previewURL)
|
||||||
this.removeClass('loading')
|
.on(['mouseenter', 'touchstart'], () => { if (this.post.isGif) { $img.src(this.post.large_file_url) } })
|
||||||
|
.on(['mouseleave', 'touchend', 'touchcancel'], () => { if (this.post.isGif) { $img.src(this.post.previewURL) } })
|
||||||
|
.animate({opacity: [0, 1]}, {duration: 300, fill: 'both'});
|
||||||
|
this.removeClass('loading');
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
.on('mouseenter', () => {
|
.on(['mouseenter', 'touchstart'], () => { if (!this.$video?.isPlaying) { this.$video?.src(this.post.large_file_url).hide(false).play().catch(err => undefined) } })
|
||||||
if (!this.$video?.isPlaying) {
|
.on(['mouseleave', 'touchend', 'touchcancel'], () => { this.$video?.pause().currentTime(0).hide(true); })
|
||||||
this.$video?.src(this.post.large_file_url).hide(false).play().catch(err => undefined)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('mouseleave', () => {
|
|
||||||
this.$video?.pause().currentTime(0).hide(true);
|
|
||||||
})
|
|
||||||
.on('touchstart', () => {
|
|
||||||
if (!this.$video?.isPlaying) {
|
|
||||||
this.$video?.src(this.post.large_file_url).hide(false).play().catch(err => undefined)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('touchend', () => {
|
|
||||||
this.$video?.pause().currentTime(0).hide(true);
|
|
||||||
})
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ post-tile {
|
|||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
div.video-detail {
|
div.video-detail, div.gif-detail {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: var(--background-color-lighter);//color-mix(in srgb, var(--background-color-lighter) 80%, transparent);
|
background-color: var(--background-color-lighter);//color-mix(in srgb, var(--background-color-lighter) 80%, transparent);
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
|
@ -10,7 +10,7 @@ searchbar {
|
|||||||
|
|
||||||
div.input-container {
|
div.input-container {
|
||||||
margin-top: 0.4rem;
|
margin-top: 0.4rem;
|
||||||
background-color: var(--background-color-light);
|
background-color: color-mix(in srgb, var(--background-color-light) 70%, transparent);
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
@ -71,6 +71,10 @@ searchbar {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
selection {
|
selection {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
29
src/main.ts
29
src/main.ts
@ -31,9 +31,12 @@ $(document.body).content([
|
|||||||
// Navigation Bar
|
// Navigation Bar
|
||||||
$('nav').content([
|
$('nav').content([
|
||||||
// Title
|
// Title
|
||||||
$('div').class('title').content([
|
$('a').class('title').href('/').content([
|
||||||
$('a').class('booru-name').content([$('h1').content(Booru.name$)]).href('/'),
|
$('h1').class('booru-name').content(Booru.name$),
|
||||||
$('a').class('version').target('_blank').content(`v${__APP_VERSION__}`).href(`https://git.defaultkavy.com/defaultkavy/danbooru-viewer`)
|
$('h2').class('app').content([
|
||||||
|
$('span').class('app-name').content(`Viewer`),
|
||||||
|
$('span').class('version').content(`v${__APP_VERSION__}`)
|
||||||
|
])
|
||||||
]),
|
]),
|
||||||
// Searchbar
|
// Searchbar
|
||||||
$('div').class('searchbar').content(['Search in ', Booru.name$])
|
$('div').class('searchbar').content(['Search in ', Booru.name$])
|
||||||
@ -65,13 +68,21 @@ $(document.body).content([
|
|||||||
post_route
|
post_route
|
||||||
]).on('beforeSwitch', (e) => {
|
]).on('beforeSwitch', (e) => {
|
||||||
const DURATION = 300;
|
const DURATION = 300;
|
||||||
|
const TX = 2;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
function intro() {
|
function intro() {
|
||||||
|
const transform = $.call(() => {
|
||||||
|
switch ($Router.navigationDirection) {
|
||||||
|
case $RouterNavigationDirection.Forward: return [`translateX(${TX}%)`, `translateX(0%)`];
|
||||||
|
case $RouterNavigationDirection.Back: return [`translateX(-${TX}%)`, `translateX(0%)`];
|
||||||
|
case $RouterNavigationDirection.Replace: return undefined;
|
||||||
|
}
|
||||||
|
})
|
||||||
e.$view.content(e.nextContent);
|
e.$view.content(e.nextContent);
|
||||||
e.rendered();
|
e.rendered();
|
||||||
e.nextContent.element?.class('animated').animate({
|
e.nextContent.element?.class('animated').animate({
|
||||||
opacity: [0, 1],
|
opacity: [0, 1],
|
||||||
transform: $Router.navigationDirection === $RouterNavigationDirection.Forward ? [`translateX(40%)`, `translateX(0%)`] : [`translateX(-40%)`, `translateX(0%)`]
|
transform
|
||||||
}, {
|
}, {
|
||||||
duration: DURATION,
|
duration: DURATION,
|
||||||
easing: 'ease'
|
easing: 'ease'
|
||||||
@ -81,9 +92,17 @@ $(document.body).content([
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
function outro() {
|
function outro() {
|
||||||
|
const transform = $.call(() => {
|
||||||
|
switch ($Router.navigationDirection) {
|
||||||
|
case $RouterNavigationDirection.Forward: return [`translateX(0%)`, `translateX(-${TX}%)`];
|
||||||
|
case $RouterNavigationDirection.Back: return [`translateX(0%)`, `translateX(${TX}%)`];
|
||||||
|
case $RouterNavigationDirection.Replace: return undefined;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
e.previousContent?.element?.class('animated').animate({
|
e.previousContent?.element?.class('animated').animate({
|
||||||
opacity: [1, 0],
|
opacity: [1, 0],
|
||||||
transform: $Router.navigationDirection === $RouterNavigationDirection.Forward ? [`translateX(0%)`, `translateX(-40%)`] : [`translateX(0%)`, `translateX(40%)`]
|
transform
|
||||||
}, {
|
}, {
|
||||||
duration: DURATION,
|
duration: DURATION,
|
||||||
easing: 'ease'
|
easing: 'ease'
|
||||||
|
@ -31,7 +31,7 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro
|
|||||||
let scrollTop = 0;
|
let scrollTop = 0;
|
||||||
addEventListener('scroll', () => { if ($sidebar.inDOM()) scrollTop = document.documentElement.scrollTop })
|
addEventListener('scroll', () => { if ($sidebar.inDOM()) scrollTop = document.documentElement.scrollTop })
|
||||||
$route
|
$route
|
||||||
.on('beforeShift', () => { if (innerWidth > 800) $sidebar.css({position: `absolute`, top: `${scrollTop}px`}) })
|
.on('beforeShift', () => { if (innerWidth > 800) $sidebar.css({position: `absolute`, top: `calc(${scrollTop}px + var(--nav-height) + var(--padding))`}) })
|
||||||
.on('afterShift', () => $sidebar.css({position: '', top: ''}))
|
.on('afterShift', () => $sidebar.css({position: '', top: ''}))
|
||||||
})
|
})
|
||||||
.content([
|
.content([
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#post {
|
#post {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
padding-top: var(--nav-height);
|
||||||
section {
|
section {
|
||||||
background-color: #2f2f45;
|
background-color: #2f2f45;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@ -39,7 +40,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.content {
|
div.content {
|
||||||
width: calc(100vw - 300px - 4rem);
|
width: calc(100vw - 300px - 2rem);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@ -73,9 +74,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.sidebar {
|
div.sidebar {
|
||||||
|
--padding: 1rem;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: calc(var(--nav-height) + 1rem);
|
top: calc(var(--nav-height) + var(--padding));
|
||||||
right: 1rem;
|
right: var(--padding);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.4rem;
|
gap: 0.4rem;
|
||||||
|
@ -95,6 +95,7 @@ export class Post extends $EventManager<{update: []}> {
|
|||||||
get uploader() { return User.manager.get(this.uploader_id); }
|
get uploader() { return User.manager.get(this.uploader_id); }
|
||||||
get approver() { if (this.approver_id) return User.manager.get(this.approver_id); else return null }
|
get approver() { if (this.approver_id) return User.manager.get(this.approver_id); else return null }
|
||||||
get isVideo() { return this.file_ext === 'mp4' || this.file_ext === 'webm' || this.file_ext === 'zip' }
|
get isVideo() { return this.file_ext === 'mp4' || this.file_ext === 'webm' || this.file_ext === 'zip' }
|
||||||
|
get isGif() { return this.file_ext === 'gif' }
|
||||||
get hasSound() { return this.tag_string_meta.includes('sound') }
|
get hasSound() { return this.tag_string_meta.includes('sound') }
|
||||||
get tags() {
|
get tags() {
|
||||||
const tag_list = this.tag_string.split(' ');
|
const tag_list = this.tag_string.split(' ');
|
||||||
|
Loading…
Reference in New Issue
Block a user