Make fixes for the cybrespace theme
This commit is contained in:
parent
c17216abb4
commit
aa59fde3f4
12 changed files with 2599 additions and 321 deletions
|
@ -1,25 +1,8 @@
|
||||||
pack:
|
pack:
|
||||||
admin:
|
|
||||||
- ../glitch/packs/admin.js
|
|
||||||
- ../glitch/packs/public.js
|
|
||||||
auth: ../glitch/packs/public.js
|
|
||||||
common:
|
common:
|
||||||
filename: ../glitch/packs/common.js
|
filename: pack/common.js
|
||||||
stylesheet: true
|
stylesheet: true
|
||||||
embed: ../glitch/packs/public.js
|
|
||||||
error: ../glitch/packs/error.js
|
|
||||||
home:
|
|
||||||
filename: ../glitch/packs/home.js
|
|
||||||
preload:
|
|
||||||
- flavours/glitch/async/compose
|
|
||||||
- flavours/glitch/async/getting_started
|
|
||||||
- flavours/glitch/async/home_timeline
|
|
||||||
- flavours/glitch/async/notifications
|
|
||||||
mailer:
|
|
||||||
modal:
|
|
||||||
public: ../glitch/packs/public.js
|
|
||||||
settings: ../glitch/packs/settings.js
|
|
||||||
share: ../glitch/packs/share.js
|
|
||||||
|
|
||||||
|
|
||||||
locales: locales
|
locales: locales
|
||||||
|
inherit_locales: glitch
|
||||||
|
fallback: glitch
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
|
||||||
import { start } from '../mastodon/common';
|
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
||||||
function loaded() {
|
|
||||||
const TimelineContainer = require('../mastodon/containers/timeline_container').default;
|
|
||||||
const React = require('react');
|
|
||||||
const ReactDOM = require('react-dom');
|
|
||||||
const mountNode = document.getElementById('mastodon-timeline');
|
|
||||||
|
|
||||||
if (mountNode !== null) {
|
|
||||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
|
||||||
ReactDOM.render(<TimelineContainer {...props} />, mountNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const ready = require('../mastodon/ready').default;
|
|
||||||
ready(loaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadPolyfills().then(main).catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
|
@ -1,24 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import ready from '../mastodon/ready';
|
|
||||||
|
|
||||||
ready(() => {
|
|
||||||
const React = require('react');
|
|
||||||
const ReactDOM = require('react-dom');
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('[data-admin-component]'), element => {
|
|
||||||
const componentName = element.getAttribute('data-admin-component');
|
|
||||||
const { locale, ...componentProps } = JSON.parse(element.getAttribute('data-props'));
|
|
||||||
|
|
||||||
import('../mastodon/containers/admin_component').then(({ default: AdminComponent }) => {
|
|
||||||
return import('../mastodon/components/admin/' + componentName).then(({ default: Component }) => {
|
|
||||||
ReactDOM.render((
|
|
||||||
<AdminComponent locale={locale}>
|
|
||||||
<Component {...componentProps} />
|
|
||||||
</AdminComponent>
|
|
||||||
), element);
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,13 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
|
||||||
import { start } from '../mastodon/common';
|
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
||||||
loadPolyfills().then(async () => {
|
|
||||||
const { default: main } = await import('mastodon/main');
|
|
||||||
|
|
||||||
return main();
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
|
@ -1,2 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import 'styles/application.scss';
|
|
|
@ -1,14 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import ready from '../mastodon/ready';
|
|
||||||
|
|
||||||
ready(() => {
|
|
||||||
const image = document.querySelector('img');
|
|
||||||
|
|
||||||
image.addEventListener('mouseenter', () => {
|
|
||||||
image.src = '/oops.gif';
|
|
||||||
});
|
|
||||||
|
|
||||||
image.addEventListener('mouseleave', () => {
|
|
||||||
image.src = '/oops.png';
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Dynamically set webpack's loading path depending on a meta header, in order
|
|
||||||
// to share the same assets regardless of instance configuration.
|
|
||||||
// See https://webpack.js.org/guides/public-path/#on-the-fly
|
|
||||||
|
|
||||||
function removeOuterSlashes(string) {
|
|
||||||
return string.replace(/^\/*/, '').replace(/\/*$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatPublicPath(host = '', path = '') {
|
|
||||||
let formattedHost = removeOuterSlashes(host);
|
|
||||||
if (formattedHost && !/^http/i.test(formattedHost)) {
|
|
||||||
formattedHost = `//${formattedHost}`;
|
|
||||||
}
|
|
||||||
const formattedPath = removeOuterSlashes(path);
|
|
||||||
return `${formattedHost}/${formattedPath}/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cdnHost = document.querySelector('meta[name=cdn-host]');
|
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase, no-undef, no-unused-vars
|
|
||||||
__webpack_public_path__ = formatPublicPath(cdnHost ? cdnHost.content : '', process.env.PUBLIC_OUTPUT_PATH);
|
|
|
@ -1,175 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
|
||||||
import ready from '../mastodon/ready';
|
|
||||||
import { start } from '../mastodon/common';
|
|
||||||
import loadKeyboardExtensions from '../mastodon/load_keyboard_extensions';
|
|
||||||
import 'cocoon-js-vanilla';
|
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const IntlMessageFormat = require('intl-messageformat').default;
|
|
||||||
const { timeAgoString } = require('../mastodon/components/relative_timestamp');
|
|
||||||
const { delegate } = require('@rails/ujs');
|
|
||||||
const emojify = require('../mastodon/features/emoji/emoji').default;
|
|
||||||
const { getLocale } = require('../mastodon/locales');
|
|
||||||
const { messages } = getLocale();
|
|
||||||
const React = require('react');
|
|
||||||
const ReactDOM = require('react-dom');
|
|
||||||
const Rellax = require('rellax');
|
|
||||||
const { createBrowserHistory } = require('history');
|
|
||||||
|
|
||||||
const scrollToDetailedStatus = () => {
|
|
||||||
const history = createBrowserHistory();
|
|
||||||
const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');
|
|
||||||
const location = history.location;
|
|
||||||
|
|
||||||
if (detailedStatuses.length === 1 && (!location.state || !location.state.scrolledToDetailedStatus)) {
|
|
||||||
detailedStatuses[0].scrollIntoView();
|
|
||||||
history.replace(location.pathname, { ...location.state, scrolledToDetailedStatus: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getEmojiAnimationHandler = (swapTo) => {
|
|
||||||
return ({ target }) => {
|
|
||||||
target.src = target.getAttribute(swapTo);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
ready(() => {
|
|
||||||
const locale = document.documentElement.lang;
|
|
||||||
|
|
||||||
const dateTimeFormat = new Intl.DateTimeFormat(locale, {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
});
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('.emojify'), (content) => {
|
|
||||||
content.innerHTML = emojify(content.innerHTML);
|
|
||||||
});
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('time.formatted'), (content) => {
|
|
||||||
const datetime = new Date(content.getAttribute('datetime'));
|
|
||||||
const formattedDate = dateTimeFormat.format(datetime);
|
|
||||||
|
|
||||||
content.title = formattedDate;
|
|
||||||
content.textContent = formattedDate;
|
|
||||||
});
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
|
|
||||||
const datetime = new Date(content.getAttribute('datetime'));
|
|
||||||
const now = new Date();
|
|
||||||
|
|
||||||
content.title = dateTimeFormat.format(datetime);
|
|
||||||
content.textContent = timeAgoString({
|
|
||||||
formatMessage: ({ id, defaultMessage }, values) => (new IntlMessageFormat(messages[id] || defaultMessage, locale)).format(values),
|
|
||||||
formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date),
|
|
||||||
}, datetime, now, now.getFullYear(), content.getAttribute('datetime').includes('T'));
|
|
||||||
});
|
|
||||||
|
|
||||||
const reactComponents = document.querySelectorAll('[data-component]');
|
|
||||||
|
|
||||||
if (reactComponents.length > 0) {
|
|
||||||
import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')
|
|
||||||
.then(({ default: MediaContainer }) => {
|
|
||||||
[].forEach.call(reactComponents, (component) => {
|
|
||||||
[].forEach.call(component.children, (child) => {
|
|
||||||
component.removeChild(child);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const content = document.createElement('div');
|
|
||||||
|
|
||||||
ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);
|
|
||||||
document.body.appendChild(content);
|
|
||||||
scrollToDetailedStatus();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
scrollToDetailedStatus();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
scrollToDetailedStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
const parallaxComponents = document.querySelectorAll('.parallax');
|
|
||||||
|
|
||||||
if (parallaxComponents.length > 0 ) {
|
|
||||||
new Rellax('.parallax', { speed: -1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate(document, '#registration_user_password_confirmation,#registration_user_password', 'input', () => {
|
|
||||||
const password = document.getElementById('registration_user_password');
|
|
||||||
const confirmation = document.getElementById('registration_user_password_confirmation');
|
|
||||||
if (confirmation.value && confirmation.value.length > password.maxLength) {
|
|
||||||
confirmation.setCustomValidity((new IntlMessageFormat(messages['password_confirmation.exceeds_maxlength'] || 'Password confirmation exceeds the maximum password length', locale)).format());
|
|
||||||
} else if (password.value && password.value !== confirmation.value) {
|
|
||||||
confirmation.setCustomValidity((new IntlMessageFormat(messages['password_confirmation.mismatching'] || 'Password confirmation does not match', locale)).format());
|
|
||||||
} else {
|
|
||||||
confirmation.setCustomValidity('');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
delegate(document, '#user_password,#user_password_confirmation', 'input', () => {
|
|
||||||
const password = document.getElementById('user_password');
|
|
||||||
const confirmation = document.getElementById('user_password_confirmation');
|
|
||||||
if (!confirmation) return;
|
|
||||||
|
|
||||||
if (confirmation.value && confirmation.value.length > password.maxLength) {
|
|
||||||
confirmation.setCustomValidity((new IntlMessageFormat(messages['password_confirmation.exceeds_maxlength'] || 'Password confirmation exceeds the maximum password length', locale)).format());
|
|
||||||
} else if (password.value && password.value !== confirmation.value) {
|
|
||||||
confirmation.setCustomValidity((new IntlMessageFormat(messages['password_confirmation.mismatching'] || 'Password confirmation does not match', locale)).format());
|
|
||||||
} else {
|
|
||||||
confirmation.setCustomValidity('');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
|
|
||||||
delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
|
|
||||||
|
|
||||||
delegate(document, '.status__content__spoiler-link', 'click', function() {
|
|
||||||
const statusEl = this.parentNode.parentNode;
|
|
||||||
|
|
||||||
if (statusEl.dataset.spoiler === 'expanded') {
|
|
||||||
statusEl.dataset.spoiler = 'folded';
|
|
||||||
this.textContent = (new IntlMessageFormat(messages['status.show_more'] || 'Show more', locale)).format();
|
|
||||||
} else {
|
|
||||||
statusEl.dataset.spoiler = 'expanded';
|
|
||||||
this.textContent = (new IntlMessageFormat(messages['status.show_less'] || 'Show less', locale)).format();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => {
|
|
||||||
const statusEl = spoilerLink.parentNode.parentNode;
|
|
||||||
const message = (statusEl.dataset.spoiler === 'expanded') ? (messages['status.show_less'] || 'Show less') : (messages['status.show_more'] || 'Show more');
|
|
||||||
spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
delegate(document, '.sidebar__toggle__icon', 'click', () => {
|
|
||||||
document.querySelector('.sidebar ul').classList.toggle('visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Empty the honeypot fields in JS in case something like an extension
|
|
||||||
// automatically filled them.
|
|
||||||
delegate(document, '#registration_new_user,#new_user', 'submit', () => {
|
|
||||||
['user_website', 'user_confirm_password', 'registration_user_website', 'registration_user_confirm_password'].forEach(id => {
|
|
||||||
const field = document.getElementById(id);
|
|
||||||
if (field) {
|
|
||||||
field.value = '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadPolyfills()
|
|
||||||
.then(main)
|
|
||||||
.then(loadKeyboardExtensions)
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
import './public-path';
|
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
|
||||||
import { start } from '../mastodon/common';
|
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
||||||
function loaded() {
|
|
||||||
const ComposeContainer = require('../mastodon/containers/compose_container').default;
|
|
||||||
const React = require('react');
|
|
||||||
const ReactDOM = require('react-dom');
|
|
||||||
const mountNode = document.getElementById('mastodon-compose');
|
|
||||||
|
|
||||||
if (mountNode !== null) {
|
|
||||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
|
||||||
ReactDOM.render(<ComposeContainer {...props} />, mountNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const ready = require('../mastodon/ready').default;
|
|
||||||
ready(loaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadPolyfills().then(main).catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
3
app/javascript/skins/cybrespace/win95/common.scss
Normal file
3
app/javascript/skins/cybrespace/win95/common.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@import '../cybrespace/components';
|
||||||
|
@import '~flavours/glitch/styles/index';
|
||||||
|
@import 'win95';
|
4
app/javascript/skins/cybrespace/win95/names.yml
Normal file
4
app/javascript/skins/cybrespace/win95/names.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
en:
|
||||||
|
skins:
|
||||||
|
cybrespace:
|
||||||
|
win95: "cybre.space Windows 95 theme"
|
2589
app/javascript/skins/cybrespace/win95/win95.scss
Normal file
2589
app/javascript/skins/cybrespace/win95/win95.scss
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue