Started using custom video controls
This commit is contained in:
parent
da716fc3aa
commit
11865a6500
@ -9,10 +9,17 @@ component AMVMini(amv *arn.AMV, user *arn.User)
|
||||
AMVMiniFooter(amv, user)
|
||||
|
||||
component AMVVideo(amv *arn.AMV)
|
||||
.video-container
|
||||
video.video.lazy(controls, controlsList="nodownload")
|
||||
.video-container(id=amv.ID)
|
||||
video.video.media-play-area.lazy.action(data-action="playVideo", data-trigger="click", data-media-id=amv.ID)
|
||||
source(data-src="https://notify.moe/videos/amvs/" + amv.File, data-type="video/webm")
|
||||
|
||||
//- button.media-play-button
|
||||
//- RawIcon("play")
|
||||
|
||||
.video-controls
|
||||
button.video-control.action(data-action="toggleFullscreen", data-trigger="click", data-id=amv.ID)
|
||||
RawIcon("square-o")
|
||||
|
||||
component AMVFooter(amv *arn.AMV, user *arn.User)
|
||||
.amv-footer
|
||||
if amv.Title.ByUser(user) == ""
|
||||
|
@ -19,12 +19,13 @@ component SoundTrackContent(track *arn.SoundTrack, user *arn.User)
|
||||
component SoundTrackMedia(track *arn.SoundTrack)
|
||||
if track.File != "" && track.HasMediaByService("Youtube")
|
||||
.soundtrack-media
|
||||
.soundtrack-play-area.action(data-action="toggleAudio", data-trigger="click", data-audio-src="https://notify.moe/audio/" + track.File, data-soundtrack-id=track.ID)
|
||||
img.soundtrack-image.lazy(data-src="https://img.youtube.com/vi/" + track.MediaByService("Youtube")[0].ServiceID + "/0.jpg", alt=track.Title)
|
||||
button.soundtrack-play-button
|
||||
.media-play-area.action(data-action="toggleAudio", data-trigger="click", data-audio-src="https://notify.moe/audio/" + track.File, data-media-id=track.ID)
|
||||
img.media-image.lazy(data-src="https://img.youtube.com/vi/" + track.MediaByService("Youtube")[0].ServiceID + "/0.jpg", alt=track.Title)
|
||||
|
||||
button.media-play-button
|
||||
RawIcon("play")
|
||||
|
||||
.soundtrack-visualizer
|
||||
.media-visualizer
|
||||
.visualizer-box.visualizer-box-1
|
||||
.visualizer-box.visualizer-box-2
|
||||
.visualizer-box.visualizer-box-3
|
||||
|
@ -24,7 +24,7 @@
|
||||
min-height 112px
|
||||
height 112px
|
||||
|
||||
.soundtrack-play-button
|
||||
.media-play-button
|
||||
width 48px
|
||||
height 48px
|
||||
font-size 1rem
|
@ -17,7 +17,7 @@ component SoundTrackPage(track *arn.SoundTrack, user *arn.User)
|
||||
|
||||
if user != nil && media.Service == "Youtube" && track.File != ""
|
||||
.buttons
|
||||
button.action(data-action="playAudio", data-trigger="click", data-audio-src="/audio/" + track.File, data-soundtrack-id=track.ID)
|
||||
button.action(data-action="playAudio", data-trigger="click", data-audio-src="/audio/" + track.File, data-media-id=track.ID)
|
||||
Icon("play")
|
||||
span Play in background
|
||||
|
||||
|
@ -31,7 +31,7 @@ const soundtrack-margin = 1rem
|
||||
iframe
|
||||
width 100%
|
||||
|
||||
.soundtrack-image
|
||||
.media-image
|
||||
object-fit cover
|
||||
width 100%
|
||||
height 100%
|
||||
@ -39,7 +39,7 @@ const soundtrack-margin = 1rem
|
||||
filter brightness(100%)
|
||||
transition filter transition-speed ease
|
||||
|
||||
.soundtrack-play-button
|
||||
.media-play-button
|
||||
position absolute
|
||||
top 50%
|
||||
left 50%
|
||||
@ -56,7 +56,7 @@ const soundtrack-margin = 1rem
|
||||
.icon-play
|
||||
transform translateX(27%)
|
||||
|
||||
.soundtrack-visualizer
|
||||
.media-visualizer
|
||||
horizontal
|
||||
justify-content center
|
||||
align-items center
|
||||
@ -101,33 +101,6 @@ animation change-color
|
||||
100%
|
||||
background-color hsl(235, 100%, 68%)
|
||||
|
||||
.soundtrack-play-area
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
cursor pointer
|
||||
transition opacity 250ms ease
|
||||
|
||||
&.playing
|
||||
.soundtrack-play-button
|
||||
opacity 0
|
||||
|
||||
.soundtrack-visualizer
|
||||
opacity 1
|
||||
|
||||
.soundtrack-image
|
||||
filter brightness(0) !important
|
||||
|
||||
:hover
|
||||
.soundtrack-play-button
|
||||
color button-hover-color
|
||||
background button-hover-background
|
||||
|
||||
.soundtrack-image
|
||||
filter brightness(50%)
|
||||
|
||||
.soundtrack-footer
|
||||
media-footer
|
||||
|
||||
@ -142,7 +115,7 @@ animation change-color
|
||||
border-bottom-right-radius 0
|
||||
border-top-right-radius 0
|
||||
|
||||
.soundtrack-image
|
||||
.media-image
|
||||
border-bottom-left-radius 0
|
||||
border-top-left-radius 0
|
||||
|
||||
|
@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier"
|
||||
|
||||
// Play audio
|
||||
export function playAudio(arn: AnimeNotifier, element: HTMLElement) {
|
||||
arn.audioPlayer.play(element.dataset.soundtrackId, element.dataset.audioSrc)
|
||||
arn.audioPlayer.play(element.dataset.mediaId, element.dataset.audioSrc)
|
||||
}
|
||||
|
||||
// Pause audio
|
||||
@ -45,7 +45,7 @@ export function playPauseAudio(arn: AnimeNotifier) {
|
||||
export function toggleAudio(arn: AnimeNotifier, element: HTMLElement) {
|
||||
// If we're clicking on the same track again, stop playing.
|
||||
// Otherwise, start the track we clicked on.
|
||||
if(arn.currentSoundTrackId && element.dataset.soundtrackId === arn.currentSoundTrackId) {
|
||||
if(arn.currentMediaId && element.dataset.mediaId === arn.currentMediaId) {
|
||||
stopAudio(arn)
|
||||
} else {
|
||||
playAudio(arn, element)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import AnimeNotifier from "../AnimeNotifier"
|
||||
import Diff from "scripts/Diff";
|
||||
import Diff from "scripts/Diff"
|
||||
|
||||
// Follow user
|
||||
export async function followUser(arn: AnimeNotifier, element: HTMLElement) {
|
||||
|
37
scripts/Actions/Video.ts
Normal file
37
scripts/Actions/Video.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import AnimeNotifier from "../AnimeNotifier"
|
||||
|
||||
// Play video
|
||||
export function playVideo(arn: AnimeNotifier, video: HTMLVideoElement) {
|
||||
video.volume = arn.audioPlayer.volume
|
||||
|
||||
if(video.readyState >= 2) {
|
||||
togglePlayVideo(video)
|
||||
return
|
||||
}
|
||||
|
||||
video.load()
|
||||
|
||||
video.addEventListener("loadeddata", () => {
|
||||
togglePlayVideo(video)
|
||||
})
|
||||
}
|
||||
|
||||
function togglePlayVideo(video: HTMLVideoElement) {
|
||||
if(video.paused) {
|
||||
video.play()
|
||||
} else {
|
||||
video.pause()
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle fullscreen
|
||||
export function toggleFullscreen(arn: AnimeNotifier, button: HTMLElement) {
|
||||
let elementId = button.dataset.id
|
||||
let element = document.getElementById(elementId)
|
||||
|
||||
if(document.fullscreen) {
|
||||
document.exitFullscreen()
|
||||
} else {
|
||||
element.requestFullscreen()
|
||||
}
|
||||
}
|
@ -20,3 +20,4 @@ export * from "./SideBar"
|
||||
export * from "./StatusMessage"
|
||||
export * from "./Theme"
|
||||
export * from "./Upload"
|
||||
export * from "./Video"
|
@ -34,7 +34,7 @@ export default class AnimeNotifier {
|
||||
isLoading: boolean
|
||||
diffCompletedForCurrentPath: boolean
|
||||
lastReloadContentPath: string
|
||||
currentSoundTrackId: string
|
||||
currentMediaId: string
|
||||
serverEvents: ServerEvents
|
||||
|
||||
constructor(app: Application) {
|
||||
@ -160,7 +160,7 @@ export default class AnimeNotifier {
|
||||
Promise.resolve().then(() => this.displayLocalDates()),
|
||||
Promise.resolve().then(() => this.setSelectBoxValue()),
|
||||
Promise.resolve().then(() => this.textAreaFocus()),
|
||||
Promise.resolve().then(() => this.markPlayingSoundTrack()),
|
||||
Promise.resolve().then(() => this.markPlayingMedia()),
|
||||
Promise.resolve().then(() => this.assignActions()),
|
||||
Promise.resolve().then(() => this.updatePushUI()),
|
||||
Promise.resolve().then(() => this.dragAndDrop()),
|
||||
@ -639,9 +639,9 @@ export default class AnimeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
markPlayingSoundTrack() {
|
||||
for(let element of findAll("soundtrack-play-area")) {
|
||||
if(element.dataset.soundtrackId === this.currentSoundTrackId) {
|
||||
markPlayingMedia() {
|
||||
for(let element of findAll("media-play-area")) {
|
||||
if(element.dataset.mediaId === this.currentMediaId) {
|
||||
element.classList.add("playing")
|
||||
}
|
||||
}
|
||||
@ -893,7 +893,7 @@ export default class AnimeNotifier {
|
||||
lazyLoadVideo(video: HTMLVideoElement) {
|
||||
// Once the video becomes visible, load it
|
||||
video["became visible"] = () => {
|
||||
video.pause()
|
||||
// video.pause()
|
||||
|
||||
// Prevent context menu
|
||||
video.addEventListener("contextmenu", e => e.preventDefault())
|
||||
@ -907,11 +907,16 @@ export default class AnimeNotifier {
|
||||
element.src = element.dataset.src
|
||||
modified = true
|
||||
}
|
||||
|
||||
if(element.type !== element.dataset.type) {
|
||||
element.type = element.dataset.type
|
||||
modified = true
|
||||
}
|
||||
}
|
||||
|
||||
if(modified) {
|
||||
Diff.mutations.queue(() => {
|
||||
video.load()
|
||||
// video.load()
|
||||
video.classList.add("element-found")
|
||||
})
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ export default class AudioPlayer {
|
||||
// Stop current track
|
||||
this.stop()
|
||||
|
||||
this.arn.currentSoundTrackId = trackId
|
||||
this.arn.markPlayingSoundTrack()
|
||||
this.arn.currentMediaId = trackId
|
||||
this.arn.markPlayingMedia()
|
||||
this.arn.loading(true)
|
||||
|
||||
// Mark as loading
|
||||
@ -187,7 +187,7 @@ export default class AudioPlayer {
|
||||
|
||||
// Stop
|
||||
stop() {
|
||||
this.arn.currentSoundTrackId = undefined
|
||||
this.arn.currentMediaId = undefined
|
||||
|
||||
// Remove CSS class "playing"
|
||||
let playingElements = document.getElementsByClassName("playing")
|
||||
@ -242,6 +242,8 @@ export default class AudioPlayer {
|
||||
|
||||
// Set volume
|
||||
setVolume(volume: number) {
|
||||
this.volume = volume
|
||||
|
||||
if(!this.gainNode) {
|
||||
return
|
||||
}
|
||||
|
26
styles/media.scarlet
Normal file
26
styles/media.scarlet
Normal file
@ -0,0 +1,26 @@
|
||||
.media-play-area
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
cursor pointer
|
||||
transition opacity 250ms ease
|
||||
|
||||
&.playing
|
||||
.media-play-button
|
||||
opacity 0
|
||||
|
||||
.media-visualizer
|
||||
opacity 1
|
||||
|
||||
.media-image
|
||||
filter brightness(0) !important
|
||||
|
||||
:hover
|
||||
.media-play-button
|
||||
color button-hover-color
|
||||
background button-hover-background
|
||||
|
||||
.media-image
|
||||
filter brightness(50%)
|
@ -8,6 +8,10 @@ const video-padding = 56.25%
|
||||
border-radius ui-element-border-radius
|
||||
overflow hidden
|
||||
|
||||
:hover
|
||||
.video-controls
|
||||
opacity 1
|
||||
|
||||
.video
|
||||
position absolute
|
||||
width 100%
|
||||
@ -15,3 +19,19 @@ const video-padding = 56.25%
|
||||
left 0
|
||||
top 0
|
||||
background-color black
|
||||
|
||||
.video-controls
|
||||
position absolute
|
||||
bottom 1rem
|
||||
right 1rem
|
||||
opacity 0
|
||||
default-transition
|
||||
|
||||
.video-control
|
||||
background transparent
|
||||
border none
|
||||
color white
|
||||
font-size 1.2rem
|
||||
|
||||
::-webkit-media-controls
|
||||
display none !important
|
Loading…
Reference in New Issue
Block a user