Styled landing, Bluesky and Fedi redirect pages.
This commit is contained in:
parent
7e75a71bd2
commit
b6f5a4e0cc
24 changed files with 406 additions and 132 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
20250226.1
|
||||
20250226.2
|
||||
|
|
|
@ -18,10 +18,13 @@ const MszLoadingIcon = function() {
|
|||
let tsLastUpdate;
|
||||
let counter = 0;
|
||||
let playing = false;
|
||||
let delay = 50;
|
||||
let playResolve;
|
||||
let pauseResolve;
|
||||
|
||||
const update = tsCurrent => {
|
||||
try {
|
||||
if(tsLastUpdate !== undefined && (tsCurrent - tsLastUpdate) < 50)
|
||||
if(tsLastUpdate !== undefined && (tsCurrent - tsLastUpdate) < delay)
|
||||
return;
|
||||
tsLastUpdate = tsCurrent;
|
||||
|
||||
|
@ -30,29 +33,94 @@ const MszLoadingIcon = function() {
|
|||
|
||||
++counter;
|
||||
} finally {
|
||||
if(playResolve)
|
||||
try {
|
||||
playResolve();
|
||||
} finally {
|
||||
playResolve = undefined;
|
||||
playing = true;
|
||||
}
|
||||
|
||||
if(pauseResolve)
|
||||
try {
|
||||
pauseResolve();
|
||||
} finally {
|
||||
pauseResolve = undefined;
|
||||
playing = false;
|
||||
}
|
||||
|
||||
if(playing)
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
};
|
||||
|
||||
const play = () => {
|
||||
if(playing)
|
||||
return;
|
||||
playing = true;
|
||||
requestAnimationFrame(update);
|
||||
return new Promise(resolve => {
|
||||
if(playing || playResolve) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
playResolve = resolve;
|
||||
requestAnimationFrame(update);
|
||||
});
|
||||
};
|
||||
const pause = () => {
|
||||
return new Promise(resolve => {
|
||||
if(!playing || pauseResolve) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
pauseResolve = resolve;
|
||||
});
|
||||
};
|
||||
const stop = async () => {
|
||||
await pause();
|
||||
counter = 0;
|
||||
};
|
||||
const restart = async () => {
|
||||
await stop();
|
||||
await play();
|
||||
};
|
||||
const reverse = () => {
|
||||
blocks.reverse();
|
||||
};
|
||||
const setBlock = (num, state=null) => {
|
||||
element.children[num].classList.toggle('msz-loading-icon-block-hidden', !state);
|
||||
};
|
||||
const batsu = () => {
|
||||
setBlock(0, true);setBlock(1, false);setBlock(2, true);
|
||||
setBlock(3, false);setBlock(4, true);setBlock(5, false);
|
||||
setBlock(6, true);setBlock(7, false);setBlock(8, true);
|
||||
};
|
||||
const maru = () => {
|
||||
setBlock(0, true);setBlock(1, true);setBlock(2, true);
|
||||
setBlock(3, true);setBlock(4, false);setBlock(5, true);
|
||||
setBlock(6, true);setBlock(7, true);setBlock(8, true);
|
||||
};
|
||||
const pause = () => { playing = false; };
|
||||
const stop = () => { pause(); counter = 0; };
|
||||
const restart = () => { stop(); play(); };
|
||||
|
||||
return {
|
||||
get element() { return element; },
|
||||
get playing() { return playing; },
|
||||
get delay() { return delay; },
|
||||
set delay(value) {
|
||||
if(typeof value !== 'number')
|
||||
value = parseFloat(value);
|
||||
if(isNaN(value) || !isFinite(value))
|
||||
return;
|
||||
if(value < 0)
|
||||
value = Math.abs(value);
|
||||
delay = value;
|
||||
},
|
||||
|
||||
play: play,
|
||||
pause: pause,
|
||||
stop: stop,
|
||||
restart: restart,
|
||||
play,
|
||||
pause,
|
||||
stop,
|
||||
restart,
|
||||
reverse,
|
||||
batsu,
|
||||
maru,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
mask-image: linear-gradient(0deg, transparent 10%, var(--background-colour) 100%);
|
||||
-webkit-mask-image: linear-gradient(0deg, transparent 10%, var(--background-colour) 100%);
|
||||
background: var(--background-pattern);
|
||||
background-color: var(--accent-colour);
|
||||
background-blend-mode: multiply;
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
(async () => {
|
||||
const status = document.querySelector('.js-status');
|
||||
status.textContent = 'Looking up DID...';
|
||||
|
||||
let did = null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${location.protocol}//${BSKY_HANDLE}/.well-known/atproto-did`);
|
||||
did = await response.text();
|
||||
} catch(ex) {
|
||||
status.style.color = 'red';
|
||||
status.textContent = `Could not find DID! ${ex}`;
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof did !== 'string' || !did.startsWith('did:')) {
|
||||
status.style.color = 'red';
|
||||
status.textContent = 'Look up result was not a valid DID.';
|
||||
return;
|
||||
}
|
||||
|
||||
const url = BSKY_FORMAT.replace('%s', did);
|
||||
status.textContent = `Redirecting to ${url}...`;
|
||||
location.replace(url);
|
||||
})();
|
|
@ -1,39 +0,0 @@
|
|||
(async () => {
|
||||
const status = document.querySelector('.js-status');
|
||||
status.textContent = 'Looking up Fediverse profile...';
|
||||
|
||||
let url = null;
|
||||
try {
|
||||
const response = await fetch(`${location.protocol}//${FEDI_INSTANCE}/.well-known/webfinger?format=json&resource=acct:${FEDI_USERNAME}@${FEDI_INSTANCE}`);
|
||||
const webfinger = await response.json();
|
||||
|
||||
if(typeof webfinger === 'object') {
|
||||
if(Array.isArray(webfinger.links))
|
||||
for(const link of webfinger.links)
|
||||
if(typeof link === 'object' && link.rel === 'http://webfinger.net/rel/profile-page' && typeof link.href === 'string') {
|
||||
url = link.href;
|
||||
break;
|
||||
}
|
||||
|
||||
if(typeof url !== 'string' && Array.isArray(webfinger.aliases))
|
||||
for(const alias of webfinger.aliases)
|
||||
if(typeof alias === 'string') {
|
||||
url = alias;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(ex) {
|
||||
status.style.color = 'red';
|
||||
status.textContent = `Could not complete Webfinger lookup! ${ex}`;
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof url !== 'string' || (!url.startsWith('https://') && !url.startsWith('http://'))) {
|
||||
status.style.color = 'red';
|
||||
status.textContent = 'Could not find an acceptable profile URL.';
|
||||
return;
|
||||
}
|
||||
|
||||
status.textContent = `Redirecting to ${url}...`;
|
||||
location.replace(url);
|
||||
})();
|
42
assets/redirects.css/landing.css
Normal file
42
assets/redirects.css/landing.css
Normal file
|
@ -0,0 +1,42 @@
|
|||
.redir-landing {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.redir-landing-content {
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
background: #191919;
|
||||
box-shadow: 0 1px 2px #0009;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.redir-landing-body {
|
||||
text-align: center;
|
||||
}
|
||||
.redir-landing-body p {
|
||||
margin: .5em;
|
||||
}
|
||||
|
||||
.redir-landing-footer {
|
||||
font-size: .8em;
|
||||
line-height: 1.4em;
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.redir-landing-logo {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background-color: #fff;
|
||||
mask: url('/images/flashii.svg') no-repeat center;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
margin: 10px;
|
||||
font-size: 0;
|
||||
}
|
54
assets/redirects.css/main.css
Normal file
54
assets/redirects.css/main.css
Normal file
|
@ -0,0 +1,54 @@
|
|||
:root {
|
||||
--accent-colour: #8559a5;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #111;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
font-family: var(--font-regular);
|
||||
overflow-y: scroll;
|
||||
position: static;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: var(--font-monospace);
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1e90ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: #6B4F80;
|
||||
}
|
||||
a:hover,
|
||||
a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.redir-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
mask-image: linear-gradient(315deg, #000f 0, #0000 40%);
|
||||
background: url('/images/clouds.png');
|
||||
background-color: var(--accent-colour);
|
||||
background-blend-mode: multiply;
|
||||
}
|
||||
|
||||
.redir-foreground {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@include landing.css;
|
||||
@include social.css;
|
26
assets/redirects.css/social.css
Normal file
26
assets/redirects.css/social.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
.redir-social {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.redir-social-content {
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
background: #191919;
|
||||
box-shadow: 0 1px 2px #0009;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.redir-social-body {
|
||||
text-align: center;
|
||||
}
|
||||
.redir-social-body p {
|
||||
margin: .5em;
|
||||
line-height: 1.4em;
|
||||
}
|
32
assets/redirects.js/bsky.jsx
Normal file
32
assets/redirects.js/bsky.jsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
const MszRedirectsBsky = async () => {
|
||||
const loading = new MszLoading({ element: '.js-loading', size: 2, inline: true });
|
||||
|
||||
const statusBig = document.querySelector('.js-status-big');
|
||||
const statusSmall = document.querySelector('.js-status-small');
|
||||
const setStatusSmall = body => {
|
||||
$removeChildren(statusSmall);
|
||||
$appendChild(statusSmall, body);
|
||||
};
|
||||
|
||||
setStatusSmall(<>Resolving ATProto DID for @{BSKY_HANDLE}...</>);
|
||||
|
||||
try {
|
||||
const { body } = await $xhr.get(`${location.protocol}//${BSKY_HANDLE}/.well-known/atproto-did`);
|
||||
if(typeof body !== 'string' || !body.startsWith('did:'))
|
||||
throw new Error('Was unable to resolve the given handle.');
|
||||
|
||||
const url = BSKY_FORMAT.replace('%s', body);
|
||||
setStatusSmall(<>Redirecting to <a href={url} rel="noopener">{url}</a>...</>);
|
||||
location.replace(url);
|
||||
} catch(ex) {
|
||||
await loading.icon.stop();
|
||||
loading.icon.batsu();
|
||||
|
||||
let errorText = ex.toString();
|
||||
if(errorText.startsWith('['))
|
||||
errorText = 'Something went wrong.';
|
||||
|
||||
statusBig.textContent = 'Profile not found!';
|
||||
setStatusSmall(<span style="color: red">{errorText}</span>);
|
||||
}
|
||||
};
|
49
assets/redirects.js/fedi.jsx
Normal file
49
assets/redirects.js/fedi.jsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
const MszRedirectsFedi = async () => {
|
||||
const loading = new MszLoading({ element: '.js-loading', size: 2, inline: true });
|
||||
|
||||
const statusBig = document.querySelector('.js-status-big');
|
||||
const statusSmall = document.querySelector('.js-status-small');
|
||||
const setStatusSmall = body => {
|
||||
$removeChildren(statusSmall);
|
||||
$appendChild(statusSmall, body);
|
||||
};
|
||||
|
||||
setStatusSmall(<>Resolving Webfinger resource for @{FEDI_USERNAME}@{FEDI_INSTANCE}...</>);
|
||||
|
||||
try {
|
||||
const { body } = await $xhr.get(`${location.protocol}//${FEDI_INSTANCE}/.well-known/webfinger?format=json&resource=acct:${FEDI_USERNAME}@${FEDI_INSTANCE}`, { type: 'json' });
|
||||
|
||||
let url;
|
||||
if(typeof body === 'object') {
|
||||
if(Array.isArray(body.links))
|
||||
for(const link of body.links)
|
||||
if(typeof link === 'object' && link.rel === 'http://webfinger.net/rel/profile-page' && typeof link.href === 'string') {
|
||||
url = link.href;
|
||||
break;
|
||||
}
|
||||
|
||||
if(typeof url !== 'string' && Array.isArray(body.aliases))
|
||||
for(const alias of body.aliases)
|
||||
if(typeof alias === 'string') {
|
||||
url = alias;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof url !== 'string' || (!url.startsWith('https://') && !url.startsWith('http://')))
|
||||
throw new Error('Unable to resolve profile URL for given handle.');
|
||||
|
||||
setStatusSmall(<>Redirecting to <a href={url} rel="noopener">{url}</a>...</>);
|
||||
location.replace(url);
|
||||
} catch(ex) {
|
||||
await loading.icon.stop();
|
||||
loading.icon.batsu();
|
||||
|
||||
let errorText = ex.toString();
|
||||
if(errorText.startsWith('['))
|
||||
errorText = 'Something went wrong.';
|
||||
|
||||
statusBig.textContent = 'Profile not found!';
|
||||
setStatusSmall(<span style="color: red">{errorText}</span>);
|
||||
}
|
||||
};
|
9
assets/redirects.js/main.js
Normal file
9
assets/redirects.js/main.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include bsky.jsx
|
||||
#include fedi.jsx
|
||||
|
||||
(() => {
|
||||
if(location.pathname === '/bsky' || location.pathname.startsWith('/bsky/'))
|
||||
MszRedirectsBsky();
|
||||
if(location.pathname === '/fedi' || location.pathname.startsWith('/fedi/'))
|
||||
MszRedirectsFedi();
|
||||
})();
|
4
build.js
4
build.js
|
@ -25,14 +25,14 @@ const fs = require('fs');
|
|||
{ source: 'common.js', target: '/assets', name: 'common.{hash}.js', },
|
||||
{ source: 'misuzu.js', target: '/assets', name: 'misuzu.{hash}.js', },
|
||||
{ source: 'oauth2.js', target: '/assets', name: 'oauth2.{hash}.js', },
|
||||
{ source: 'redir-bsky.js', target: '/assets', name: 'redir-bsky.{hash}.js', },
|
||||
{ source: 'redir-fedi.js', target: '/assets', name: 'redir-fedi.{hash}.js', },
|
||||
{ source: 'redirects.js', target: '/assets', name: 'redirects.{hash}.js', },
|
||||
],
|
||||
css: [
|
||||
{ source: 'errors.css', target: '/', name: 'errors.css', },
|
||||
{ source: 'common.css', target: '/assets', name: 'common.{hash}.css', },
|
||||
{ source: 'misuzu.css', target: '/assets', name: 'misuzu.{hash}.css', },
|
||||
{ source: 'oauth2.css', target: '/assets', name: 'oauth2.{hash}.css', },
|
||||
{ source: 'redirects.css', target: '/assets', name: 'redirects.{hash}.css', },
|
||||
],
|
||||
twig: [
|
||||
{ source: 'errors/400', target: '/', name: 'error-400.html', },
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
<?php
|
||||
namespace Misuzu\Redirects;
|
||||
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Template;
|
||||
|
||||
class LandingRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
#[HttpGet('/')]
|
||||
public function getIndex(): string {
|
||||
return <<<HTML
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Redirects</title>
|
||||
<p>Short URL Service for <a href=/home rel=noopener>Flashii</a></p>
|
||||
<p>This is a temporary landing page until backend is less tied up.</p>
|
||||
<p><a href=https://flash.moe target=_blank rel=noopener>flashwave</a> 2017-2025</p>
|
||||
HTML;
|
||||
return Template::renderRaw('redirects.landing');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ class RedirectsContext {
|
|||
public private(set) NamedRedirectsData $named;
|
||||
public private(set) IncrementalRedirectsData $incremental;
|
||||
|
||||
public string $bskyProfileUrlFormat {
|
||||
get => $this->config->getString('bsky_profile', 'https://bsky.app/profile/%s');
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
DbConnection $dbConn,
|
||||
public private(set) Config $config
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
<?php
|
||||
namespace Misuzu\Redirects;
|
||||
|
||||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\AssetInfo;
|
||||
use Misuzu\Template;
|
||||
|
||||
class SocialRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
private Config $config;
|
||||
|
||||
public function __construct(
|
||||
RedirectsContext $redirectsCtx,
|
||||
private AssetInfo $assetInfo
|
||||
) {
|
||||
$this->config = $redirectsCtx->config->scopeTo('social');
|
||||
}
|
||||
private RedirectsContext $redirectsCtx
|
||||
) {}
|
||||
|
||||
#[HttpGet('/bsky/((did:[a-z0-9]+:[A-Za-z0-9.\-_:%]+)|(([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])))')]
|
||||
public function getBlueskyRedirect(HttpResponseBuilder $response, HttpRequest $request, string $handle): int|string {
|
||||
|
@ -41,38 +35,23 @@ class SocialRedirectsRoutes implements RouteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
$format = $this->config->getString('bsky_profile', 'https://bsky.app/profile/%s');
|
||||
$format = $this->redirectsCtx->bskyProfileUrlFormat;
|
||||
if(is_string($did)) {
|
||||
$response->redirect(sprintf($format, $did), true);
|
||||
return 301;
|
||||
}
|
||||
|
||||
$handle = rawurlencode($handle);
|
||||
$script = $this->assetInfo->getAssetUrl('redir-bsky.js');
|
||||
|
||||
return <<<HTML
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Redirecting to Bluesky profile...</title>
|
||||
<div class=js-status><noscript>Javascript must be enabled for Bluesky redirects to work.</noscript></div>
|
||||
<script>const BSKY_FORMAT = '{$format}'; const BSKY_HANDLE = decodeURIComponent('{$handle}');</script>
|
||||
<script src="{$script}"></script>
|
||||
HTML;
|
||||
return Template::renderRaw('redirects.bsky', [
|
||||
'bsky_format' => $format,
|
||||
'bsky_handle' => $handle,
|
||||
]);
|
||||
}
|
||||
|
||||
#[HttpGet('/fedi/([A-Za-z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})')]
|
||||
public function getFediverseRedirect(HttpResponseBuilder $response, HttpRequest $request, string $userName, string $instance): string {
|
||||
$userName = rawurlencode($userName);
|
||||
$instance = rawurlencode($instance);
|
||||
$script = $this->assetInfo->getAssetUrl('redir-fedi.js');
|
||||
|
||||
return <<<HTML
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Redirecting to Fediverse profile...</title>
|
||||
<div class=js-status><noscript>Javascript must be enabled for Fediverse redirects to work.</noscript></div>
|
||||
<script>const FEDI_USERNAME = '{$userName}'; const FEDI_INSTANCE = decodeURIComponent('{$instance}');</script>
|
||||
<script src="{$script}"></script>
|
||||
HTML;
|
||||
return Template::renderRaw('redirects.fedi', [
|
||||
'fedi_username' => $userName,
|
||||
'fedi_instance' => $instance,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
{% block html_head %}
|
||||
<meta name="description" content="{{ error_blerb }}">
|
||||
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
|
||||
<link href="/vendor/fontawesome/css/all.min.css" rel="stylesheet">
|
||||
<link href="/errors.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
</form>
|
||||
|
||||
{% if globals.eeprom_path is not empty and globals.eeprom_app is not empty %}
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app }}';
|
||||
</script>
|
||||
{% endif %}
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<button type="button" id="-msz-manage-setting-array-enter" class="input__button input__button--save">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
var mszMSF = document.getElementById('-msz-manage-setting-form'),
|
||||
mszMSA = document.getElementById('-msz-manage-setting-array'),
|
||||
mszMSAD = document.getElementById('-msz-manage-setting-array-delete'),
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
{% block html_head %}
|
||||
{% include '_layout/meta.twig' %}
|
||||
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
|
||||
<link href="{{ asset('common.css') }}" type="text/css" rel="stylesheet">
|
||||
<link href="{{ asset('misuzu.css') }}" type="text/css" rel="stylesheet">
|
||||
<link href="/vendor/fontawesome/css/all.min.css" rel="stylesheet">
|
||||
<link href="{{ asset('common.css') }}" rel="stylesheet">
|
||||
<link href="{{ asset('misuzu.css') }}" rel="stylesheet">
|
||||
{% if main_css_vars is defined and main_css_vars is iterable and main_css_vars is not empty %}
|
||||
<style>
|
||||
:root {
|
||||
|
@ -55,7 +55,7 @@
|
|||
{% include '_layout/footer.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
<script src="/vendor/highlightjs/highlight.min.js" type="text/javascript"></script>
|
||||
<script src="{{ asset('common.js') }}" type="text/javascript"></script>
|
||||
<script src="{{ asset('misuzu.js') }}" type="text/javascript"></script>
|
||||
<script src="/vendor/highlightjs/highlight.min.js"></script>
|
||||
<script src="{{ asset('common.js') }}"></script>
|
||||
<script src="{{ asset('misuzu.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% if globals.eeprom_path is not empty and globals.eeprom_app_messages is not empty %}
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app_messages }}';
|
||||
</script>
|
||||
{% endif %}
|
||||
|
|
19
templates/redirects/bsky.twig
Normal file
19
templates/redirects/bsky.twig
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends 'redirects/master.twig' %}
|
||||
|
||||
{% set html_title = 'Redirecting to Bluesky profile...' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="redir-social">
|
||||
<div class="redir-social-content">
|
||||
<div class="js-loading"></div>
|
||||
<article class="redir-social-body">
|
||||
<h1 class="js-status-big">Redirecting to profile...</h1>
|
||||
<p class="js-status-small"><noscript>Javascript must be enabled for Bluesky redirects to work.</noscript></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const BSKY_FORMAT = '{{ bsky_format }}';
|
||||
const BSKY_HANDLE = '{{ bsky_handle }}';
|
||||
</script>
|
||||
{% endblock %}
|
19
templates/redirects/fedi.twig
Normal file
19
templates/redirects/fedi.twig
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends 'redirects/master.twig' %}
|
||||
|
||||
{% set html_title = 'Redirecting to Fediverse profile...' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="redir-social">
|
||||
<div class="redir-social-content">
|
||||
<div class="js-loading"></div>
|
||||
<article class="redir-social-body">
|
||||
<h1 class="js-status-big">Redirecting to profile...</h1>
|
||||
<p class="js-status-small"><noscript>Javascript must be enabled for Fediverse redirects to work.</noscript></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const FEDI_USERNAME = '{{ fedi_username }}';
|
||||
const FEDI_INSTANCE = '{{ fedi_instance }}';
|
||||
</script>
|
||||
{% endblock %}
|
29
templates/redirects/landing.twig
Normal file
29
templates/redirects/landing.twig
Normal file
|
@ -0,0 +1,29 @@
|
|||
{% extends 'redirects/master.twig' %}
|
||||
|
||||
{% set html_title = globals.site_info.name ~ ' Redirect Service' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="redir-landing">
|
||||
<div class="redir-landing-content">
|
||||
<article class="redir-landing-body">
|
||||
<p><div class="redir-landing-logo"></div></p>
|
||||
<h1>{{ html_title }}</h1>
|
||||
<p>Short URL Service for <a href="{{ globals.site_info.url }}" rel="noopener">{{ globals.site_info.name }}</a></p>
|
||||
</article>
|
||||
<footer class="redir-landing-footer">
|
||||
<p>
|
||||
<a href="https://flash.moe" target="_blank" rel="noopener">flashwave</a>
|
||||
2013-{{ ''|date('Y') }} /
|
||||
{% set git_branch = git_branch() %}
|
||||
{% if git_branch != 'HEAD' %}
|
||||
<a href="https://patchii.net/flashii/misuzu/src/branch/{{ git_branch }}" target="_blank" rel="noopener">{{ git_branch }}</a>
|
||||
{% else %}
|
||||
{% set git_tag = git_tag() %}
|
||||
<a href="https://patchii.net/flashii/misuzu/src/tag/{{ git_tag }}" target="_blank" rel="noopener">{{ git_tag }}</a>
|
||||
{% endif %}
|
||||
# <a href="https://patchii.net/flashii/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noopener">{{ git_commit_hash() }}</a>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
16
templates/redirects/master.twig
Normal file
16
templates/redirects/master.twig
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends 'html.twig' %}
|
||||
|
||||
{% block html_head %}
|
||||
<link href="/vendor/fontawesome/css/all.min.css" rel="stylesheet">
|
||||
<link href="{{ asset('common.css') }}" rel="stylesheet">
|
||||
<link href="{{ asset('redirects.css') }}" rel="stylesheet">
|
||||
{% endblock %}
|
||||
|
||||
{% block html_body %}
|
||||
<div class="redir-background"></div>
|
||||
<div class="redir-foreground">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<script src="{{ asset('common.js') }}"></script>
|
||||
<script src="{{ asset('redirects.js') }}"></script>
|
||||
{% endblock %}
|
Loading…
Add table
Reference in a new issue