19 Commits

Author SHA1 Message Date
Zoë Bijl 9ae713c083 [bugfix] make focus visible
Mastodon’s UI has been plagued with inaccessibility from the start. Removing the focus outline is one example of that. This is the start of fixing that. Removes all instances of `outline: 0 | none;`.

Next step is to add nicely styled focus outlines.
2025-10-10 01:07:35 +02:00
tobi 4b4a9f981f [chore] Update to yarn 4 (#90)
Update to yarn 4 and use `masto-fe-standalone-woodpecker-build` container for builds.

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/90
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-10-09 16:13:26 +02:00
Zoë Bijl 3faabb8280 [docs] update AUTHORS.md (#89)
Removes Mastodon authors and replaces it with Sloth Flavour authors. Also adds a special thanks section to attribute the original project authors.

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/89
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-09 15:02:45 +02:00
Zoë Bijl 5f9a92953f [docs] update changelog (#87)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/87
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-09 11:59:01 +02:00
Zoë Bijl 81445f0afd [build] upgrade to Prettier 3.6.2 (#86)
Upgrades Prettier to 3.6.2 and pins it there. Prettier [recommends pinning the version](https://prettier.io/docs/install#summary):

> Install an exact version of Prettier locally in your project. This makes sure that everyone in the project gets the exact same version of Prettier. Even a patch release of Prettier can result in slightly different formatting, so you wouldn’t want different team members using different versions and formatting each other’s changes back and forth.

---

Should probably merge after #85.

Co-authored-by: tobi <kipvandenbos@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/86
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-09 11:52:50 +02:00
Zoë Bijl adf075d19f [bugfix] Fix linter issues (#85)
- [x] .js
- [x] .json
- [x] .md
- [x] .scss
- [x] .yml

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/85
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-09 11:11:42 +02:00
Zoë Bijl 8a26776492 [docs] Add changelog based on “Keep a Changelog” (#80)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/80
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-09 11:10:00 +02:00
Zoë Bijl a011c5addf [build] update caniuse-lite browserlist (#81)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/81
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-08 14:45:40 +02:00
Zoë Bijl d7d013609c [bugfix] correctly format editorconfig (#78)
I had incorrectly assumed you could split the array over multiple lines. Also removed non-existant (for now) files.

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/78
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-05 12:00:31 +02:00
Matthew Jorgensen e36d764aaa [feature] Preserve 'mastodon-settings' from localStorage on logout (#66)
This preserves the settings for the FE, things like theme, etc.

---

Retains the `mastodon-settings` object from localStorage on logout. I think this is safe to do, it doesn't appear there's any instance-specific or otherwise sensitive info in this object:

```json
{
  "side_arm_reply_mode": "keep",
  "media": {
    "use_blurhash": true,
    "letterbox": false,
    "fullwidth": true,
    "reveal_behind_cw": false,
    "pop_in_player": true,
    "pop_in_position": "right"
  },
  "stretch": true,
  "inline_preview_cards": true,
  "hicolor_privacy_icons": false,
  "notifications": {
    "favicon_badge": false,
    "tab_badge": true
  },
  "confirm_missing_media_description": false,
  "theme": "mastodon",
  "layout": "mobile",
  "preselect_on_reply": false,
  "status_icons": {
    "language": true,
    "reply": true,
    "local_only": true,
    "media": true,
    "visibility": true
  },
  "prepend_cw_re": false,
  "confirm_boost_missing_media_description": false,
  "tag_misleading_links": true,
  "side_arm": "none",
  "collapsed": {
    "enabled": true,
    "auto": {
      "all": false,
      "notifications": false,
      "lengthy": true,
      "reblogs": false,
      "replies": false,
      "media": false,
      "height": 400
    },
    "backgrounds": {
      "user_backgrounds": false,
      "preview_images": false
    },
    "show_action_bar": true
  },
  "show_reply_count": false,
  "confirm_before_clearing_draft": true,
  "rewrite_mentions": "no",
  "content_warnings": {
    "auto_unfold": false,
    "filter": null,
    "media_outside": true,
    "shared_state": true
  },
  "always_show_spoilers_field": true,
  "show_content_type_choice": true
}

```

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/66
Co-authored-by: Matthew Jorgensen <me@prplecake.com>
Co-committed-by: Matthew Jorgensen <me@prplecake.com>
2025-10-01 14:03:18 +02:00
Zoë Bijl c6eb0b1927 [feature] Redesigned login page (#76)
Reworked the login page

- Simplified some of the HTML and CSS
- Removed some `aria-label`s
- Added alt text for the logo
- Added a label for the input field
- Added subtle borders to otherwise flat elements

![redesigned login page with the mentioned changes](/attachments/53dc5c16-deac-4a68-912e-8a4486a93b53)

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/76
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-10-01 14:02:18 +02:00
Zoë Bijl 4edb2f2b2c [docs] add documentation for yarn dev (#75)
Added a few lines about running `yarn dev`. It’s easy enough to miss which port it runs on or whether it runs a server at all. Having this explicit URL should help.

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/75
Co-authored-by: Zoë Bijl <code@moiety.me>
Co-committed-by: Zoë Bijl <code@moiety.me>
2025-09-30 11:35:34 +02:00
Sqx. Flann 110c8fb8cc [bugfix] account for data structure change in instance API fallback (#63)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/63
Co-authored-by: Sqx. Flann <fl4nn+codeberg@opensuse.org>
Co-committed-by: Sqx. Flann <fl4nn+codeberg@opensuse.org>
2025-07-14 16:42:05 +02:00
Sqx. Flann 6d0b964e2b [feature] Query media description limit (#62)
fixes #61

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/62
Co-authored-by: Sqx. Flann <fl4nn+codeberg@opensuse.org>
Co-committed-by: Sqx. Flann <fl4nn+codeberg@opensuse.org>
2025-06-23 10:51:25 +02:00
prplecake 60792ec753 [feature] Add logout button to sidebar (#48)
This one should probably be scrutinized a little more than my previous two.

For example, I don't know why I needed to do this: https://codeberg.org/prplecake/masto-fe-standalone/src/commit/1a1f48ceaa544650a8b8f50f8fa4e8c7cdc44c12/app/javascript/flavours/glitch/features/ui/index.jsx#L152

~~But, it appears to work.~~ It's live at https://masto-fe.compostintraining.club if you want to test it out.

~~Edit: it breaks stuff. Images don't load anymore...~~ Maybe that was just a network glitch...

Fixes #21.

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/48
Co-authored-by: prplecake <me@prplecake.com>
Co-committed-by: prplecake <me@prplecake.com>
2025-06-07 15:12:37 +02:00
tobi e5869dc945 [docs] Mention correct port (80 not 3000) (#58)
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/58
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-06-07 15:00:01 +02:00
prplecake f61625f4bd [bugfix] Don't show deprecated setting modal when auto unfold CWs is toggled on (#47)
Missed in #46, sorry!

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/47
Co-authored-by: prplecake <me@prplecake.com>
Co-committed-by: prplecake <me@prplecake.com>
2025-05-14 20:59:44 +00:00
prplecake 02106153ec [feature] Re-enable auto-unfold CW setting (#46)
Fixes #45

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/46
Co-authored-by: prplecake <me@prplecake.com>
Co-committed-by: prplecake <me@prplecake.com>
2025-05-14 17:23:29 +00:00
daj 8eba3f59f8 [bugfix] Update public/auth.js (#38)
trim trailing spaces from user input for Instance URL

Fix for Issue #37

Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/38
Co-authored-by: daj <daj@findmyinbox.co.uk>
Co-committed-by: daj <daj@findmyinbox.co.uk>
2025-04-27 20:56:29 +00:00
51 changed files with 18620 additions and 18576 deletions
+7
View File
@@ -0,0 +1,7 @@
root = true
[*.scss]
indent_size = 2
[login.scss]
indent_size = 4
+3
View File
@@ -55,6 +55,9 @@ npm-debug.log
yarn-error.log
yarn-debug.log
# Ignore yarn state file
.yarn/install-state.gz
# Ignore vagrant log files
*-cloudimg-console.log
-1
View File
@@ -1 +0,0 @@
20.8
+5 -5
View File
@@ -1,23 +1,23 @@
steps:
lint:
image: node:22-alpine
image: docker.io/superseriousbusiness/masto-fe-standalone-woodpecker-build:0.1.0
pull: true
# https://woodpecker-ci.org/docs/usage/volumes
volumes:
- /woodpecker/masto-fe-standalone/node_modules:/woodpecker/src/codeberg.org/superseriousbusiness/masto-fe-standalone/node_modules
- /woodpecker/masto-fe-standalone/.eslintcache:/woodpecker/src/codeberg.org/superseriousbusiness/masto-fe-standalone/.eslintcache
# https://woodpecker-ci.org/docs/administration/configuration/backends/docker#run-user
backend_options:
docker:
user: 1000:1000
# https://woodpecker-ci.org/docs/usage/workflow-syntax#commands
commands:
- yarn
- yarn lint:js
# https://woodpecker-ci.org/docs/usage/workflow-syntax#when---conditional-execution
when:
- event: pull_request
+1
View File
@@ -0,0 +1 @@
nodeLinker: node-modules
+15 -1884
View File
File diff suppressed because it is too large Load Diff
+69 -3198
View File
File diff suppressed because it is too large Load Diff
+14 -3
View File
@@ -4,11 +4,22 @@
## Dependencies
To work on the code decently, you should have Node and Yarn installed. To avoid fuckery, Node Version Manager is **highly recommended**: https://github.com/nvm-sh/nvm.
To work on the code, you must have Node installed.
To avoid fuckery, Node Version Manager is **highly recommended**: https://github.com/nvm-sh/nvm. You can then install the latest `lts` version of node with `nvm install --lts && nvm use --lts`.
You should install yarn as described [here](https://yarnpkg.com/getting-started/install) and/or [here](https://yarnpkg.com/migration/guide).
## Testing Locally
You can fairly easily test builds of Masto-FE locally by using Docker and the GoToSocial testrig.
If you want to run Masto-FE in dev mode:
- install the project: `yarn install`
- start the dev server: `yarn dev`
You should now be able to connect on http://localhost:3035. Changes will automatically compile.
You can also fairly easily test builds of Masto-FE locally by using Docker and the GoToSocial testrig.
### Build GoToSocial + launch the GtS testrig
@@ -37,7 +48,7 @@ Leave the testrig running.
### Build Masto-FE + run it locally
Now in a *separate* terminal window, get back to the Masto-FE directory, and do a Docker build (this might take a bit of time):
Now in a _separate_ terminal window, get back to the Masto-FE directory, and do a Docker build (this might take a bit of time):
```bash
docker build -t superseriousbusiness/masto-fe-standalone:latest .
+1 -1
View File
@@ -1,5 +1,5 @@
### BUILDER IMAGE ###
FROM node:lts-alpine AS builder
FROM docker.io/superseriousbusiness/masto-fe-standalone-woodpecker-build:0.1.0 AS builder
# Prepare the build directory, copy
# relevant source + config files over.
+1 -1
View File
@@ -40,7 +40,7 @@ Serve all the stuff in `public` behind an nginx or whatever you want! See the in
### Docker (definitely the easiest way)
The Docker container is based on Nginx, and serves over port 3000. Just deploy it and listen on that port, preferably with a reverse proxy at some point (Traefik? Caddy? Another Nginx perhaps?) handling https.
The Docker container is based on Nginx, and serves over port 80. Just deploy it and listen on that port, preferably with a reverse proxy at some point (Traefik? Caddy? Another Nginx perhaps?) handling https.
## Testing locally, linting, etc
@@ -1,4 +1,4 @@
import { expandSpoilers, disableSwiping } from 'flavours/glitch/initial_state';
import { disableSwiping } from 'flavours/glitch/initial_state';
import { openModal } from './modal';
@@ -7,18 +7,9 @@ export const LOCAL_SETTING_DELETE = 'LOCAL_SETTING_DELETE';
export function checkDeprecatedLocalSettings() {
return (dispatch, getState) => {
const local_auto_unfold = getState().getIn(['local_settings', 'content_warnings', 'auto_unfold']);
const local_swipe_to_change_columns = getState().getIn(['local_settings', 'swipe_to_change_columns']);
let changed_settings = [];
if (local_auto_unfold !== null && local_auto_unfold !== undefined) {
if (local_auto_unfold === expandSpoilers) {
dispatch(deleteLocalSetting(['content_warnings', 'auto_unfold']));
} else {
changed_settings.push('user_setting_expand_spoilers');
}
}
if (local_swipe_to_change_columns !== null && local_swipe_to_change_columns !== undefined) {
if (local_swipe_to_change_columns === !disableSwiping) {
dispatch(deleteLocalSetting(['swipe_to_change_columns']));
@@ -21,11 +21,21 @@ export const fetchServer = () => (dispatch, getState) => {
dispatch(fetchServerRequest());
api(getState)
.get('/api/v2/instance').then(({ data }) => {
if (data.contact.account) dispatch(importFetchedAccount(data.contact.account));
dispatch(fetchServerSuccess(data));
}).catch(err => dispatch(fetchServerFail(err)));
/* global data */
try {
api(getState)
.get('/api/v2/instance').then({ data }).catch(error => {
console.error(error);
});
if (data.contact.account) dispatch(importFetchedAccount(data.contact.account));
dispatch(fetchServerSuccess(data));
} catch (e) {
api(getState)
.get('/api/v1/instance').then(({ data }) => {
if (data.contact_account) dispatch(importFetchedAccount(data.contact_account));
dispatch(fetchServerSuccess(data));
}).catch(err => dispatch(fetchServerFail(err)));
}
};
const fetchServerRequest = () => ({
@@ -8,9 +8,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
// Our imports
import { expandSpoilers } from 'flavours/glitch/initial_state';
import DeprecatedLocalSettingsPageItem from './deprecated_item';
import LocalSettingsPageItem from './item';
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -308,35 +305,21 @@ class LocalSettingsPage extends PureComponent {
</LocalSettingsPageItem>
<section>
<h2><FormattedMessage id='settings.content_warnings_unfold_opts' defaultMessage='Auto-unfolding options' /></h2>
<DeprecatedLocalSettingsPageItem
<LocalSettingsPageItem
settings={settings}
item={['content_warnings', 'auto_unfold']}
onChange={onChange}
id='mastodon-settings--content_warnings-auto_unfold'
value={expandSpoilers}
>
<FormattedMessage id='settings.enable_content_warnings_auto_unfold' defaultMessage='Automatically unfold content-warnings' />
<span className='hint'>
<FormattedMessage
id='settings.deprecated_setting'
defaultMessage="This setting is now controlled from Mastodon's {settings_page_link}"
values={{
settings_page_link: (
<span>
<FormattedMessage
id='settings.shared_settings_link'
defaultMessage='user preferences'
/>
</span>
),
}}
/>
</span>
</DeprecatedLocalSettingsPageItem>
</LocalSettingsPageItem>
<LocalSettingsPageItem
settings={settings}
item={['content_warnings', 'filter']}
id='mastodon-settings--content_warnings-auto_unfold'
onChange={onChange}
dependsOn={[['content_warnings', 'auto_unfold']]}
placeholder={intl.formatMessage(messages.regexp)}
disabled={!expandSpoilers}
>
<FormattedMessage id='settings.content_warnings_filter' defaultMessage='Content warnings to not automatically unfold:' />
</LocalSettingsPageItem>
@@ -55,6 +55,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
singleColumn: PropTypes.bool,
children: PropTypes.node,
openSettings: PropTypes.func,
onLogout: PropTypes.func,
};
// Corresponds to (max-width: $no-gap-breakpoint + 285px - 1px) in SCSS
@@ -139,7 +140,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
};
render () {
const { columns, children, singleColumn, openSettings } = this.props;
const { columns, children, singleColumn, openSettings, onLogout } = this.props;
const { renderComposePanel } = this.state;
if (singleColumn) {
@@ -158,7 +159,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
<div className='columns-area__panels__pane columns-area__panels__pane--start columns-area__panels__pane--navigational'>
<div className='columns-area__panels__pane__inner'>
<NavigationPanel onOpenSettings={openSettings} />
<NavigationPanel onOpenSettings={openSettings} onLogout={onLogout} />
</div>
</div>
</div>
@@ -11,7 +11,6 @@ import illustration from 'flavours/glitch/images/logo_warn_glitch.svg';
const messages = defineMessages({
discardChanges: { id: 'confirmations.deprecated_settings.confirm', defaultMessage: 'Use Mastodon preferences' },
user_setting_expand_spoilers: { id: 'settings.enable_content_warnings_auto_unfold', defaultMessage: 'Automatically unfold content-warnings' },
user_setting_disable_swiping: { id: 'settings.swipe_to_change_columns', defaultMessage: 'Allow swiping to change columns (Mobile only)' },
});
@@ -24,7 +24,7 @@ import CharacterCounter from 'flavours/glitch/features/compose/components/charac
import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress';
import { Tesseract as fetchTesseract } from 'flavours/glitch/features/ui/util/async-components';
import Video, { getPointerPosition } from 'flavours/glitch/features/video';
import { me } from 'flavours/glitch/initial_state';
import { me , maxMediaDescChars } from 'flavours/glitch/initial_state';
import { assetHost } from 'flavours/glitch/utils/config';
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from '../../../actions/compose';
@@ -367,10 +367,10 @@ class FocalPointModal extends ImmutablePureComponent {
<div className='setting-text__toolbar'>
<button disabled={detecting || media.get('type') !== 'image' || is_changing_upload} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button>
<CharacterCounter max={1500} text={detecting ? '' : description} />
<CharacterCounter max={maxMediaDescChars} text={detecting ? '' : description} />
</div>
<Button disabled={!dirty || detecting || isUploadingThumbnail || length(description) > 1500 || is_changing_upload} text={intl.formatMessage(is_changing_upload ? messages.applying : messages.apply)} onClick={this.handleSubmit} />
<Button disabled={!dirty || detecting || isUploadingThumbnail || length(description) > maxMediaDescChars || is_changing_upload} text={intl.formatMessage(is_changing_upload ? messages.applying : messages.apply)} onClick={this.handleSubmit} />
</div>
<div className='focal-point-modal__content'>
@@ -30,6 +30,7 @@ const messages = defineMessages({
advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' },
openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' },
app_settings: { id: 'navigation_bar.app_settings', defaultMessage: 'App settings' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Log out' },
});
class NavigationPanel extends Component {
@@ -42,6 +43,7 @@ class NavigationPanel extends Component {
static propTypes = {
intl: PropTypes.object.isRequired,
onOpenSettings: PropTypes.func,
onLogout: PropTypes.func,
};
isFirehoseActive = (match, location) => {
@@ -49,7 +51,7 @@ class NavigationPanel extends Component {
};
render() {
const { intl, onOpenSettings } = this.props;
const { intl, onOpenSettings, onLogout } = this.props;
const { signedIn, disabledAccountId } = this.context.identity;
return (
@@ -104,6 +106,7 @@ class NavigationPanel extends Component {
<hr />
<ColumnLink transparent onClick={onOpenSettings} icon='cogs' text={intl.formatMessage(messages.app_settings)} />
<ColumnLink transparent onClick={onLogout} icon='sign-out' text={intl.formatMessage(messages.logout)} />
</>
)}
@@ -112,6 +115,7 @@ class NavigationPanel extends Component {
<ColumnLink transparent to='/about' icon='ellipsis-h' text={intl.formatMessage(messages.about)} />
</div>
<NavigationPortal />
</div>
);
@@ -1,14 +1,22 @@
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { openModal } from 'flavours/glitch/actions/modal';
import { logOut } from 'flavours/glitch/utils/log_out';
import ColumnsArea from '../components/columns_area';
const messages = defineMessages({
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
});
const mapStateToProps = state => ({
columns: state.getIn(['settings', 'columns']),
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch, { intl }) => ({
openSettings (e) {
e.preventDefault();
e.stopPropagation();
@@ -17,6 +25,17 @@ const mapDispatchToProps = dispatch => ({
modalProps: {},
}));
},
onLogout () {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: intl.formatMessage(messages.logoutMessage),
confirm: intl.formatMessage(messages.logoutConfirm),
closeWhenConfirm: false,
onConfirm: () => logOut(),
},
}));
},
});
export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(ColumnsArea);
export default injectIntl(connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(ColumnsArea));
@@ -149,7 +149,9 @@ class SwitchingColumnsArea extends PureComponent {
componentDidUpdate (prevProps) {
if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) {
this.node.handleChildrenContentChange();
if (this.node && this.node.handleChildrenContentChange === 'function') {
this.node.handleChildrenContentChange();
}
}
if (prevProps.singleColumn !== this.props.singleColumn) {
@@ -104,6 +104,7 @@ export const hasMultiColumnPath = initialPath === '/'
* @property {object} local_settings
* @property {number} max_toot_chars
* @property {number} max_media_attachments
* @property {number} max_media_desc_chars
* @property {number} poll_limits
*/
@@ -167,6 +168,7 @@ export const sso_redirect = getMeta('sso_redirect');
// Glitch-soc-specific settings
export const maxChars = (initialState && initialState.max_toot_chars) || 500;
export const maxMediaAttachments = (initialState && initialState.max_media_attachments) || 4;
export const maxMediaDescChars = (initialState && initialState.max_media_desc_chars) || 1500;
export const favouriteModal = getMeta('favourite_modal');
export const pollLimits = (initialState && initialState.poll_limits);
export const defaultContentType = getMeta('default_content_type');
@@ -23,6 +23,7 @@ const initialState = ImmutableMap({
tag_misleading_links: true,
rewrite_mentions: 'no',
content_warnings : ImmutableMap({
auto_unfold : false,
filter : null,
media_outside: true,
shared_state : true,
@@ -52,7 +52,6 @@
}
@mixin search-input() {
outline: 0;
box-sizing: border-box;
width: 100%;
border: 0;
@@ -164,10 +164,6 @@ body {
button {
font-family: inherit;
cursor: pointer;
&:focus {
outline: none;
}
}
.app-holder {
@@ -178,7 +174,6 @@ button {
width: 100%;
align-items: center;
justify-content: center;
outline: 0 !important;
}
& > noscript {
@@ -250,7 +245,6 @@ button {
margin: 0;
line-height: inherit;
cursor: pointer;
outline: 0;
transition: color 300ms linear;
text-decoration: underline;
@@ -753,7 +753,6 @@
font-size: 14px;
resize: none;
border: 0;
outline: 0;
border-radius: 4px;
&::placeholder {
@@ -260,10 +260,6 @@ $ui-header-height: 55px;
background: lighten($ui-base-color, 11%);
}
&:focus {
outline: 0;
}
&--transparent {
background: transparent;
color: $ui-secondary-color;
@@ -350,7 +346,6 @@ $ui-header-height: 55px;
cursor: pointer;
position: relative;
z-index: 2;
outline: 0;
overflow: hidden;
& > button {
@@ -377,11 +372,6 @@ $ui-header-height: 55px;
text-shadow: 0 0 10px rgba($ui-highlight-color, 0.4);
}
}
&:focus,
&:active {
outline: 0;
}
}
.column {
@@ -743,10 +733,6 @@ $ui-header-height: 55px;
input {
width: 100%;
margin-bottom: 6px;
&:focus {
outline: 0;
}
}
}
@@ -786,16 +772,6 @@ $ui-header-height: 55px;
color: lighten($darker-text-color, 4%);
}
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&:focus {
background: lighten($ui-base-color, 4%);
}
@@ -50,7 +50,6 @@
border-radius: 4px;
padding: 10px;
width: 100%;
outline: 0;
color: $inverted-text-color;
background: $simple-background-color;
font-size: 14px;
@@ -61,9 +60,6 @@
color: $dark-text-color;
}
&:focus {
outline: 0;
}
@include single-column('screen and (max-width: 630px)') {
font-size: 16px;
}
@@ -220,7 +216,6 @@
padding: 10px 32px 0 10px;
width: 100%;
min-height: 100px;
outline: 0;
color: $inverted-text-color;
background: $simple-background-color;
font-size: 14px;
@@ -236,10 +231,6 @@
all: unset;
}
&:focus {
outline: 0;
}
@include single-column('screen and (max-width: 630px)') {
font-size: 16px;
}
@@ -670,7 +661,6 @@
&.active {
background: $ui-highlight-color;
color: $primary-text-color;
outline: 0;
.language-dropdown__dropdown__results__item__common-name {
color: $secondary-text-color;
@@ -77,7 +77,6 @@
&:focus,
&:hover {
outline: none;
background: lighten($ui-base-color, 3%);
transition: background 200ms ease-out;
}
@@ -76,14 +76,8 @@
padding-bottom: 2px;
padding-inline-start: 2px;
padding-inline-end: 5px;
outline: 0;
cursor: pointer;
&:active,
&:focus {
outline: 0 !important;
}
img {
filter: grayscale(100%);
opacity: 0.8;
@@ -123,16 +123,6 @@
border: 1px solid $ui-secondary-color;
border-radius: 4px;
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&::-webkit-search-cancel-button {
display: none;
}
@@ -60,7 +60,6 @@
border-bottom: 1px $ui-secondary-color solid;
cursor: pointer;
text-decoration: none;
outline: none;
transition: background 0.3s;
box-sizing: border-box;
width: 100%;
@@ -454,10 +454,6 @@
height: 100% !important;
}
&:focus {
outline: 0;
}
.detailed-status & {
width: 100%;
height: 100%;
@@ -483,7 +479,6 @@
max-height: 100% !important;
width: 100% !important;
height: 100% !important;
outline: 0;
}
}
@@ -590,7 +585,6 @@
.player-button {
display: inline-block;
outline: 0;
flex: 0 0 auto;
background: transparent;
padding: 5px;
@@ -198,16 +198,6 @@
transition: none;
}
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&.inverted {
color: $lighter-text-color;
@@ -282,7 +272,6 @@
cursor: pointer;
padding: 0 3px;
white-space: nowrap;
outline: 0;
transition: all 100ms ease-in;
transition-property: background-color, color;
@@ -308,16 +297,6 @@
&.active {
color: $highlight-text-color;
}
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
}
body > [data-popper-placement] {
@@ -623,7 +602,6 @@ body > [data-popper-placement] {
&:hover,
&:active {
background: var(--dropdown-border-color);
outline: 0;
}
}
}
@@ -1038,7 +1016,6 @@ body > [data-popper-placement] {
background: transparent;
border: 0;
border-bottom: 2px solid $ui-primary-color;
outline: 0;
box-sizing: border-box;
display: block;
font-family: inherit;
@@ -1195,12 +1172,8 @@ button.icon-button.active i.fa-retweet {
align-items: center;
}
&:focus {
outline: 0 !important;
.ckbox {
box-shadow: 0 0 1px 1px $ui-highlight-color;
}
&:focus.ckbox {
box-shadow: 0 0 1px 1px $ui-highlight-color;
}
}
@@ -1523,7 +1496,6 @@ button.icon-button.active i.fa-retweet {
&:focus {
background: lighten($ui-base-color, 2%);
outline: 0;
}
&__avatar {
@@ -693,17 +693,12 @@
line-height: 22px;
resize: vertical;
border: 0;
outline: 0;
border-radius: 4px;
margin: 20px 0;
&::placeholder {
color: $dark-text-color;
}
&:focus {
outline: 0;
}
}
&__toggle {
@@ -821,7 +816,6 @@
font-family: inherit;
font-size: 14px;
resize: none;
outline: 0;
border-radius: 4px;
border: 1px solid $ui-secondary-color;
min-height: 100px;
@@ -1019,7 +1013,6 @@
color: $inverted-text-color;
display: inline-block;
width: auto;
outline: 0;
font-family: inherit;
background: $simple-background-color
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(darken($simple-background-color, 14%))}'/></svg>")
@@ -1128,7 +1121,6 @@
}
.embed-modal__html {
outline: 0;
box-sizing: border-box;
display: block;
width: 100%;
@@ -1142,16 +1134,6 @@
margin-bottom: 15px;
border-radius: 4px;
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&:focus {
background: lighten($ui-base-color, 4%);
}
@@ -1377,10 +1359,6 @@ img.modal-warning {
&::placeholder {
color: lighten($darker-text-color, 4%);
}
&:focus {
outline: 0;
}
}
.button {
@@ -1477,7 +1455,6 @@ img.modal-warning {
overflow: hidden;
&:focus {
outline: 0;
background: darken($ui-base-color, 4%);
}
}
@@ -107,37 +107,17 @@
color: lighten($darker-text-color, 4%);
}
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&:focus {
background: lighten($ui-base-color, 4%);
}
}
.search__icon {
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus {
outline: 0 !important;
}
.fa {
position: absolute;
top: 16px;
inset-inline-end: 10px;
display: inline-block;
opacity: 0;
transition: all 100ms linear;
transition-property: color, transform, opacity;
font-size: 18px;
@@ -57,10 +57,6 @@
padding-top: 5px;
clear: both;
&:focus {
outline: 0;
}
.emojione {
width: 20px;
height: 20px;
@@ -213,7 +209,6 @@
.focusable {
&:focus {
outline: 0;
background: lighten($ui-base-color, 4%);
&.status.status-direct {
@@ -27,7 +27,6 @@
align-items: center;
color: $primary-text-color;
text-decoration: none;
outline: 0;
padding: 12px 16px;
line-height: 32px;
font-weight: 500;
@@ -432,7 +432,6 @@ code {
color: $primary-text-color;
display: block;
width: 100%;
outline: 0;
font-family: inherit;
resize: vertical;
background: darken($ui-base-color, 10%);
@@ -535,7 +534,6 @@ code {
box-sizing: border-box;
cursor: pointer;
font-weight: 500;
outline: 0;
margin-bottom: 10px;
margin-inline-end: 10px;
@@ -581,7 +579,6 @@ code {
color: $primary-text-color;
display: block;
width: 100%;
outline: 0;
font-family: inherit;
resize: vertical;
background: darken($ui-base-color, 10%)
@@ -702,7 +699,6 @@ code {
}
.oauth-code {
outline: 0;
box-sizing: border-box;
display: block;
width: 100%;
@@ -714,16 +710,6 @@ code {
font-size: 14px;
margin: 0;
&::-moz-focus-inner {
border: 0;
}
&::-moz-focus-inner,
&:focus,
&:active {
outline: 0 !important;
}
&:focus {
background: lighten($ui-base-color, 4%);
}
@@ -5,88 +5,76 @@
@import 'basics';
body {
height: 100vh;
a {
color: #89caff;
}
font-family: ui-rounded, mastodon-font-sans-serif, sans-serif;
font-size: 1rem;
line-height: 1.5;
}
.login-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
max-width: 30rem;
--login-row-gap: 10px;
display: grid;
row-gap: var(--login-row-gap);
margin: 50px auto;
padding: 1rem;
margin: auto;
max-width: 30rem;
box-sizing: border-box;
}
header {
display: flex;
justify-content: center;
margin-bottom: 1rem;
}
.mascot {
height: 10rem;
img {
height: 150px;
}
}
main {
display: flex;
position: relative;
flex-direction: column;
row-gap: 10px;
row-gap: var(--login-row-gap);
}
.login {
display: flex;
position: relative;
column-gap: 10px;
h1 {
font-size: 28px;
line-height: 33px;
font-weight: 700;
margin-bottom: 15px;
}
.instance {
background: #282c37;
border: 0;
border-radius: 4px;
box-shadow: none;
box-sizing: border-box;
color: #9baec8;
display: block;
label {
font-family: inherit;
font-size: 16px;
line-height: 18px;
margin: 0;
outline: 0;
padding: 15px;
padding-inline-end: 30px;
width: 100%;
color: $primary-text-color;
display: block;
word-wrap: break-word;
font-weight: 500;
grid-column: 1 / -1;
}
.button {
display: flex;
column-gap: .5rem;
align-items: center;
justify-content: center;
background-color: #66befe;
border: 0 none;
form {
display: grid;
gap: 10px;
grid-template-columns: 1fr min-content;
}
:focus-visible,
button:focus-visible {
outline: 2px solid #66befe;
outline-offset: 3px;
}
button {
padding: 7px 10px;
border: 1px solid lighten(#66befe, 7%);
border-radius: 4px;
box-sizing: border-box;
color: #2a2b2f;
cursor: pointer;
font-size: 16px;
letter-spacing: 0;
line-height: 22px;
font-family: inherit;
font-size: inherit;
font-weight: 500;
padding: 7px 10px;
position: relative;
text-align: center;
text-decoration: none;
white-space: nowrap;
flex-basis: auto;
background-color: #66befe;
&:hover {
background-color: #89caff;
@@ -98,21 +86,35 @@ main {
}
}
.content {
background-color: #444b5d;
input[type='text'] {
display: block;
margin: 0;
padding: 15px;
font-size: 1rem;
line-height: 1.5rem;
border: 1px solid lighten(#282c37, 7%);
border-radius: 4px;
display: flex;
flex-direction: column;
row-gap: .75rem;
box-sizing: border-box;
box-shadow: none;
color: #9baec8;
font-family: inherit;
font-size: inherit;
line-height: 18px;
background: #282c37;
}
.content {
padding: 20px 15px;
border-radius: 4px;
border: 1px solid lighten(#39404f, 7%);
color: #fff;
background-color: #39404f;
}
.link-footer {
padding: 10px;
padding-inline: 10px;
color: #97a8b4;
font-size: 0.875rem;
p, a {
color: #97A8B4;
a {
color: inherit;
}
}
}
@@ -85,7 +85,6 @@
width: 100%;
font-size: 14px;
color: $inverted-text-color;
outline: 0;
font-family: inherit;
background: $simple-background-color;
border: 1px solid darken($simple-background-color, 14%);
@@ -139,16 +138,6 @@
border-color: $valid-value-color;
}
&::-moz-focus-inner {
outline: 0 !important;
border: 0;
}
&:focus,
&:active {
outline: 0 !important;
}
&.disabled {
border-color: $dark-text-color;
@@ -285,7 +274,6 @@
color: $inverted-text-color;
display: inline-block;
width: auto;
outline: 0;
font-family: inherit;
background: $simple-background-color
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(darken($simple-background-color, 14%))}'/></svg>")
@@ -96,7 +96,8 @@ $dismiss-overlay-width: 4rem;
:root {
--dropdown-border-color: #{lighten($ui-base-color, 12%)};
--dropdown-background-color: #{lighten($ui-base-color, 4%)};
--dropdown-shadow: 0 20px 25px -5px #{rgba($base-shadow-color, 0.25)},
--dropdown-shadow:
0 20px 25px -5px #{rgba($base-shadow-color, 0.25)},
0 8px 10px -6px #{rgba($base-shadow-color, 0.25)};
--modal-background-color: #{darken($ui-base-color, 4%)};
--modal-border-color: #{lighten($ui-base-color, 4%)};
@@ -1,9 +1,9 @@
import { expandSpoilers } from 'flavours/glitch/initial_state';
function _autoUnfoldCW(spoiler_text, skip_unfold_regex) {
if (!expandSpoilers)
function _autoUnfoldCW(spoiler_text, settings) {
if (!settings.getIn(['content_warnings', 'auto_unfold']))
return false;
const skip_unfold_regex = settings.getIn(['content_warnings', 'filter']);
if (!skip_unfold_regex)
return true;
@@ -20,12 +20,12 @@ function _autoUnfoldCW(spoiler_text, skip_unfold_regex) {
}
export function autoHideCW(settings, spoiler_text) {
return !_autoUnfoldCW(spoiler_text, settings.getIn(['content_warnings', 'filter']));
return !_autoUnfoldCW(spoiler_text, settings);
}
export function autoUnfoldCW(settings, status) {
if (!status)
return false;
return _autoUnfoldCW(status.get('spoiler_text'), settings.getIn(['content_warnings', 'filter']));
return _autoUnfoldCW(status.get('spoiler_text'), settings);
}
+15 -5
View File
@@ -17,11 +17,21 @@ export const fetchServer = () => (dispatch, getState) => {
dispatch(fetchServerRequest());
api(getState)
.get('/api/v2/instance').then(({ data }) => {
if (data.contact.account) dispatch(importFetchedAccount(data.contact.account));
dispatch(fetchServerSuccess(data));
}).catch(err => dispatch(fetchServerFail(err)));
/* global data */
try {
api(getState)
.get('/api/v2/instance').then({ data }).catch(error => {
console.error(error);
});
if (data.contact.account) dispatch(importFetchedAccount(data.contact.account));
dispatch(fetchServerSuccess(data));
} catch (e) {
api(getState)
.get('/api/v1/instance').then(({ data }) => {
if (data.contact_account) dispatch(importFetchedAccount(data.contact_account));
dispatch(fetchServerSuccess(data));
}).catch(err => dispatch(fetchServerFail(err)));
}
};
const fetchServerRequest = () => ({
@@ -23,7 +23,7 @@ import Audio from 'mastodon/features/audio';
import CharacterCounter from 'mastodon/features/compose/components/character_counter';
import UploadProgress from 'mastodon/features/compose/components/upload_progress';
import { Tesseract as fetchTesseract } from 'mastodon/features/ui/util/async-components';
import { me } from 'mastodon/initial_state';
import { me , maxMediaDescChars } from 'mastodon/initial_state';
import { assetHost } from 'mastodon/utils/config';
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from '../../../actions/compose';
@@ -374,12 +374,12 @@ class FocalPointModal extends ImmutablePureComponent {
>
<FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' />
</button>
<CharacterCounter max={1500} text={detecting ? '' : description} />
<CharacterCounter max={maxMediaDescChars} text={detecting ? '' : description} />
</div>
<Button
type='submit'
disabled={!dirty || detecting || isUploadingThumbnail || length(description) > 1500 || is_changing_upload}
disabled={!dirty || detecting || isUploadingThumbnail || length(description) > maxMediaDescChars || is_changing_upload}
text={intl.formatMessage(is_changing_upload ? messages.applying : messages.apply)}
/>
</form>
+2
View File
@@ -90,6 +90,7 @@
* @property {boolean=} critical_updates_pending
* @property {InitialStateMeta} meta
* @property {number} max_toot_chars
* @property {number} max_media_desc_chars
*/
const element = document.getElementById('initial-state');
@@ -149,5 +150,6 @@ export const sso_redirect = getMeta('sso_redirect');
// Glitch-soc-specific settings
export const maxChars = (initialState && initialState.max_toot_chars) || 500;
export const maxMediaDescChars = (initialState && initialState.max_media_desc_chars) || 1500;
export default initialState;
@@ -96,7 +96,8 @@ $font-monospace: 'mastodon-font-monospace' !default;
:root {
--dropdown-border-color: #{lighten($ui-base-color, 12%)};
--dropdown-background-color: #{lighten($ui-base-color, 4%)};
--dropdown-shadow: 0 20px 25px -5px #{rgba($base-shadow-color, 0.25)},
--dropdown-shadow:
0 20px 25px -5px #{rgba($base-shadow-color, 0.25)},
0 8px 10px -6px #{rgba($base-shadow-color, 0.25)};
--modal-background-color: #{darken($ui-base-color, 4%)};
--modal-border-color: #{lighten($ui-base-color, 4%)};
+3 -2
View File
@@ -208,7 +208,7 @@
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"lint-staged": "^13.2.2",
"prettier": "^3.0.0",
"prettier": "3.6.2",
"react-test-renderer": "^18.2.0",
"stylelint": "^15.10.1",
"stylelint-config-standard-scss": "^11.0.0",
@@ -230,5 +230,6 @@
"Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop --force-exclusion -a",
"*.{js,jsx,ts,tsx}": "eslint --fix",
"*.{css,scss}": "stylelint --fix"
}
},
"packageManager": "yarn@4.10.3"
}
+7 -1
View File
@@ -1,5 +1,11 @@
document.addEventListener("DOMContentLoaded", async function() {
await ready();
const form = document.querySelector('#login')
form?.addEventListener("submit", (event) => {
event.preventDefault();
auth();
});
});
async function ready() {
@@ -20,7 +26,7 @@ async function ready() {
async function auth() {
setMessage('Please wait');
const instance = document.getElementById('instance').value;
const instance = document.getElementById('instance').value.trim();
const matches = instance.match(/((?:http|https):\/\/)?(.*)/);
const protocol = matches[1];
+13 -17
View File
@@ -5,35 +5,31 @@
<meta charset="UTF-8">
<title>Login | Masto-FE (🦥 flavour)</title>
<meta content="width=device-width, initial-scale=1" name="viewport">
<link rel="stylesheet" media="all" href="/packs/css/core/common.css" />
<link rel="stylesheet" media="all" href="/packs/css/flavours/glitch/login.css" />
<script src="/auth.js"></script>
</head>
<body>
<body class="app-body">
<div class="login-container">
<header>
<img class="mascot" alt src="images/mascot.svg" />
<img alt="a friendly smiling sloth" src="images/mascot.svg" />
</header>
<main>
<div class="login">
<input class="instance" id="instance" placeholder="Instance URL" aria-label="Instance URL" value="" onkeypress="if (event.keyCode == 13) auth()">
<button type="submit" class="button" id="btn" onclick="auth()">
<h1>Log into your instance</h1>
<form method="post" id="login">
<label for="instance">Instance URL</label>
<input type="text" id="instance" value="" class="input instance">
<button type="submit" class="button" id="btn">
<span id="message">Authorize</span>
</button>
</div>
<div class="content">
</form>
<aside class="content">
<p>
This is a standalone version of the Mastodon front-end that offers compatibility with GoToSocial instances. It is based
on <a href="https://iceshrimp.dev/iceshrimp/masto-fe-standalone" rel="nofollow">Iceshrimp's Masto-FE Standalone</a>,
which is itself a fork of <a href="https://github.com/glitch-soc/mastodon" rel="nofollow">Mastodon Glitch Edition</a>,
which in turn forks <a href="https://github.com/mastodon/mastodon/" rel="nofollow">Mastodon</a>. Phew!
<strong>Note:</strong>
this application is completely client-side, meaning everything happens in the browser on your machine.
It does not store information anywhere else than your browser's local storage.
</p>
<p>
The application is completely client-side, meaning everything happens in the browser on your machine. It does not store
information anywhere else than your browser's local storage.
</p>
</div>
</aside>
</main>
<footer class="link-footer">
<p>
+4
View File
@@ -4,7 +4,11 @@
<meta charset="UTF-8">
<title>Logout | Masto-FE (🦥 flavour)</title>
<script>
const preserveSettings = localStorage.getItem("mastodon-settings");
localStorage.clear();
if (preserveSettings !== null) {
localStorage.setItem("mastodon-settings", preserveSettings);
}
window.location.href = "/login.html";
</script>
</head>
+10 -1
View File
@@ -23,7 +23,15 @@ async function loadState() {
}
const apiUrl = `${protocol}${domain}/api`;
const instance = await fetch(`${apiUrl}/v1/instance`).then(async p => await p.json());
let instance
try {
instance = await fetch(`${apiUrl}/v2/instance`).then(async p => await p.json());
if (!instance.configuration) {
throw new Error('Instance API v2 unavaialble');
}
} catch (e) {
instance = await fetch(`${apiUrl}/v1/instance`).then(async p => await p.json());
}
const options = {headers: {Authorization: `Bearer ${access_token}`}};
const credentials = await fetch(`${apiUrl}/v1/accounts/verify_credentials`, options).then(async p => await p.json());
const state = {
@@ -93,6 +101,7 @@ async function loadState() {
},
"max_toot_chars": instance.configuration.statuses.max_characters,
"max_media_attachments": instance.configuration.statuses.max_media_attachments,
"max_media_desc_chars": instance.configuration.media_attachments.description_limit,
"poll_limits": {
"max_expiration": instance.configuration.polls.max_expiration,
"max_option_chars": instance.configuration.polls.max_characters_per_option,
+18309 -13163
View File
File diff suppressed because it is too large Load Diff