v0.3.3
update: $Router package. new: open in original site button. change: searchbar input background remove transparency. change: post page video player disable picture in picture. new: post page sidebar detail add copy file link button and copy webm link button. new: ugoria format will show icon on $PostTile. new: $IconButton new: Post.isUgoria
This commit is contained in:
parent
6104d9003f
commit
86c2d5aa9f
1
dist/assets/index-B240dcNf.css
vendored
Normal file
1
dist/assets/index-B240dcNf.css
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
1
dist/assets/index-qRel_iFf.css
vendored
1
dist/assets/index-qRel_iFf.css
vendored
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>
|
||||
<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 type="module" crossorigin src="/assets/index-BfZu1R1a.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-qRel_iFf.css">
|
||||
<script type="module" crossorigin src="/assets/index-C21fHnwq.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B240dcNf.css">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
@ -1,6 +1,7 @@
|
||||
@import '/src/component/PostGrid/$PostGrid';
|
||||
@import '/src/component/PostTile/$PostTile';
|
||||
@import '/src/component/Searchbar/$Searchbar';
|
||||
@import '/src/component/IconButton/$IconButton';
|
||||
@import '/src/route/post/$post';
|
||||
@import '/src/route/gallery/$gallery';
|
||||
|
||||
@ -139,9 +140,10 @@ router {
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #aeaeec;
|
||||
padding: 2px 4px;
|
||||
border-radius: 0.4rem;
|
||||
background-color: var(--secondary-color-dark);
|
||||
color: var(--secondary-color);
|
||||
padding: 0.8rem 1.2rem;
|
||||
border-radius: 1rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "danbooru-viewer",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"vite": "^5.4.8"
|
||||
|
28
src/component/IconButton/$IconButton.ts
Normal file
28
src/component/IconButton/$IconButton.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { $Button, type $ContainerContentBuilder } from "elexis";
|
||||
|
||||
export class $IconButton extends $Button {
|
||||
$icon = $('ion-icon');
|
||||
$label = $('span');
|
||||
constructor() {
|
||||
super();
|
||||
this.addStaticClass('icon')
|
||||
this.build();
|
||||
}
|
||||
|
||||
private build() {
|
||||
super.content([
|
||||
this.$icon,
|
||||
this.$label
|
||||
])
|
||||
}
|
||||
|
||||
content(children: $ContainerContentBuilder<typeof this.$label>): this {
|
||||
this.$label.content(children);
|
||||
return this;
|
||||
}
|
||||
|
||||
icon(name: string) {
|
||||
this.$icon.name(name);
|
||||
return this;
|
||||
}
|
||||
}
|
19
src/component/IconButton/_$IconButton.scss
Normal file
19
src/component/IconButton/_$IconButton.scss
Normal file
@ -0,0 +1,19 @@
|
||||
button.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.4rem;
|
||||
background-color: transparent;
|
||||
ion-icon {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--background-color-light);
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ export class $PostTile extends $Container {
|
||||
this.post.isVideo
|
||||
? $('div').class('video-detail').content([
|
||||
this.post.hasSound ? $('ion-icon').name('volume-medium-outline') : null,
|
||||
this.post.isUgoria ? $('ion-icon').name('images-outline') : null,
|
||||
$('span').class('duration').content(this.duration$)
|
||||
]) : null,
|
||||
// Gif
|
||||
|
@ -29,7 +29,8 @@ post-tile {
|
||||
color: var(--primary-color);
|
||||
bottom: 0.3rem;
|
||||
right: 0.3rem;
|
||||
padding: 2px 4px;
|
||||
padding: 0.2em 0.4em;
|
||||
height: 1rem;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
@ -39,7 +40,12 @@ post-tile {
|
||||
// text-shadow: 0 0 0.5em var(--background-color);
|
||||
|
||||
ion-icon {
|
||||
font-size: 1.5em;
|
||||
font-size: 1.4rem;
|
||||
|
||||
&[name="images-outline"] {
|
||||
padding: 0.1rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
span.duration {
|
||||
|
@ -10,7 +10,7 @@ searchbar {
|
||||
|
||||
div.input-container {
|
||||
margin-top: 0.4rem;
|
||||
background-color: color-mix(in srgb, var(--background-color-light) 70%, transparent);
|
||||
background-color: color-mix(in srgb, var(--background-color-light) 100%, transparent);
|
||||
border-radius: 0.4rem;
|
||||
font-size: 1rem;
|
||||
width: 500px;
|
||||
|
12
src/main.ts
12
src/main.ts
@ -7,15 +7,18 @@ import { $PostGrid } from './component/PostGrid/$PostGrid';
|
||||
import { $Router, $RouterNavigationDirection } from '@elexis/router';
|
||||
import { $Searchbar } from './component/Searchbar/$Searchbar';
|
||||
import { $IonIcon } from './component/IonIcon/$IonIcon';
|
||||
import { $IconButton } from './component/IconButton/$IconButton';
|
||||
// declare elexis module
|
||||
declare module 'elexis' {
|
||||
export namespace $ {
|
||||
export interface TagNameElementMap {
|
||||
'ion-icon': typeof $IonIcon
|
||||
'ion-icon': typeof $IonIcon;
|
||||
'icon-button': typeof $IconButton;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.registerTagName('ion-icon', $IonIcon)
|
||||
$.registerTagName('icon-button', $IconButton)
|
||||
$.anchorHandler = ($a) => { $.open($a.href(), $a.target())}
|
||||
// settings
|
||||
export const [danbooru, safebooru]: Booru[] = [
|
||||
@ -48,12 +51,15 @@ $(document.body).content([
|
||||
$('ion-icon').class('search').name('search-outline').title('Search')
|
||||
.self($self => $Router.events.on('stateChange', ({beforeURL, afterURL}) => {if (beforeURL.hash === '#search') $self.hide(false); if (afterURL.hash === '#search') $self.hide(true)}))
|
||||
.on('click', () => $.open(location.href + '#search')),
|
||||
// Switch Button
|
||||
// Switch Booru
|
||||
$('ion-icon').class('switch').name('swap-horizontal').title('Switch Booru')
|
||||
.on('click', () => {
|
||||
if (Booru.used === danbooru) Booru.set(safebooru);
|
||||
else Booru.set(danbooru);
|
||||
})
|
||||
}),
|
||||
// Open Booru
|
||||
$('ion-icon').class('open').name('open-outline').title('Open in Original Site')
|
||||
.on('click', () => $.open(location.href.replace(location.origin, Booru.used.origin))),
|
||||
])
|
||||
]),
|
||||
// Searchbar
|
||||
|
@ -11,7 +11,7 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro
|
||||
$('div').class('viewer').content(async () => {
|
||||
await post.ready;
|
||||
return post.isVideo
|
||||
? $('video').height(post.image_height).width(post.image_width).src(post.file_ext === 'zip' ? post.large_file_url : post.file_url).controls(true).autoplay(true).loop(true)
|
||||
? $('video').height(post.image_height).width(post.image_width).src(post.file_ext === 'zip' ? post.large_file_url : post.file_url).controls(true).autoplay(true).loop(true).disablePictureInPicture(true)
|
||||
: $('img').src(post.large_file_url)//.once('load', (e, $img) => { $img.src(post.file_url)})
|
||||
}),
|
||||
$('div').class('content').content([
|
||||
@ -46,14 +46,36 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro
|
||||
new $Property('favorites').name('Favorites').value(post.favorites$),
|
||||
new $Property('score').name('Score').value(post.score$)
|
||||
]),
|
||||
$('button').content('Copy link').on('click', (e, $button) => {
|
||||
e.preventDefault();
|
||||
navigator.clipboard.writeText(`${Booru.used.origin}${location.pathname}`);
|
||||
$button.content('Copied!');
|
||||
setTimeout(() => {
|
||||
$button.content('Copy link')
|
||||
}, 2000);
|
||||
})
|
||||
$('div').class('buttons').content([
|
||||
$('icon-button').class('vertical').icon('link-outline').content(Booru.name$)
|
||||
.on('click', (e, $button) => {
|
||||
e.preventDefault();
|
||||
navigator.clipboard.writeText(`${Booru.used.origin}${location.pathname}`);
|
||||
$button.content('Copied!');
|
||||
setTimeout(() => {
|
||||
$button.content(Booru.name$)
|
||||
}, 2000);
|
||||
}),
|
||||
$('icon-button').class('vertical').icon('link-outline').content(`File`)
|
||||
.on('click', (e, $button) => {
|
||||
e.preventDefault();
|
||||
navigator.clipboard.writeText(post.file_url);
|
||||
$button.content('Copied!');
|
||||
setTimeout(() => {
|
||||
$button.content('File')
|
||||
}, 2000);
|
||||
}),
|
||||
$('icon-button').class('vertical').icon('link-outline').content(`Webm`)
|
||||
.on('click', (e, $button) => {
|
||||
e.preventDefault();
|
||||
navigator.clipboard.writeText(post.previewURL);
|
||||
$button.content('Copied!');
|
||||
setTimeout(() => {
|
||||
$button.content('Webm')
|
||||
}, 2000);
|
||||
})
|
||||
.hide(true).self(async ($button) => { await post.ready; if (post.file_ext === 'zip') $button.hide(false) })
|
||||
]),
|
||||
]),
|
||||
$('div').class('post-tags').content(async $tags => {
|
||||
const tags = await post.fetchTags();
|
||||
|
@ -116,6 +116,13 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
|
||||
.buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
div.property {
|
||||
|
@ -96,6 +96,7 @@ export class Post extends $EventManager<{update: []}> {
|
||||
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 isGif() { return this.file_ext === 'gif' }
|
||||
get isUgoria() { return this.file_ext === 'zip' }
|
||||
get hasSound() { return this.tag_string_meta.includes('sound') }
|
||||
get tags() {
|
||||
const tag_list = this.tag_string.split(' ');
|
||||
|
Loading…
Reference in New Issue
Block a user