Merge branch 'main' into fork-master
|
@ -18,7 +18,7 @@ module.exports = [
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
const statusCode = data.missing ? 410 : 500
|
const statusCode = data.missing ? 410 : 500
|
||||||
const subscribed = user.isSubscribed(id)
|
const subscribed = user.isSubscribed(id)
|
||||||
return render(statusCode, "pug/channel-error.pug", {settings, data, subscribed, instanceOrigin})
|
return render(statusCode, "pug/channel-error.pug", {req, settings, data, subscribed, instanceOrigin})
|
||||||
}
|
}
|
||||||
|
|
||||||
// everything is fine
|
// everything is fine
|
||||||
|
@ -35,7 +35,7 @@ module.exports = [
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const subscribed = user.isSubscribed(data.authorId)
|
const subscribed = user.isSubscribed(data.authorId)
|
||||||
return render(200, "pug/channel.pug", {settings, data, subscribed, instanceOrigin})
|
return render(200, "pug/channel.pug", {req, settings, data, subscribed, instanceOrigin})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -55,7 +55,7 @@ module.exports = [
|
||||||
label = url.searchParams.get("label")
|
label = url.searchParams.get("label")
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(200, "pug/filters.pug", {settings, categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText})
|
return render(200, "pug/filters.pug", {req, settings, categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -104,7 +104,7 @@ module.exports = [
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const categories = getCategories(user)
|
const categories = getCategories(user)
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
return render(400, "pug/filters.pug", {settings, categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText})
|
return render(400, "pug/filters.pug", {req, settings, categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText})
|
||||||
})
|
})
|
||||||
.last(state => {
|
.last(state => {
|
||||||
const {type, contents, label} = state
|
const {type, contents, label} = state
|
||||||
|
|
|
@ -8,28 +8,28 @@ module.exports = [
|
||||||
const mobile = userAgent.toLowerCase().includes("mobile")
|
const mobile = userAgent.toLowerCase().includes("mobile")
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
return render(200, "pug/home.pug", {settings, mobile})
|
return render(200, "pug/home.pug", {req, settings, mobile})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
route: "/(?:js-)?licenses", methods: ["GET"], code: async ({req}) => {
|
route: "/(?:js-)?licenses", methods: ["GET"], code: async ({req}) => {
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
return render(200, "pug/licenses.pug", {settings})
|
return render(200, "pug/licenses.pug", {req, settings})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
route: "/cant-think", methods: ["GET"], code: async ({req}) => {
|
route: "/cant-think", methods: ["GET"], code: async ({req}) => {
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
return render(200, "pug/cant-think.pug", {settings})
|
return render(200, "pug/cant-think.pug", {req, settings})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
route: "/privacy", methods: ["GET"], code: async ({req}) => {
|
route: "/privacy", methods: ["GET"], code: async ({req}) => {
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
return render(200, "pug/privacy.pug", {settings})
|
return render(200, "pug/privacy.pug", {req, settings})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,7 @@ module.exports = [
|
||||||
const filters = user.getFilters()
|
const filters = user.getFilters()
|
||||||
results = converters.applyVideoFilters(results, filters).videos
|
results = converters.applyVideoFilters(results, filters).videos
|
||||||
|
|
||||||
return render(200, "pug/search.pug", {settings, url, query, results, instanceOrigin})
|
return render(200, "pug/search.pug", {req, settings, url, query, results, instanceOrigin})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -23,7 +23,7 @@ module.exports = [
|
||||||
const user = getUser(req)
|
const user = getUser(req)
|
||||||
const settings = user.getSettings()
|
const settings = user.getSettings()
|
||||||
const instances = instancesList.get()
|
const instances = instancesList.get()
|
||||||
return render(200, "pug/settings.pug", {constants, user, settings, instances})
|
return render(200, "pug/settings.pug", {req, constants, user, settings, instances})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ module.exports = [
|
||||||
}
|
}
|
||||||
const settings = user.getSettingsOrDefaults()
|
const settings = user.getSettingsOrDefaults()
|
||||||
const instanceOrigin = settings.instance
|
const instanceOrigin = settings.instance
|
||||||
return render(200, "pug/subscriptions.pug", {url, settings, hasSubscriptions, videos, channels, missingChannelCount, refreshed, timeToPastText, instanceOrigin})
|
return render(200, "pug/subscriptions.pug", {req, url, settings, hasSubscriptions, videos, channels, missingChannelCount, refreshed, timeToPastText, instanceOrigin})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,8 +3,8 @@ const {render} = require("pinski/plugins")
|
||||||
|
|
||||||
module.exports = [
|
module.exports = [
|
||||||
{
|
{
|
||||||
route: "/takedown", methods: ["GET"], code: async () => {
|
route: "/takedown", methods: ["GET"], code: async ({req}) => {
|
||||||
return render(200, "pug/takedown.pug", {constants})
|
return render(200, "pug/takedown.pug", {req, constants})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
10
api/video.js
|
@ -111,7 +111,7 @@ module.exports = [
|
||||||
// Check if playback is allowed
|
// Check if playback is allowed
|
||||||
const videoTakedownInfo = db.prepare("SELECT id, org, url FROM TakedownVideos WHERE id = ?").get(id)
|
const videoTakedownInfo = db.prepare("SELECT id, org, url FROM TakedownVideos WHERE id = ?").get(id)
|
||||||
if (videoTakedownInfo) {
|
if (videoTakedownInfo) {
|
||||||
return render(451, "pug/takedown-video.pug", Object.assign({settings}, videoTakedownInfo))
|
return render(451, "pug/takedown-video.pug", Object.assign({req, settings}, videoTakedownInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Media fragment
|
// Media fragment
|
||||||
|
@ -129,7 +129,7 @@ module.exports = [
|
||||||
// Work out how to fetch the video
|
// Work out how to fetch the video
|
||||||
if (req.method === "GET") {
|
if (req.method === "GET") {
|
||||||
if (settings.local) { // skip to the local fetching page, which will then POST video data in a moment
|
if (settings.local) { // skip to the local fetching page, which will then POST video data in a moment
|
||||||
return render(200, "pug/local-video.pug", {settings, id})
|
return render(200, "pug/local-video.pug", {req, settings, id})
|
||||||
}
|
}
|
||||||
var instanceOrigin = settings.instance
|
var instanceOrigin = settings.instance
|
||||||
var outURL = `${instanceOrigin}/api/v1/videos/${id}`
|
var outURL = `${instanceOrigin}/api/v1/videos/${id}`
|
||||||
|
@ -153,7 +153,7 @@ module.exports = [
|
||||||
// automatically add the entry to the videos list, so it won't be fetched again
|
// automatically add the entry to the videos list, so it won't be fetched again
|
||||||
const args = {id, ...channelTakedownInfo}
|
const args = {id, ...channelTakedownInfo}
|
||||||
db.prepare("INSERT INTO TakedownVideos (id, org, url) VALUES (@id, @org, @url)").run(args)
|
db.prepare("INSERT INTO TakedownVideos (id, org, url) VALUES (@id, @org, @url)").run(args)
|
||||||
return render(451, "pug/takedown-video.pug", Object.assign({settings}, channelTakedownInfo))
|
return render(451, "pug/takedown-video.pug", Object.assign({req, settings}, channelTakedownInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
// process stream list ordering
|
// process stream list ordering
|
||||||
|
@ -199,7 +199,7 @@ module.exports = [
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(200, "pug/video.pug", {
|
return render(200, "pug/video.pug", {
|
||||||
url, video, formats, subscribed, instanceOrigin, mediaFragment, autoplay, continuous,
|
req, url, video, formats, subscribed, instanceOrigin, mediaFragment, autoplay, continuous,
|
||||||
sessionWatched, sessionWatchedNext, settings
|
sessionWatched, sessionWatchedNext, settings
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ module.exports = [
|
||||||
// Create appropriate formatted message
|
// Create appropriate formatted message
|
||||||
const message = render(0, `pug/errors/${errorType}.pug`, locals).content
|
const message = render(0, `pug/errors/${errorType}.pug`, locals).content
|
||||||
|
|
||||||
return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message, settings})
|
return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message, req, settings})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/static/images/mstile-150x150.png"/>
|
||||||
|
<TileColor>#2b5797</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "CloudTube",
|
||||||
|
"short_name": "CloudTube",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/static/images/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/static/images/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/static/images/maskable-icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/static/images/maskable-icon-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#36393f",
|
||||||
|
"background_color": "#36393f",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 710 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 491 B |
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M2667 4020 c-115 -29 -296 -105 -387 -162 -54 -34 -182 -133 -207
|
||||||
|
-159 -12 -14 -33 -49 -47 -79 -13 -30 -48 -80 -78 -110 -46 -47 -170 -221
|
||||||
|
-180 -252 -3 -7 -39 1 -96 21 -50 17 -147 43 -214 57 -111 23 -137 24 -258 18
|
||||||
|
-87 -4 -154 -13 -190 -24 -30 -10 -82 -24 -115 -31 -90 -17 -163 -59 -231
|
||||||
|
-131 -184 -197 -233 -305 -250 -554 -6 -90 -3 -115 31 -279 31 -152 44 -193
|
||||||
|
81 -265 24 -47 59 -120 78 -162 19 -43 56 -106 82 -140 66 -88 173 -196 214
|
||||||
|
-217 126 -65 482 -83 711 -35 68 14 156 36 194 49 95 32 317 43 420 22 39 -8
|
||||||
|
104 -18 145 -22 41 -3 109 -12 150 -20 166 -31 322 -37 825 -33 420 4 509 7
|
||||||
|
555 21 30 9 89 24 131 35 156 39 312 154 413 306 20 30 41 58 46 61 5 3 34 52
|
||||||
|
64 108 43 82 58 123 75 206 26 126 27 278 5 387 -18 86 -32 121 -74 174 -15
|
||||||
|
19 -34 49 -43 66 -34 67 -174 199 -262 248 -16 9 -52 32 -78 51 -27 19 -67 39
|
||||||
|
-90 45 -23 6 -71 24 -107 39 -64 28 -340 91 -397 91 -28 0 -30 4 -56 88 -15
|
||||||
|
48 -40 108 -55 134 -38 64 -224 269 -288 318 -63 48 -182 104 -250 118 -75 16
|
||||||
|
-224 22 -267 12z m-428 -984 c7 -8 33 -16 59 -19 183 -20 276 -46 447 -127 61
|
||||||
|
-29 128 -58 149 -66 22 -8 67 -32 100 -53 34 -21 84 -50 113 -65 29 -14 68
|
||||||
|
-40 88 -57 31 -27 35 -37 35 -78 0 -40 -5 -51 -32 -77 -53 -49 -130 -100 -171
|
||||||
|
-114 -21 -6 -57 -26 -80 -44 -49 -37 -70 -49 -192 -106 -49 -23 -99 -51 -111
|
||||||
|
-61 -11 -10 -45 -32 -75 -48 -30 -16 -88 -47 -129 -70 -95 -52 -134 -54 -177
|
||||||
|
-8 -74 76 -121 287 -133 592 -4 121 -13 236 -19 255 -19 60 -14 101 16 132 30
|
||||||
|
31 91 39 112 14z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -15,6 +15,6 @@
|
||||||
"denque": "^1.5.1",
|
"denque": "^1.5.1",
|
||||||
"mixin-deep": "^2.0.1",
|
"mixin-deep": "^2.0.1",
|
||||||
"node-fetch": "^2.6.6",
|
"node-fetch": "^2.6.6",
|
||||||
"pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725"
|
"pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#9653807f309aee34c8c63ce4e6ee760cccbfdf0d"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,18 @@ html
|
||||||
- const theme = settings && ["dark", "light", "edgeless-light"][settings.theme] || "dark"
|
- const theme = settings && ["dark", "light", "edgeless-light"][settings.theme] || "dark"
|
||||||
link(rel="stylesheet" type="text/css" href=getStaticURL("sass", `/${theme}.sass`))
|
link(rel="stylesheet" type="text/css" href=getStaticURL("sass", `/${theme}.sass`))
|
||||||
script(type="module" src=getStaticURL("html", "/static/js/focus.js"))
|
script(type="module" src=getStaticURL("html", "/static/js/focus.js"))
|
||||||
|
link(rel="apple-touch-icon" sizes="180x180" href="/static/images/apple-touch-icon.png")
|
||||||
|
link(rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon-32x32.png")
|
||||||
|
link(rel="icon" type="image/png" sizes="16x16" href="/static/images/favicon-16x16.png")
|
||||||
|
link(rel="manifest" href="/site.webmanifest")
|
||||||
|
link(rel="mask-icon" href="/static/images/safari-pinned-tab.svg" color="#5bbad5")
|
||||||
|
link(rel="shortcut icon" href="/static/images/favicon.ico")
|
||||||
|
meta(name="apple-mobile-web-app-title" content="CloudTube")
|
||||||
|
meta(name="application-name" content="CloudTube")
|
||||||
|
meta(name="msapplication-TileColor" content="#2b5797")
|
||||||
|
meta(name="msapplication-config" content="/browserconfig.xml")
|
||||||
|
meta(name="theme-color" content="#36393f")
|
||||||
|
|
||||||
block head
|
block head
|
||||||
|
|
||||||
body.show-focus
|
body.show-focus
|
||||||
|
@ -14,6 +26,9 @@ html
|
||||||
if showNav
|
if showNav
|
||||||
nav.main-nav
|
nav.main-nav
|
||||||
.links
|
.links
|
||||||
|
if req && req.headers && "x-insecure" in req.headers
|
||||||
|
a(href="/").link.home CloudTube - Insecure
|
||||||
|
else
|
||||||
a(href="/").link.home CloudTube
|
a(href="/").link.home CloudTube
|
||||||
a(href="/subscriptions" title="Subscriptions").link.icon-link
|
a(href="/subscriptions" title="Subscriptions").link.icon-link
|
||||||
!= icons.get("subscriptions")
|
!= icons.get("subscriptions")
|
||||||
|
|