Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55c4d094ee | ||
|
|
13091adc4d | ||
|
|
483ea5148b | ||
|
|
f065052213 | ||
|
|
b71eaf390c | ||
|
|
64d27f57ff | ||
|
|
e776c57030 | ||
|
|
8ba15c9126 | ||
|
|
db9c7e09b9 | ||
|
|
4dc179a7d2 | ||
|
|
d9777c3c82 | ||
|
|
218ba874f9 | ||
|
|
b3f24f5911 | ||
|
|
abebf72ce1 | ||
|
|
94c9f67ce1 | ||
|
|
5aa65c86ea | ||
|
|
58b01b77fb | ||
|
|
720a49f544 | ||
|
|
d8c5dc964f | ||
|
|
36c44873a2 |
No files matched your search
@@ -4,15 +4,26 @@ import { execSync } from "node:child_process";
|
|||||||
const host = process.env.TAURI_DEV_HOST;
|
const host = process.env.TAURI_DEV_HOST;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
IMG_ORIGIN = `https://git.polv.cc/polv/yt2press/raw/branch/${
|
IMG_ORIGIN = `https://git.polv.cc/polv/yt2press/raw/branch/${execSync(
|
||||||
execSync("git branch --show-current").toString().trimEnd()
|
"git branch --show-current",
|
||||||
}/docs/public`,
|
)
|
||||||
|
.toString()
|
||||||
|
.trimEnd()}/docs/public`,
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
// https://vitepress.dev/reference/site-config
|
// https://vitepress.dev/reference/site-config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: "yt2press",
|
title: "yt2press",
|
||||||
description: "video to vitepress",
|
description: "video to vitepress",
|
||||||
|
head: [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
{
|
||||||
|
async: "async",
|
||||||
|
src: "https://www.youtube.com/iframe_api",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
// https://vitepress.dev/reference/default-theme-config
|
// https://vitepress.dev/reference/default-theme-config
|
||||||
nav: [{ text: "Home", link: "/" }],
|
nav: [{ text: "Home", link: "/" }],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Teleport to="body">
|
<Teleport to="body">
|
||||||
<div :class="$style.container">
|
<div :class="$style.container">
|
||||||
<YouTube v-if="youtubeID" :id="youtubeID" />
|
<YouTube ref="yt" v-if="youtubeID" :id="youtubeID" />
|
||||||
<video
|
<video
|
||||||
v-else-if="videoURL"
|
v-else-if="videoURL"
|
||||||
controls
|
controls
|
||||||
@@ -15,12 +15,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useData } from "vitepress";
|
import { useData } from "vitepress";
|
||||||
import { computed, ref, useTemplateRef, watch } from "vue";
|
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from "vue";
|
||||||
import YouTube from "./YouTube.vue";
|
import YouTube from "./YouTube.vue";
|
||||||
|
|
||||||
const { frontmatter } = useData<{ video?: string }>();
|
const { frontmatter } = useData<{ video?: string }>();
|
||||||
const videoURL = computed(() => frontmatter.value?.video);
|
const videoURL = computed(() => frontmatter.value?.video);
|
||||||
const videoEl = useTemplateRef("video");
|
const videoEl = useTemplateRef("video");
|
||||||
|
const ytEl = useTemplateRef("yt");
|
||||||
|
|
||||||
const youtubeID = ref("");
|
const youtubeID = ref("");
|
||||||
|
|
||||||
@@ -41,14 +42,15 @@ function imgClickListener(ev: PointerEvent) {
|
|||||||
if (!(ev.target instanceof HTMLImageElement)) return;
|
if (!(ev.target instanceof HTMLImageElement)) return;
|
||||||
const img = ev.target;
|
const img = ev.target;
|
||||||
|
|
||||||
if (!videoEl.value) return;
|
|
||||||
const v = videoEl.value;
|
|
||||||
|
|
||||||
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
|
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
|
||||||
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
|
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
|
|
||||||
v.currentTime = t;
|
if (videoEl.value) {
|
||||||
|
videoEl.value.currentTime = t;
|
||||||
|
} else if (ytEl.value) {
|
||||||
|
ytEl.value.seekTo(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(videoURL, () => {
|
watch(videoURL, () => {
|
||||||
@@ -60,12 +62,38 @@ function onVideoNotFound() {
|
|||||||
youtubeID.value = m[1] || "";
|
youtubeID.value = m[1] || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ts-ignore
|
function onOrientationChanged() {
|
||||||
const { SSR } = import.meta.env;
|
if (window.screen.orientation.type.startsWith("landscape")) {
|
||||||
|
if (videoEl.value) {
|
||||||
|
videoEl.value.requestFullscreen();
|
||||||
|
return;
|
||||||
|
} else if (ytEl.value) {
|
||||||
|
ytEl.value.requestFullscreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!SSR) {
|
if (document.fullscreenElement) {
|
||||||
setTimeout(() => setImgClick(), 500);
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => setImgClick(), 500);
|
||||||
|
|
||||||
|
if (window.screen?.orientation) {
|
||||||
|
window.screen.orientation.addEventListener("change", onOrientationChanged);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (window.screen?.orientation) {
|
||||||
|
window.screen.orientation.removeEventListener("change", onOrientationChanged);
|
||||||
|
}
|
||||||
|
if (document.fullscreenElement) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="$style.container">
|
<div :class="$style.container">
|
||||||
<iframe
|
<iframe
|
||||||
|
id="yt-player"
|
||||||
|
ref="iframe"
|
||||||
:class="$style.iframe"
|
:class="$style.iframe"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
:src="'https://www.youtube.com/embed/' + $props.id"
|
:src="url.href"
|
||||||
frameborder="0"
|
frameborder="0"
|
||||||
allow="
|
allow="
|
||||||
accelerometer;
|
accelerometer;
|
||||||
@@ -20,7 +22,36 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
defineProps<{ id: string; title?: string }>();
|
import { onMounted, ref, useTemplateRef } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps<{ id: string; title?: string }>();
|
||||||
|
|
||||||
|
defineExpose({ seekTo, requestFullscreen });
|
||||||
|
|
||||||
|
const url = new URL("https://www.youtube.com/embed/" + props.id);
|
||||||
|
url.searchParams.set("enablejsapi", "1");
|
||||||
|
|
||||||
|
const player = ref();
|
||||||
|
const iframe = useTemplateRef("iframe");
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const { YT } = window as any;
|
||||||
|
if (YT?.Player && iframe.value) {
|
||||||
|
player.value = new YT.Player(iframe.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function seekTo(t: number) {
|
||||||
|
if (player.value) {
|
||||||
|
player.value.seekTo(t, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFullscreen() {
|
||||||
|
if (iframe.value) {
|
||||||
|
iframe.value.requestFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* body {
|
||||||
|
padding-top: env(safe-area-inset-top);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
|
} */
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import "./custom.css";
|
||||||
|
|
||||||
import type { Theme } from "vitepress";
|
import type { Theme } from "vitepress";
|
||||||
import DefaultTheme from "vitepress/theme";
|
import DefaultTheme from "vitepress/theme";
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
|
|||||||
@@ -9,6 +9,21 @@ hero:
|
|||||||
|
|
||||||
<Downloader />
|
<Downloader />
|
||||||
|
|
||||||
|
- [HTC三次押中科技革命,為何三次都替別人賺了大錢?|從台灣股王到被Google兩度帶走核心團隊](./HTC三次押中科技革命,為何三次都替別人賺了大錢?|從台灣股王到被Google兩度帶走核心團隊.md)
|
||||||
|
- [茅台最怕的,不是競爭對手,而是中國年輕人!曾經一瓶難求的白酒,神話還能撐多久?](./茅台最怕的,不是競爭對手,而是中國年輕人!曾經一瓶難求的白酒,神話還能撐多久?.md)
|
||||||
|
- [沃爾瑪抄走一切,為什麼還是打不過好市多?Costco 最反常識的商業秘密!](./沃爾瑪抄走一切,為什麼還是打不過好市多?Costco_最反常識的商業秘密!.md)
|
||||||
|
- [辛拉麵背後:財閥、媒體與國家,如何一步步設計你的泡麵選擇](./辛拉麵背後:財閥、媒體與國家,如何一步步設計你的泡麵選擇.md)
|
||||||
|
- [一家輪胎公司,為什麼能決定全世界廚師的命運?|米其林:一本虧錢百年的生死簿](./一家輪胎公司,為什麼能決定全世界廚師的命運?|米其林:一本虧錢百年的生死簿.md)
|
||||||
|
- [日清差點把杯麵做死,卻被一場持槍劫案救活|一杯泡麵如何賣遍全球?](./日清差點把杯麵做死,卻被一場持槍劫案救活|一杯泡麵如何賣遍全球?.md)
|
||||||
|
- [柯達破產14年后,竟靠一件T恤還魂,年入10億美金...](./柯達破產14年后,竟靠一件T恤還魂,年入10億美金.md)
|
||||||
|
- [別再把紅牛當飲料公司!它如何靠「玩命運動」,一年賣出140億罐?](./別再把紅牛當飲料公司!它如何靠「玩命運動」,一年賣出140億罐?.md)
|
||||||
|
- [一家馬桶公司,為什麼成了AI命脈?TOTO埋了50年的暗棋](./一家馬桶公司,為什麼成了AI命脈?TOTO埋了50年的暗棋.md)
|
||||||
|
- [樂高差點被「創新」害死:最後救它的,竟是一雙舊球鞋!](./樂高差點被「創新」害死:最後救它的,竟是一雙舊球鞋!.md)
|
||||||
|
- [錯過NVIDIA了?Anthropic可能是下一個改變你財富命運的AI巨頭](./錯過NVIDIA了?Anthropic可能是下一個改變你財富命運的AI巨頭.md)
|
||||||
|
- [長榮帝國締造者張榮發:算準了世界,為何算錯了自己的人生?](./長榮帝國締造者張榮發:算準了世界,為何算錯了自己的人生?.md)
|
||||||
|
- [不准離婚、不准婚外情:李錦記靠一部狠到離譜的家法,打破「富不過三代」!](./不准離婚、不准婚外情:李錦記靠一部狠到離譜的家法,打破「富不過三代」!.md)
|
||||||
|
- [誠品自食其果?養肥黃金地段18年,反被房東掃地出門....](./誠品自食其果?養肥黃金地段18年,反被房東掃地出門.....md)
|
||||||
|
- [Shein帝国:廉价时尚背后的惊人代价|许仰天|婚纱网店](./Shein帝国:廉价时尚背后的惊人代价|许仰天|婚纱网店.md)
|
||||||
- [【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ](./【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ.md)
|
- [【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ](./【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ.md)
|
||||||
- [比西藏、新疆、蒙古近 【韓國為啥不是中國的?】文化最像 卻沒被併吞?](./比西藏、新疆、蒙古近_【韓國為啥不是中國的?】文化最像_卻沒被併吞?.md)
|
- [比西藏、新疆、蒙古近 【韓國為啥不是中國的?】文化最像 卻沒被併吞?](./比西藏、新疆、蒙古近_【韓國為啥不是中國的?】文化最像_卻沒被併吞?.md)
|
||||||
- [泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?](./泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?.md)
|
- [泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?](./泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?.md)
|
||||||
|
|||||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 28 KiB |