diff --git a/mixins/AMV.pixy b/mixins/AMV.pixy index 7c28bcf7..7c322c7a 100644 --- a/mixins/AMV.pixy +++ b/mixins/AMV.pixy @@ -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) == "" diff --git a/mixins/SoundTrack.pixy b/mixins/SoundTrack.pixy index c5b95448..d2ad56bc 100644 --- a/mixins/SoundTrack.pixy +++ b/mixins/SoundTrack.pixy @@ -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 diff --git a/pages/anime/soundtracks.scarlet b/pages/anime/soundtracks.scarlet index 7c593057..dd506f0e 100644 --- a/pages/anime/soundtracks.scarlet +++ b/pages/anime/soundtracks.scarlet @@ -24,7 +24,7 @@ min-height 112px height 112px - .soundtrack-play-button + .media-play-button width 48px height 48px font-size 1rem \ No newline at end of file diff --git a/pages/soundtrack/soundtrack.pixy b/pages/soundtrack/soundtrack.pixy index 60ae5ceb..20921257 100644 --- a/pages/soundtrack/soundtrack.pixy +++ b/pages/soundtrack/soundtrack.pixy @@ -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 diff --git a/pages/soundtracks/soundtracks.scarlet b/pages/soundtracks/soundtracks.scarlet index cce7f849..bdbd89ed 100644 --- a/pages/soundtracks/soundtracks.scarlet +++ b/pages/soundtracks/soundtracks.scarlet @@ -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 diff --git a/scripts/Actions/Audio.ts b/scripts/Actions/Audio.ts index 651763c3..a8e6ff55 100644 --- a/scripts/Actions/Audio.ts +++ b/scripts/Actions/Audio.ts @@ -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) diff --git a/scripts/Actions/User.ts b/scripts/Actions/User.ts index 8c2ef723..c1ced1da 100644 --- a/scripts/Actions/User.ts +++ b/scripts/Actions/User.ts @@ -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) { diff --git a/scripts/Actions/Video.ts b/scripts/Actions/Video.ts new file mode 100644 index 00000000..2bdf686c --- /dev/null +++ b/scripts/Actions/Video.ts @@ -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() + } +} \ No newline at end of file diff --git a/scripts/Actions/index.ts b/scripts/Actions/index.ts index f3e221f5..dd88dde3 100644 --- a/scripts/Actions/index.ts +++ b/scripts/Actions/index.ts @@ -19,4 +19,5 @@ export * from "./Shop" export * from "./SideBar" export * from "./StatusMessage" export * from "./Theme" -export * from "./Upload" \ No newline at end of file +export * from "./Upload" +export * from "./Video" \ No newline at end of file diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 56f83c95..70abf92d 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -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") }) } diff --git a/scripts/AudioPlayer.ts b/scripts/AudioPlayer.ts index d633c4a6..c223dd4b 100644 --- a/scripts/AudioPlayer.ts +++ b/scripts/AudioPlayer.ts @@ -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 } diff --git a/styles/media.scarlet b/styles/media.scarlet new file mode 100644 index 00000000..c5703525 --- /dev/null +++ b/styles/media.scarlet @@ -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%) \ No newline at end of file diff --git a/styles/video.scarlet b/styles/video.scarlet index df65b728..b7dc4899 100644 --- a/styles/video.scarlet +++ b/styles/video.scarlet @@ -8,10 +8,30 @@ const video-padding = 56.25% border-radius ui-element-border-radius overflow hidden + :hover + .video-controls + opacity 1 + .video position absolute width 100% height 100% left 0 top 0 - background-color black \ No newline at end of file + 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 \ No newline at end of file