Added new kick/ban screen.
This commit is contained in:
parent
dd2fd189dc
commit
123b21f8cb
7 changed files with 181 additions and 74 deletions
67
src/mami.css/baka.css
Normal file
67
src/mami.css/baka.css
Normal file
|
@ -0,0 +1,67 @@
|
|||
@keyframes baka-marquee-anim {
|
||||
from { transform: translateX(0); }
|
||||
to { transform: translateX(-100%); }
|
||||
}
|
||||
|
||||
.baka {
|
||||
color: #000;
|
||||
background: repeating-linear-gradient(-45deg, #ff3d3d, #ff3d3d 20px, #f00 20px, #f00 40px);
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.baka-container {
|
||||
flex-shrink: 1;
|
||||
flex-grow: 1;
|
||||
background: #0008;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.baka-bottom {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
height: 6em;
|
||||
}
|
||||
|
||||
.baka-spacing {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.baka-marquee {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 6em;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
background: #0005;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.baka-marquee-text {
|
||||
font-size: 5rem;
|
||||
line-height: 1.2em;
|
||||
font-weight: 700;
|
||||
padding: 0 .25em;
|
||||
text-transform: uppercase;
|
||||
animation: baka-marquee-anim 2.33s infinite linear;
|
||||
}
|
||||
|
||||
.baka-duration {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
margin: 5px;
|
||||
}
|
||||
.baka-duration-inner {
|
||||
padding: 5px 10px;
|
||||
background: #0002;
|
||||
display: inline-block;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
@include views.css;
|
||||
|
||||
@include baka.css;
|
||||
@include chat.css;
|
||||
@include eeprom.css;
|
||||
@include emote.css;
|
||||
|
|
|
@ -25,6 +25,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
|||
#include sound/context.js
|
||||
#include sound/osukeys.js
|
||||
#include sound/umisound.js
|
||||
#include ui/baka.jsx
|
||||
#include ui/chat-layout.js
|
||||
#include ui/hooks.js
|
||||
#include ui/emotes.js
|
||||
|
@ -564,6 +565,12 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
|||
'_1013': 'You cannot connect to the server right now, try again later.',
|
||||
'_1015': 'Your client and the server could not establish a secure connection.',
|
||||
};
|
||||
const sessFailReasons = {
|
||||
'authfail': 'Authentication failed.',
|
||||
'sockfail': 'Too many active connections.',
|
||||
'userfail': 'Name in use.',
|
||||
'joinfail': 'You are banned.',
|
||||
};
|
||||
|
||||
let dumpEvents = false;
|
||||
settings.watch('dumpEvents', value => dumpEvents = value);
|
||||
|
@ -606,64 +613,6 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
|||
});
|
||||
|
||||
|
||||
const playBannedSfx = async () => {
|
||||
await soundCtx.library.play('touhou:pichuun');
|
||||
};
|
||||
const playBannedBgm = async preload => {
|
||||
const name = 'touhou:th10score';
|
||||
|
||||
if(preload) {
|
||||
await soundCtx.library.loadBuffer(name);
|
||||
return;
|
||||
}
|
||||
|
||||
const source = await soundCtx.library.loadSource(name);
|
||||
source.setLoop(true, 10.512, 38.074);
|
||||
await source.play();
|
||||
};
|
||||
const displayBanMessage = baka => {
|
||||
let message;
|
||||
if(baka.perma)
|
||||
message = 'You have been banned till the end of time, please try again in a different dimension.';
|
||||
else if(baka.until)
|
||||
message = `You were banned until ${baka.until.toLocaleString()}!`;
|
||||
else
|
||||
message = 'You were kicked, refresh to log back in!';
|
||||
|
||||
const icon = baka.type === 'kick' ? 'bomb' : 'hammer';
|
||||
const header = baka.type === 'kick' ? 'Kicked!' : 'Banned!';
|
||||
|
||||
const currentView = views.current();
|
||||
|
||||
if(currentView === undefined || 'setIcon' in currentView) {
|
||||
playBannedBgm();
|
||||
getLoadingOverlay(icon, header, message);
|
||||
} else {
|
||||
const currentViewElem = views.currentElement();
|
||||
|
||||
MamiAnimate({
|
||||
duration: 550,
|
||||
easing: 'outExpo',
|
||||
start: () => {
|
||||
playBannedBgm(true);
|
||||
playBannedSfx();
|
||||
},
|
||||
update: t => {
|
||||
currentViewElem.style.transform = `scale(${(1 - .5 * t)}, ${(1 - 1 * t)})`;
|
||||
},
|
||||
end: () => {
|
||||
getLoadingOverlay(icon, header, message).then(() => {
|
||||
playBannedBgm();
|
||||
|
||||
// there's currently no way to reconnect after a kick/ban so just dispose of the ui entirely
|
||||
if(views.count() > 1)
|
||||
views.shift();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Umi.Server.watch('session:start', start => {
|
||||
if(dumpEvents) console.log('session:start', start);
|
||||
|
||||
|
@ -697,23 +646,14 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
|||
if(dumpEvents) console.log('session:fail', fail);
|
||||
|
||||
if(fail.baka !== undefined) {
|
||||
displayBanMessage(fail.baka);
|
||||
new MamiForceDisconnectNotice(fail.baka).pushOn(views);
|
||||
return;
|
||||
}
|
||||
|
||||
const message = (reason => {
|
||||
if(reason === 'authfail')
|
||||
return 'Authentication failed.';
|
||||
if(reason === 'sockfail')
|
||||
return 'Too many active connections.';
|
||||
if(reason === 'userfail')
|
||||
return 'Name in use.';
|
||||
if(reason === 'joinfail')
|
||||
return 'You are banned.';
|
||||
return `Unknown reason: ${reason}`;
|
||||
})(fail.session.reason);
|
||||
|
||||
getLoadingOverlay('cross', 'Failed!', message);
|
||||
getLoadingOverlay(
|
||||
'cross', 'Failed!',
|
||||
sessFailReasons[fail.session.reason] ?? `Unknown reason: ${fail.session.reason}`
|
||||
);
|
||||
|
||||
if(fail.session.needsAuth)
|
||||
setTimeout(() => location.assign(futami.get('login')), 1000);
|
||||
|
@ -721,7 +661,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
|||
Umi.Server.watch('session:term', term => {
|
||||
if(dumpEvents) console.log('session:term', term);
|
||||
|
||||
displayBanMessage(term.baka);
|
||||
new MamiForceDisconnectNotice(term.baka).pushOn(views);
|
||||
});
|
||||
|
||||
Umi.Server.watch('user:add', add => {
|
||||
|
|
1
src/mami.js/sleep.js
Normal file
1
src/mami.js/sleep.js
Normal file
|
@ -0,0 +1 @@
|
|||
const MamiSleep = durationMs => new Promise(resolve => { setTimeout(resolve, durationMs); });
|
82
src/mami.js/ui/baka.jsx
Normal file
82
src/mami.js/ui/baka.jsx
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include animate.js
|
||||
#include easings.js
|
||||
#include rng.js
|
||||
|
||||
const MamiForceDisconnectNotice = function(banInfo) {
|
||||
const message = (() => {
|
||||
if(banInfo.perma)
|
||||
return 'You have been banned till the end of time, please try again in a different dimension';
|
||||
if(banInfo.until)
|
||||
return `You were banned until ${banInfo.until.toLocaleString()}`;
|
||||
return 'You were kicked, refresh to log back in';
|
||||
})();
|
||||
|
||||
let marqueeElem;
|
||||
const html = <div class="baka">
|
||||
<div class="baka-container">
|
||||
<div class="baka-duration">
|
||||
<div class="baka-duration-inner">{message}</div>
|
||||
</div>
|
||||
{marqueeElem = <div class="baka-marquee"></div>}
|
||||
</div>
|
||||
<div class="baka-bottom"/>
|
||||
</div>;
|
||||
|
||||
const marqueeString = banInfo.type === 'kick' ? 'Kicked' : 'Banned';
|
||||
for(let i = 0; i < 10; ++i)
|
||||
marqueeElem.append(<div class="baka-marquee-text">{marqueeString}</div>);
|
||||
|
||||
const rng = new MamiRNG;
|
||||
let sfxBuf, sfxSrc, bgmSrc;
|
||||
|
||||
const pub = {
|
||||
getElement: () => html,
|
||||
onViewPush: async () => {
|
||||
try {
|
||||
sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun');
|
||||
sfxSrc = mami.sound.audio.createSource(sfxBuf);
|
||||
} catch(ex) {
|
||||
sfxBuf = sfxSrc = undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
bgmSrc = await mami.sound.library.loadSource('touhou:th10score');
|
||||
bgmSrc.setLoop(true, 10.512, 38.074);
|
||||
} catch(ex) {
|
||||
bgmSrc = undefined;
|
||||
}
|
||||
},
|
||||
onViewPop: async () => {
|
||||
bgmSrc?.stop();
|
||||
bgmSrc = sfxBuf = sfxSrc = undefined;
|
||||
},
|
||||
pushOn: async views => {
|
||||
const rotate = rng.next(-20, 20);
|
||||
|
||||
await views.push(pub, ctx => MamiAnimate({
|
||||
async: true,
|
||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||
start: () => {
|
||||
sfxSrc?.play();
|
||||
ctx.toElem.style.top = '-100%';
|
||||
},
|
||||
update: t => {
|
||||
const tOutBounce = MamiEasings.outBounce(t);
|
||||
ctx.toElem.style.top = `${-100 + (tOutBounce * 100)}%`;
|
||||
|
||||
const tOutExpo = MamiEasings.outExpo(t);
|
||||
ctx.fromElem.style.transform = `scale(${1 - (1 * tOutExpo)}) rotate(${rotate * tOutExpo}deg)`;
|
||||
ctx.fromElem.style.filter = `grayscale(${tOutExpo * 100}%)`;
|
||||
},
|
||||
end: () => {
|
||||
bgmSrc?.play();
|
||||
ctx.toElem.style.top = null;
|
||||
ctx.fromElem.style.transform = null;
|
||||
ctx.fromElem.style.filter = null;
|
||||
},
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
return pub;
|
||||
};
|
|
@ -1,12 +1,14 @@
|
|||
#include animate.js
|
||||
#include common.js
|
||||
#include emotes.js
|
||||
#include sleep.js
|
||||
#include utility.js
|
||||
#include youare.jsx
|
||||
#include settings/backup.js
|
||||
#include ui/baka.jsx
|
||||
#include ui/emotes.js
|
||||
#include ui/menus.js
|
||||
#include ui/view.js
|
||||
#include ui/youare.jsx
|
||||
|
||||
Umi.UI.Settings = (function() {
|
||||
const items = [
|
||||
|
@ -384,6 +386,20 @@ Umi.UI.Settings = (function() {
|
|||
title: 'Disable Old Theme System',
|
||||
type: 'checkbox',
|
||||
},
|
||||
{
|
||||
title: 'Test kick/ban notice',
|
||||
type: 'button',
|
||||
invoke: async button => {
|
||||
button.disabled = true;
|
||||
await (new MamiForceDisconnectNotice({
|
||||
perma: true,
|
||||
type: 'ban',
|
||||
})).pushOn(mami.views);
|
||||
await MamiSleep(5000);
|
||||
await mami.views.pop();
|
||||
button.disabled = false;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'You are an idiot!',
|
||||
type: 'button',
|
||||
|
|
Loading…
Reference in a new issue