Compare commits

...

2 commits

38 changed files with 226 additions and 217 deletions

View file

@ -120,8 +120,8 @@ const MamiAnimate = info => {
}
return {
getCompletion: () => tCompletion,
getRawCompletion: () => tRawCompletion,
get completion() { return tCompletion; },
get rawCompletion() { return tRawCompletion; },
start: () => {
if(!started) {
started = true;

View file

@ -5,19 +5,10 @@ const MamiDetectAutoPlaySource = '/+NIxA!!FhpbmcA#PA$wA@fgAV$#q$#/$#A#OUxBTUUzLj
const MamiDetectAutoPlay = async () => {
try {
const audio = $e('audio', { src: 'data:audio/mpeg;base64,' + MamiSRLE.decode(MamiDetectAutoPlaySource) });
try {
await audio.play();
} catch(ex) {
if('name' in ex && ex.name !== 'NotAllowedError' && ex.name !== 'AbortError') {
console.error(ex);
throw ex;
}
return false;
}
} catch(ex) {}
await $e('audio', { src: 'data:audio/mpeg;base64,' + MamiSRLE.decode(MamiDetectAutoPlaySource) }).play();
} catch(ex) {
return false;
}
return true;
};

View file

@ -35,24 +35,24 @@ const MamiAudioContext = function() {
reset();
return {
getAudioContext: () => ctx,
getAudioContextGain: () => mainGain,
get audioContext() { return ctx; },
get audioContextGain() { return mainGain; },
isReady: () => ctx !== undefined,
get ready() { return ctx !== undefined; },
reset: reset,
onReset: handler => {
if(!onReset.includes(handler))
onReset.push(handler);
},
getVolume: () => volume,
setVolume: vol => {
volume = vol;
get volume() { return volume; },
set volume(value) {
volume = value;
if(!isMuted && mainGain !== undefined)
mainGain.gain.value = volume;
},
isMuted: () => isMuted,
setMuted: mute => {
get muted() { return isMuted; },
set muted(mute) {
isMuted = mute;
if(mainGain !== undefined)
mainGain.gain.value = isMuted ? 0 : volume;

View file

@ -2,14 +2,14 @@ const MamiAudioSourceDummy = function() {
return {
play: async () => {},
stop: () => {},
getRate: () => 0,
setRate: rate => {},
getDetune: () => 0,
setDetune: rate => {},
getVolume: () => 0,
setVolume: volume => {},
isMuted: () => true,
setMuted: mute => {},
get rate() { return 0; },
set rate(rate) {},
get detune() { return 0; },
set detune(rate) {},
get volume() { return 0; },
set volume(value) {},
get muted() { return true; },
set muted(mute) {},
setLoop: (loop, start, end) => {},
};
};
@ -43,8 +43,8 @@ const MamiAudioSource = function(source, gain, buffer) {
disconnect();
},
getRate: () => source.playbackRate.value,
setRate: rate => {
get rate() { return source.playbackRate.value; },
set rate(rate) {
source.playbackRate.value = Math.min(
source.playbackRate.maxValue,
Math.max(
@ -53,8 +53,8 @@ const MamiAudioSource = function(source, gain, buffer) {
)
);
},
getDetune: () => source.detune.value,
setDetune: rate => {
get detune() { return source.detune.value; },
set detune(rate) {
source.detune.value = Math.min(
source.detune.maxValue,
Math.max(
@ -64,14 +64,14 @@ const MamiAudioSource = function(source, gain, buffer) {
);
},
getVolume: () => volume,
setVolume: vol => {
volume = vol;
get volume() { return volume; },
set volume(value) {
volume = value;
if(!isMuted)
gain.gain.value = volume;
},
isMuted: () => isMuted,
setMuted: mute => {
get muted() { return isMuted; },
set muted(mute) {
gain.gain.value = (isMuted = mute) ? 0 : volume;
},

View file

@ -85,7 +85,7 @@ const MamiColourPicker = function(options) {
const tabs = new MamiTabsControl({
onAdd: ctx => {
const name = ctx.info.getName(),
const name = ctx.info.name,
containerName = `colpick-tab-${name}-container`,
buttonName = `colpick-tab-${name}-button`;
@ -100,18 +100,18 @@ const MamiColourPicker = function(options) {
onclick={ctx.onClick}/>);
},
onRemove: ctx => {
const name = ctx.info.getName();
const name = ctx.info.name;
$rq(`.colpick-tab-${name}-button`);
$rq(`.colpick-tab-${name}-container`);
},
onSwitch: ctx => {
if(ctx.from !== undefined) {
ctx.from.elem.classList.toggle('colpick-tab-container-inactive', true);
$q(`.colpick-tab-${ctx.from.info.getName()}-button`).classList.toggle('colpick-tab-button-active', false);
$q(`.colpick-tab-${ctx.from.info.name}-button`).classList.toggle('colpick-tab-button-active', false);
}
ctx.elem.classList.toggle('colpick-tab-container-inactive', false);
$q(`.colpick-tab-${ctx.info.getName()}-button`).classList.toggle('colpick-tab-button-active', true);
$q(`.colpick-tab-${ctx.info.name}-button`).classList.toggle('colpick-tab-button-active', true);
},
});
@ -122,7 +122,7 @@ const MamiColourPicker = function(options) {
if(options.showSlidersTab)
tabs.add(new MamiColourPickerSlidersTab);
if(tabs.count() < 1)
if(tabs.count < 1)
html.removeChild(tabsElem);
const addValue = (id, name, valueInfo) => {
@ -162,9 +162,9 @@ const MamiColourPicker = function(options) {
setColour(options.colour);
return {
getElement: () => html,
getColour: () => colour,
setColour: setColour,
get element() { return html; },
get colour() { return colour; },
set colour(value) { setColour(value); },
setPosition: setPosition,
close: close,
dialog: pos => {

View file

@ -23,9 +23,9 @@ const MamiColourPickerGridTab = function() {
}
return {
getName: () => 'grid',
getTitle: () => 'Grid',
getElement: () => html,
get name() { return 'grid'; },
get title() { return 'Grid'; },
get element() { return html; },
onChange: handler => onChange = handler,
updateColour: colour => {
let elem = html.querySelector('.colpick-grid-option-active');

View file

@ -11,9 +11,9 @@ const MamiColourPickerPresetsTab = function(presets) {
type="button" onclick={() => onChange(preset.c)}/>);
return {
getName: () => 'presets',
getTitle: () => 'Presets',
getElement: () => html,
get name() { return 'presets'; },
get title() { return 'Presets'; },
get element() { return html; },
onChange: handler => onChange = handler,
updateColour: colour => {
let elem = html.querySelector('.colpick-presets-option-active');

View file

@ -18,7 +18,7 @@ const MamiColourPickerSlider = function(name, title, mask, shift) {
</div>;
return {
getElement: () => html,
get element() { return html; },
onChange: handler => onChange = handler,
updateColour: colour => {
const masked = colour & mask,
@ -43,9 +43,9 @@ const MamiColourPickerSlidersTab = function() {
const html = <div>{...sliders}</div>;
return {
getName: () => 'sliders',
getTitle: () => 'Sliders',
getElement: () => html,
get name() { return 'sliders'; },
get title() { return 'Sliders'; },
get element() { return html; },
onChange: handler => {
for(const slider of sliders)
slider.onChange(handler);

View file

@ -11,7 +11,7 @@ const MamiColourPickerValueHex = function() {
}}/>;
return {
getElement: () => html,
get element() { return html; },
onChange: handler => onChange = handler,
updateColour: colour => html.value = MamiColour.hex(colour),
};

View file

@ -6,7 +6,7 @@ const MamiColourPickerValueRaw = function() {
onchange={() => onChange(Math.min(html.max, Math.max(html.min, html.value)))}/>;
return {
getElement: () => html,
get element() { return html; },
onChange: handler => onChange = handler,
updateColour: colour => html.value = colour,
};

View file

@ -13,13 +13,14 @@ const MamiPingIndicator = function(initialStrength) {
for(let i = 1; i <= 3; ++i)
bars.push(html.appendChild(<div class={`ping-bar ping-bar-${i}`}/>));
let interval;
let interval, strength;
const setStrength = strength => {
if(typeof strength !== 'number')
throw 'strength must be a number';
const setStrength = value => {
if(typeof value !== 'number')
throw 'value must be a number';
if(strength < 0) {
strength = value;
if(value < 0) {
if(interval === undefined) {
const cyclesMax = bars.length * 2;
let cycles = -1;
@ -43,12 +44,12 @@ const MamiPingIndicator = function(initialStrength) {
}
for(const i in bars)
bars[i].classList.toggle('ping-bar-on', i < strength);
bars[i].classList.toggle('ping-bar-on', i < value);
}
html.classList.toggle('ping-state-good', strength > 1);
html.classList.toggle('ping-state-warn', strength == 1);
html.classList.toggle('ping-state-poor', strength < 1);
html.classList.toggle('ping-state-good', value > 1);
html.classList.toggle('ping-state-warn', value == 1);
html.classList.toggle('ping-state-poor', value < 1);
};
if(typeof initialStrength !== 'number')
@ -58,7 +59,7 @@ const MamiPingIndicator = function(initialStrength) {
return {
get element() { return html; },
getElement: () => html,
setStrength: setStrength,
get strength() { return strength; },
set strength(value) { setStrength(value); },
};
};

View file

@ -8,9 +8,9 @@ const MamiTabsControl = function(options) {
define('onSwitch').required().type('function').done();
});
const onAdd = options.onAdd,
onRemove = options.onRemove,
onSwitch = options.onSwitch;
const onAdd = options.onAdd;
const onRemove = options.onRemove;
const onSwitch = options.onSwitch;
const tabs = new Map;
let currentTab;
@ -19,6 +19,8 @@ const MamiTabsControl = function(options) {
let element;
if(elementInfo instanceof Element) {
element = elementInfo;
} else if('element' in elementInfo) {
element = elementInfo.element;
} else if('getElement' in elementInfo) {
element = elementInfo.getElement();
} else throw 'elementInfo is not a valid type';
@ -106,15 +108,15 @@ const MamiTabsControl = function(options) {
return {
switch: switchTab,
current: () => currentTab,
currentId: () => getExistingTabId(currentTab),
currentElement: () => {
get current() { return currentTab; },
get currentId() { return getExistingTabId(currentTab); },
get currentElement() {
if(currentTab === undefined)
return undefined;
return extractElement(currentTab);
},
count: () => tabs.size,
get count() { return tabs.size; },
has: tabInfo => getExistingTabId(tabInfo) !== undefined,
add: async (tabInfo, title) => {
if(typeof tabInfo !== 'object')
@ -127,8 +129,8 @@ const MamiTabsControl = function(options) {
tabId = MamiUniqueStr(8);
tabs.set(tabId, tabInfo);
if(title !== 'string' && 'getTitle' in tabInfo)
title = tabInfo.getTitle();
if(title !== 'string' && 'title' in tabInfo)
title = tabInfo.title;
const element = extractElement(tabInfo);

View file

@ -15,6 +15,8 @@ const MamiViewsControl = function(options) {
let element;
if(elementInfo instanceof Element) {
element = elementInfo;
} else if('element' in elementInfo) {
element = elementInfo.element;
} else if('getElement' in elementInfo) {
element = elementInfo.getElement();
} else throw 'elementInfo is not a valid type';
@ -155,9 +157,9 @@ const MamiViewsControl = function(options) {
push: push,
pop: pop,
raise: raise,
count: () => views.length,
current: current,
currentElement: () => {
get count() { return views.length; },
get current() { return current(); },
get currentElement() {
const currentInfo = current();
if(currentInfo === undefined)
return undefined;

View file

@ -70,20 +70,20 @@ const MamiInit = async args => {
await ctx.views.push(loadingOverlay);
if(!('futami' in window)) {
loadingOverlay.setMessage('Loading environment...');
loadingOverlay.message = 'Loading environment...';
try {
window.futami = await FutamiCommon.load();
} catch(ex) {
console.error('Failed to load common settings.', ex);
loadingOverlay.setIcon('cross');
loadingOverlay.setHeader('Failed!');
loadingOverlay.setMessage('Failed to load common settings.');
loadingOverlay.icon = 'cross';
loadingOverlay.header = 'Failed!';
loadingOverlay.message = 'Failed to load common settings.';
return;
}
}
if(!MamiMisuzuAuth.hasInfo()) {
loadingOverlay.setMessage('Fetching credentials...');
loadingOverlay.message = 'Fetching credentials...';
try {
const auth = await MamiMisuzuAuth.update();
if(!auth.ok)
@ -104,7 +104,7 @@ const MamiInit = async args => {
}
loadingOverlay.setMessage('Loading settings...');
loadingOverlay.message = 'Loading settings...';
const settings = new MamiSettings(args.settingsPrefix, ctx.events.scopeTo('settings'));
ctx.settings = settings;
@ -156,7 +156,7 @@ const MamiInit = async args => {
settings.define('notificationTriggers').default('').immutable(noNotifSupport).create();
loadingOverlay.setMessage('Loading sounds...');
loadingOverlay.message = 'Loading sounds...';
const soundCtx = new MamiSoundContext;
ctx.sound = soundCtx;
@ -201,7 +201,7 @@ const MamiInit = async args => {
let packName = ev.detail.value;
if(packName === '') {
const names = packs.names();
const names = packs.names;
if(names.length < 1)
return;
@ -222,7 +222,7 @@ const MamiInit = async args => {
// loading these asynchronously makes them not show up in the backlog
// revisit when emote reparsing is implemented
loadingOverlay.setMessage('Loading emoticons...');
loadingOverlay.message = 'Loading emoticons...';
try {
const emotes = await futami.getJson('emotes');
MamiEmotes.loadLegacy(emotes);
@ -251,7 +251,7 @@ const MamiInit = async args => {
});
loadingOverlay.setMessage('Preparing UI...');
loadingOverlay.message = 'Preparing UI...';
ctx.textTriggers = new MamiTextTriggers;
@ -330,7 +330,7 @@ const MamiInit = async args => {
settings.watch('playJokeSounds', ev => {
if(!ev.detail.value) return;
if(!ctx.textTriggers.hasTriggers())
if(!ctx.textTriggers.hasTriggers)
futami.getJson('texttriggers').then(trigInfos => ctx.textTriggers.addTriggers(trigInfos));
});
@ -348,12 +348,12 @@ const MamiInit = async args => {
}
}
OsuKeys.setEnable(ev.detail.value !== 'no');
OsuKeys.setRandomRate(ev.detail.value === 'rng');
OsuKeys.enable = ev.detail.value !== 'no';
OsuKeys.randomRate = ev.detail.value === 'rng';
});
loadingOverlay.setMessage('Building menus...');
loadingOverlay.message = 'Building menus...';
MamiCompat('Umi.Parser.SockChatBBcode.EmbedStub', { value: () => {} }); // intentionally a no-op
MamiCompat('Umi.UI.View.SetText', { value: text => console.log(`Umi.UI.View.SetText(text: ${text})`) });
@ -461,8 +461,8 @@ const MamiInit = async args => {
category.setting('soundPack').title('Sound pack').type('select').options(() => {
const options = { '': 'Default' };
for(const name of soundCtx.packs.names())
options[name] = soundCtx.packs.info(name).getTitle();
for(const name of soundCtx.packs.names)
options[name] = soundCtx.packs.info(name).title;
return options;
}).done();
@ -795,15 +795,15 @@ const MamiInit = async args => {
});
loadingOverlay.setMessage('Connecting...');
loadingOverlay.message = 'Connecting...';
const setLoadingOverlay = async (icon, header, message, optional) => {
const currentView = ctx.views.current();
const currentView = ctx.views.current;
if('setIcon' in currentView) {
currentView.setIcon(icon);
currentView.setHeader(header);
currentView.setMessage(message);
if('icon' in currentView) {
currentView.icon = icon;
currentView.header = header;
currentView.message = message;
return currentView;
}
@ -837,7 +837,7 @@ const MamiInit = async args => {
return;
sbActPing.pingMs = -1;
pingIndicator.setStrength(-1);
pingIndicator.strength = -1;
const reconManAttempt = ev => {
if(sockChatRestarting || ev.detail.delay > 2000)

View file

@ -31,7 +31,7 @@ const MamiForceDisconnectNotice = function(banInfo) {
let sfxBuf, bgmSrc;
const pub = {
getElement: () => html,
get element() { return html; },
onViewPush: async () => {
try {
sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun');

View file

@ -21,7 +21,7 @@ const MamiYouAreAnIdiot = function(sndLibrary, views) {
let soundSrc;
const pub = {
getElement: () => html,
get element() { return html; },
onViewPush: async () => {
try {
soundSrc = await sndLibrary.loadSource('misc:youare');

View file

@ -31,7 +31,7 @@ const MamiRNG = function(seed) {
vars[mjVal] = seedArray[ii];
}
for(let k = 1; k < 5; k++) {
for(let k = 1; k < 5; k++)
for(let i = 0; i < 56; i++) {
let n = i + 30;
@ -43,15 +43,14 @@ const MamiRNG = function(seed) {
if(seedArray[i] < 0)
seedArray[i] += MBIG;
}
}
let inext = 0,
inextp = 21;
let inext = 0;
let inextp = 21;
const internalSample = function() {
const internalSample = () => {
const retVal = new Int32Array(1);
let locINext = inext,
locINextp = inextp;
let locINext = inext;
let locINextp = inextp;
if(++locINext >= 56)
locINext = 1;
@ -73,19 +72,17 @@ const MamiRNG = function(seed) {
return retVal[0];
};
const sample = function() {
return internalSample() * (1.0 / MBIG);
};
const sample = () => internalSample() * (1.0 / MBIG);
return {
sample: sample,
next: function(minValue, maxValue) {
let hasMinVal = (typeof minValue).toLowerCase() === 'number',
hasMaxVal = (typeof maxValue).toLowerCase() === 'number';
const vars = new Int32Array(3),
minVal = 0, maxVal = 1, retVal = 2;
next: (minValue, maxValue) => {
let hasMinVal = (typeof minValue).toLowerCase() === 'number';
let hasMaxVal = (typeof maxValue).toLowerCase() === 'number';
const vars = new Int32Array(3);
const minVal = 0, maxVal = 1, retVal = 2;
if(hasMinVal) {
if(hasMinVal)
if(!hasMaxVal) {
hasMinVal = false;
hasMaxVal = true;
@ -94,7 +91,6 @@ const MamiRNG = function(seed) {
vars[minVal] = minValue;
vars[maxVal] = maxValue;
}
}
if(hasMaxVal) {
if(hasMinVal) {

View file

@ -7,7 +7,7 @@ const MamiSettingsBackup = function(settings) {
const maxVersion = 1;
const exportData = () => {
const names = settings.names();
const names = settings.names;
const data = { a: header, v: version, d: [] };
for(const name of names) {

View file

@ -13,9 +13,9 @@ const MamiSettingsScoped = function(settings, prefix) {
define: name => settings.define(prefix + name),
defined: name => settings.defined(prefix + name),
info: name => settings.info(prefix + name),
names: () => {
get names() {
const filtered = [];
const names = settings.names();
const names = settings.names;
for(const name in names)
if(name.startsWith(prefix))

View file

@ -25,7 +25,7 @@ const MamiSettings = function(storageOrPrefix, eventTarget) {
});
const dispatchUpdate = (name, value, silent, local) => eventTarget.dispatch(createUpdateEvent(name, value, false, silent, local));
const broadcast = new BroadcastChannel(`${MAMI_MAIN_JS}:settings:${storage.name()}`);
const broadcast = new BroadcastChannel(`${MAMI_MAIN_JS}:settings:${storage.name}`);
const broadcastUpdate = (name, value, silent) => {
setTimeout(() => broadcast.postMessage({ act: 'update', name: name, value: value, silent: !!silent }), 0);
};
@ -211,7 +211,7 @@ const MamiSettings = function(storageOrPrefix, eventTarget) {
define: name => new settingBlueprint(name),
defined: name => settings.has(name),
info: name => getSetting(name),
names: () => Array.from(settings.keys()),
get names() { return Array.from(settings.keys()); },
has: name => {
const setting = settings.get(name);
return setting !== undefined

View file

@ -2,7 +2,7 @@ const MamiSettingsVirtualStorage = function(storage) {
const virtuals = new Map;
return {
name: () => `virtual:${storage.name()}`,
get name() { return `virtual:${storage.name}`; },
virtualise: name => virtuals.set(name, storage.get(name)),
get: name => {
if(virtuals.has(name))

View file

@ -5,7 +5,7 @@ const MamiSettingsWebStorage = function(storage, prefix) {
prefix = '';
return {
name: () => `webstorage:${prefix}`,
get name() { return `webstorage:${prefix}`; },
delete: name => storage.removeItem(prefix + name),
set: (name, value) => storage.setItem(prefix + name, value === undefined ? null : JSON.stringify(value)),
get: name => {

View file

@ -79,7 +79,7 @@ const MamiSockChatHandlers = function(
if(ev.detail.diff >= 200) --strength;
sbActPing.pingMs = ev.detail.diff;
pingIndicator.setStrength(strength);
pingIndicator.strength = strength;
};
@ -107,7 +107,7 @@ const MamiSockChatHandlers = function(
Umi.UI.Emoticons.Init();
Umi.Parsing.Init();
if(ctx.views.count() > 1)
if(ctx.views.count > 1)
ctx.views.pop();
};
handlers['session:fail'] = ev => {

View file

@ -23,11 +23,11 @@ const MamiSoundContext = function() {
pack = value;
},
get ready() { return audioCtx.isReady; },
get volume() { return audioCtx.getVolume(); },
set volume(value) { audioCtx.setVolume(value); },
get muted() { return audioCtx.isMuted; },
set muted(value) { audioCtx.setMuted(value); },
get ready() { return audioCtx.ready; },
get volume() { return audioCtx.volume; },
set volume(value) { audioCtx.volume = value; },
get muted() { return audioCtx.muted; },
set muted(value) { audioCtx.muted = value; },
reset: audioCtx.reset,
};

View file

@ -28,12 +28,12 @@ const OsuKeys = (() => {
};
return {
setEnable: function(value) {
set enable(value) {
if(value)
window.addEventListener('keydown', keyHandler);
else
window.removeEventListener('keydown', keyHandler);
},
setRandomRate: function(value) { sndRng = !!value; },
set randomRate(value) { sndRng = !!value; },
};
})();

View file

@ -5,6 +5,6 @@ const Seinfeld = (() => {
const rng = new MamiRNG;
return {
getRandom: () => `seinfeld:riff${rng.next(1, sounds + 1)}`,
get random() { return `seinfeld:riff${rng.next(1, sounds + 1)}`; },
};
})();

View file

@ -5,10 +5,10 @@ const MamiSoundInfo = function(name, isReadOnly, title, sources) {
sources = sources || {};
return {
getName: () => name,
isReadOnly: () => isReadOnly,
getTitle: () => title,
getSources: () => sources,
get name() { return name; },
get readOnly() { return isReadOnly; },
get title() { return title; },
get sources() { return sources; },
};
};
@ -46,7 +46,7 @@ const MamiSoundLibrary = function(soundMgr) {
throw 'soundInfo does not contain any valid sources';
soundInfo = new MamiSoundInfo(soundInfo.name, readOnly, soundInfo.title, sources);
sounds.set(soundInfo.getName(), soundInfo);
sounds.set(soundInfo.name, soundInfo);
return soundInfo;
};
@ -57,7 +57,7 @@ const MamiSoundLibrary = function(soundMgr) {
return sounds.get(name);
};
const getSoundSources = name => getSound(name).getSources();
const getSoundSources = name => getSound(name).sources;
const loadSoundSource = async name => await soundMgr.loadSource(getSoundSources(name));
return {
@ -69,7 +69,7 @@ const MamiSoundLibrary = function(soundMgr) {
sounds.clear();
},
info: name => getSound(name),
names: () => Array.from(sounds.keys()),
get names() { return Array.from(sounds.keys()); },
has: name => sounds.has(name),
get: getSound,
getSources: getSoundSources,
@ -82,10 +82,10 @@ const MamiSoundLibrary = function(soundMgr) {
const source = await loadSoundSource(name);
if(typeof volume === 'number')
source.setVolume(volume);
source.volume = volume;
if(typeof rate === 'number')
source.setRate(rate);
source.rate = rate;
await source.play();
},

View file

@ -25,8 +25,8 @@ const MamiSoundManager = function(context) {
})();
const extractUrl = urls => {
if(typeof urls === 'object' && typeof urls.getSources === 'function')
urls = urls.getSources();
if(typeof urls === 'object' && 'sources' in urls)
urls = urls.sources;
if(typeof urls === 'string')
return urls;

View file

@ -9,15 +9,15 @@ const MamiSoundPack = function(name, isReadOnly, title, events) {
const hasEventSound = eventName => events.has(eventName);
return {
getName: () => name,
isReadOnly: () => isReadOnly,
getTitle: () => title,
setTitle: newTitle => {
get name() { return name; },
get readOnly() { return isReadOnly; },
get title() { return title; },
set title(value) {
if(isReadOnly)
throw 'Cannot edit read only sound pack.';
title = (newTitle || '').toString();
title = (value || '').toString();
},
getEventNames: () => Array.from(events.keys()),
get eventNames() { return Array.from(events.keys()); },
hasEventSound: hasEventSound,
getEventSound: eventNames => {
let event;
@ -83,7 +83,7 @@ const MamiSoundPacks = function() {
throw 'packInfo does not contain any valid events';
packInfo = new MamiSoundPack(packInfo.name, readOnly, packInfo.title, events);
packs.set(packInfo.getName(), packInfo);
packs.set(packInfo.name, packInfo);
return packInfo;
};
@ -103,7 +103,7 @@ const MamiSoundPacks = function() {
packs.clear();
},
info: name => getPack(name),
names: () => Array.from(packs.keys()),
get names() { return Array.from(packs.keys()); },
has: name => packs.has(name),
get: getPack,
};

View file

@ -69,13 +69,13 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
rateSlider.value = ev.detail.value * 1000;
for(const source of sources)
source.setRate(ev.detail.value);
source.rate = ev.detail.value;
});
settings.watch('soundDetune', ev => {
detuneSlider.value = ev.detail.value;
for(const source of sources)
source.setDetune(ev.detail.value);
source.detune = ev.detail.value;
});
settings.watch('soundLoopStart', ev => {
loopStartBox.value = ev.detail.value;
@ -91,8 +91,8 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
let controls, state, name;
const player = <div class="sndtest-player">
<div class="sndtest-player-details">
<div class="sndtest-player-title">{info.getTitle()}</div>
{name = <div class="sndtest-player-name">{info.getName()}</div>}
<div class="sndtest-player-title">{info.title}</div>
{name = <div class="sndtest-player-name">{info.name}</div>}
</div>
{controls = <div class="sndtest-player-controls"/>}
{state = <div class="sndtest-player-state"/>}
@ -103,7 +103,7 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
let buffer, source;
try {
state.textContent = 'Loading...';
buffer = await manager.loadBuffer(info.getSources());
buffer = await manager.loadBuffer(info.sources);
name.textContent += ` (${buffer.duration})`;
source = audio.createSource(buffer, settings.get('soundReverse'));
@ -111,10 +111,10 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
state.textContent = 'Configuring...';
const rate = settings.get('soundRate');
source.setRate(rate);
source.rate = rate;
const detune = settings.get('soundDetune');
source.setDetune(detune);
source.detune = detune;
const loopStart = settings.get('soundLoopStart');
const loopEnd = settings.get('soundLoopEnd');
@ -136,10 +136,9 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
}
};
const names = library.names();
for(const name of names) {
for(const name of library.names) {
const info = library.info(name);
libraryButtons.appendChild(<button onclick={() => { startPlay(info); }} data-search={`${info.getTitle().toLowerCase()} ${info.getName().toLowerCase()}`}>{info.getTitle()} ({info.getName()})</button>);
libraryButtons.appendChild(<button onclick={() => { startPlay(info); }} data-search={`${info.title.toLowerCase()} ${info.name.toLowerCase()}`}>{info.title} ({info.name})</button>);
}
searchBox.addEventListener('change', () => {
@ -149,7 +148,7 @@ const MamiSoundTest = function(settings, audio, manager, library, clickPos) {
});
return {
getElement: () => container,
get element() { return container; },
onViewPop: async () => {
for(const source of sources)
source.stop();

View file

@ -12,7 +12,7 @@ Umi.Sound = (() => {
return;
if(mami.settings.get('seinfeld'))
return Seinfeld.getRandom();
return Seinfeld.random;
if(minecraft === 'yes')
return 'minecraft:door:open';

View file

@ -1,9 +1,9 @@
const MamiSRLE = (() => {
return {
encode: (input, cutoff) => {
let output = '',
last = '',
repeat = 0;
let output = '';
let last = '';
let repeat = 0;
input = (input || '').toString();
cutoff = cutoff || 1
@ -33,9 +33,9 @@ const MamiSRLE = (() => {
},
decode: input => {
let output = '',
repeat = '',
chr;
let output = '';
let repeat = '';
let chr;
input = (input || '').toString().split('').reverse();

View file

@ -317,10 +317,8 @@ const UmiThemeApply = function(theme) {
}
const coloursPfx = varPfx + 'colour-';
for(const propName in theme.colours) {
for(const propName in theme.colours)
document.body.style.setProperty(coloursPfx + propName, MamiColour.hex(theme.colours[propName]));
}
}
if(theme.sizes) {

View file

@ -1,6 +1,6 @@
const MamiTextTrigger = function(info) {
const type = info.type,
match = info.match;
const type = info.type;
const match = info.match;
for(const i in match) {
match[i] = match[i].split(';');
@ -9,10 +9,10 @@ const MamiTextTrigger = function(info) {
}
const pub = {
getType: function() { return type; },
isSoundType: function() { return type === 'sound'; },
isAliasType: function() { return type === 'alias'; },
isMatch: function(matchText) {
get type() { return type; },
get isSoundType() { return type === 'sound'; },
get isAliasType() { return type === 'alias'; },
isMatch: matchText => {
for(const i in match) {
const out = (function(filters, text) {
let result = false;
@ -61,22 +61,41 @@ const MamiTextTrigger = function(info) {
};
if(type === 'sound') {
const volume = info.volume || 1.0,
rate = info.rate || 1.0,
names = info.sounds || [];
const volume = info.volume ?? 1.0;
const rate = info.rate ?? 1.0;
const names = info.sounds ?? [];
pub.getVolume = function() { return volume; };
pub.getRate = function() {
if(rate === 'rng')
return 1.8 - (Math.random() * 1.5);
return rate;
};
pub.getSoundNames = function() { return names; };
pub.getRandomSoundName = function() { return names[Math.floor(Math.random() * names.length)]; };
Object.defineProperties(pub, {
volume: {
enumerable: true,
get() { return volume; },
},
rate: {
enumerable: true,
get() {
if(rate === 'rng')
return 1.8 - (Math.random() * 1.5);
return rate;
},
},
soundNames: {
enumerable: true,
get() { return names; },
},
getRandomSoundName: {
enumerable: true,
value: () => names[Math.floor(Math.random() * names.length)],
},
});
} else if(type === 'alias') {
const aliasFor = info.for || [];
const aliasFor = info.for ?? [];
pub.getFor = function() { return aliasFor; };
Object.defineProperties(pub, {
for: {
enumerable: true,
get() { return aliasFor; },
},
});
} else
throw 'Unsupported trigger type.';
@ -97,8 +116,8 @@ const MamiTextTriggers = function() {
for(const i in triggers) {
let trigger = triggers[i];
if(trigger.isMatch(text)) {
if(trigger.isAliasType() && !returnAlias) {
const aliasFor = trigger.getFor();
if(trigger.isAliasType && !returnAlias) {
const aliasFor = trigger.for;
trigger = getTrigger(aliasFor[Math.floor(Math.random() * aliasFor.length)]);
}
@ -111,7 +130,7 @@ const MamiTextTriggers = function() {
return {
addTrigger: addTrigger,
addTriggers: function(triggerInfos) {
addTriggers: triggerInfos => {
for(const i in triggerInfos)
try {
addTrigger(triggerInfos[i]);
@ -119,10 +138,10 @@ const MamiTextTriggers = function() {
console.error(ex);
}
},
clearTriggers: function() {
clearTriggers: () => {
triggers = [];
},
hasTriggers: function() {
get hasTriggers() {
return triggers.length > 0;
},
getTrigger: getTrigger,

View file

@ -38,12 +38,13 @@ Umi.UI.LoadingOverlay = function(icon, header, message) {
setMessage(message);
return {
setIcon: setIcon,
setHeader: setHeader,
setMessage: setMessage,
getElement: function() {
return html;
},
get icon() { return iconElem.className; },
set icon(value) { setIcon(value); },
get header() { return headerElem.textContent; },
set header(value) { setHeader(value); },
get message() { return messageElem.innerHTML; },
set message(value) { setMessage(value); },
get element() { return html; },
getViewTransition: mode => {
if(mode === 'pop')
return ctx => MamiAnimate({

View file

@ -29,7 +29,7 @@ Umi.UI.Markup = (function() {
presets: futami.get('colours'),
});
pickerTarget.appendChild(picker.getElement());
pickerTarget.appendChild(picker.element);
picker.dialog(picker.suggestPosition(ev))
.then(colour => insertRaw(`[color=${MamiColour.hex(colour)}]`, '[/color]'))

View file

@ -136,11 +136,11 @@ Umi.UI.Messages = (function() {
if(mami.settings.get('playJokeSounds'))
try {
const trigger = mami.textTriggers.getTrigger(msgText);
if(trigger.isSoundType()) {
if(trigger.isSoundType) {
soundIsLegacy = false;
soundName = trigger.getRandomSoundName();
soundVolume = trigger.getVolume();
soundRate = trigger.getRate();
soundVolume = trigger.volume;
soundRate = trigger.rate;
}
} catch(ex) {}
} else {

View file

@ -118,7 +118,7 @@ const $e = function(info, attrs, child, created) {
elem.appendChild(childElem);
else
elem.appendChild($e(child));
} else if(child.getElement) {
} else if('getElement' in child) {
const childElem = child.getElement();
if(childElem instanceof Element)
elem.appendChild(childElem);