Skip to content

Commit

Permalink
Merge branch 'merge-upstream' into glitch-soc-main
Browse files Browse the repository at this point in the history
  • Loading branch information
sneakers-the-rat authored Sep 20, 2023
2 parents 5efa6ac + bfa4e88 commit 3d4022c
Show file tree
Hide file tree
Showing 51 changed files with 10,943 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .env.production.sample
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ MAX_POLL_OPTION_CHARS=100
# HCAPTCHA_SECRET_KEY=
# HCAPTCHA_SITE_KEY=

# New registrations will automatically follow these accounts (separated by commas)
AUTOFOLLOW=

# IP and session retention
# -----------------------
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ jobs:
run: sudo apt-get update

- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
run: sudo apt-get update && sudo apt-get install -y libicu-dev libidn11-dev

- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick libpam-dev
run: sudo apt-get update && sudo apt-get install -y ffmpeg imagemagick libpam-dev

- name: Set up bundler cache
uses: ruby/setup-ruby@v1
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ yarn-debug.log

# Ignore Docker option files
docker-compose.override.yml

public/MathJax
55 changes: 55 additions & 0 deletions app/javascript/flavours/glitch/actions/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useEmoji } from './emojis';
import { importFetchedAccounts, importFetchedStatus } from './importer';
import { openModal } from './modal';
import { updateTimeline } from './timelines';
import { tex_to_unicode } from '../features/compose/util/autolatex/autolatex.js';

/** @type {AbortController | undefined} */
let fetchComposeSuggestionsAccountsController;
Expand Down Expand Up @@ -64,6 +65,7 @@ export const COMPOSE_CONTENT_TYPE_CHANGE = 'COMPOSE_CONTENT_TYPE_CHANGE';
export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE';

export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
export const COMPOSE_START_LATEX = 'COMPOSE_START_LATEX';

export const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST';
export const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
Expand Down Expand Up @@ -565,6 +567,36 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) =>
});
}, 200, { leading: true, trailing: true });

const fetchComposeSuggestionsLatex = (dispatch, getState, token) => {
const start_delimiter = token.slice(0,2);
const end_delimiter = {'\\(': '\\)', '\\[': '\\]'}[start_delimiter];
let expression = token.slice(2).replace(/\\[\)\]]?$/,'');
let brace = 0;
for(let i=0;i<expression.length;i++) {
switch(expression[i]) {
case '\\':
i += 1;
break;
case '{':
brace += 1;
break;
case '}':
brace -= 1;
break;
}
}
for(;brace<0;brace++) {
expression = '{'+expression;
}
for(;brace>0;brace--) {
expression += '}';
}
const results = [
{ start_delimiter, end_delimiter, expression }
];
dispatch(readyComposeSuggestionsLatex(token, results));
};

const fetchComposeSuggestionsEmojis = (dispatch, getState, token) => {
const results = emojiSearch(token.replace(':', ''), { maxResults: 5 });
dispatch(readyComposeSuggestionsEmojis(token, results));
Expand Down Expand Up @@ -608,13 +640,24 @@ export function fetchComposeSuggestions(token) {
case '#':
fetchComposeSuggestionsTags(dispatch, getState, token);
break;
case '\\':
fetchComposeSuggestionsLatex(dispatch, getState, token);
break;
default:
fetchComposeSuggestionsAccounts(dispatch, getState, token);
break;
}
};
}

export function readyComposeSuggestionsLatex(token, latex) {
return {
type: COMPOSE_SUGGESTIONS_READY,
token,
latex,
};
};

export function readyComposeSuggestionsEmojis(token, emojis) {
return {
type: COMPOSE_SUGGESTIONS_READY,
Expand Down Expand Up @@ -647,6 +690,10 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
completion = `#${suggestion.name}`;
} else if (suggestion.type === 'account') {
completion = '@' + getState().getIn(['accounts', suggestion.id, 'acct']);
} else if (suggestion.type === 'latex') {
const unicode = tex_to_unicode(suggestion.expression);
completion = unicode || `${suggestion.start_delimiter}${suggestion.expression}${suggestion.end_delimiter}`;
position -= 1;
}

// We don't want to replace hashtags that vary only in case due to accessibility, but we need to fire off an event so that
Expand Down Expand Up @@ -779,6 +826,14 @@ export function insertEmojiCompose(position, emoji) {
};
}

export function startLaTeXCompose(position, latex_style) {
return {
type: COMPOSE_START_LATEX,
position,
latex_style,
};
};

export function addPoll() {
return {
type: COMPOSE_POLL_ADD,
Expand Down
23 changes: 21 additions & 2 deletions app/javascript/flavours/glitch/components/autosuggest_input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,28 @@ import AutosuggestAccountContainer from 'flavours/glitch/features/compose/contai

import AutosuggestEmoji from './autosuggest_emoji';
import { AutosuggestHashtag } from './autosuggest_hashtag';
import AutosuggestLatex from './autosuggest_latex';

const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => {
let word;
let left;
let right;

left = str.slice(0, caretPosition).search(/\\\((?:(?!\\\)).)*$/);
if (left >= 0) {
right = str.slice(caretPosition).search(/\\\)/);
if (right < 0) {
word = str.slice(left);
} else {
word = str.slice(left, right + caretPosition);
}
if (word.trim().length >= 3) {
return [left + 1, word];
}
}

let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/);
let right = str.slice(caretPosition).search(/[\s\u200B]/);
left = str.slice(0, caretPosition).search(/\S+$/);
right = str.slice(caretPosition).search(/\s/);

if (right < 0) {
word = str.slice(left);
Expand Down Expand Up @@ -180,6 +196,9 @@ export default class AutosuggestInput extends ImmutablePureComponent {
} else if (suggestion.type === 'account') {
inner = <AutosuggestAccountContainer id={suggestion.id} />;
key = suggestion.id;
} else if (suggestion.type === 'latex') {
inner = <AutosuggestLatex latex={suggestion} />;
key = 'latex' + suggestion.expression;
}

return (
Expand Down
37 changes: 37 additions & 0 deletions app/javascript/flavours/glitch/components/autosuggest_latex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';

const assetHost = process.env.CDN_HOST || '';

export default class AutosuggestLatex extends React.PureComponent {

static propTypes = {
latex: PropTypes.object.isRequired,
};

setRef = (c) => {
this.node = c;
}

componentDidMount() {
try {
MathJax.typeset([this.node]);
} catch(e) {
console.error(e);
}

}

render () {
const { latex } = this.props;

return (
<div className='autosuggest-latex' ref={this.setRef}>
\({latex.expression}\)
<br/>
<small>Convert to unicode</small>
</div>
);
}

}
24 changes: 22 additions & 2 deletions app/javascript/flavours/glitch/components/autosuggest_textarea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,28 @@ import AutosuggestAccountContainer from 'flavours/glitch/features/compose/contai

import AutosuggestEmoji from './autosuggest_emoji';
import { AutosuggestHashtag } from './autosuggest_hashtag';
import AutosuggestLatex from './autosuggest_latex';

const textAtCursorMatchesToken = (str, caretPosition) => {
let word;
let left;
let right;

left = str.slice(0, caretPosition).search(/\\[\(\[](?:(?!\\[\)\]]).)*(?:\\[\)\]])?$/);
if (left >= 0) {
right = str.slice(caretPosition).search(/\\[\)\]]/);
if (right < 0) {
word = str.slice(left);
} else {
word = str.slice(left, right + caretPosition + 2);
}
if (word.trim().length >= 3) {
return [left + 1, word];
}
}

let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/);
let right = str.slice(caretPosition).search(/[\s\u200B]/);
left = str.slice(0, caretPosition).search(/\S+$/);
right = str.slice(caretPosition).search(/\s/);

if (right < 0) {
word = str.slice(left);
Expand Down Expand Up @@ -187,6 +203,9 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
} else if (suggestion.type === 'account') {
inner = <AutosuggestAccountContainer id={suggestion.id} />;
key = suggestion.id;
} else if (suggestion.type === 'latex') {
inner = <AutosuggestLatex latex={suggestion} />;
key = suggestion.expression;
}

return (
Expand Down Expand Up @@ -215,6 +234,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
value={value}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
onInput={this.onInput}
onKeyUp={onKeyUp}
onFocus={this.onFocus}
onBlur={this.onBlur}
Expand Down
13 changes: 10 additions & 3 deletions app/javascript/flavours/glitch/components/status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { HotKeys } from 'react-hotkeys';

import PictureInPicturePlaceholder from 'flavours/glitch/components/picture_in_picture_placeholder';
import PollContainer from 'flavours/glitch/containers/poll_container';
import NotificationOverlayContainer from 'flavours/glitch/features/notifications/containers/overlay_container';
import { displayMedia } from 'flavours/glitch/initial_state';
import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
import { HotKeys } from 'react-hotkeys';

import Card from '../features/status/components/card';
import Bundle from '../features/ui/components/bundle';
Expand All @@ -22,9 +21,9 @@ import { MediaGallery, Video, Audio } from '../features/ui/util/async-components
import AttachmentList from './attachment_list';
import StatusActionBar from './status_action_bar';
import StatusContent from './status_content';
import StatusExpandButton from './status_expand_button';
import StatusHeader from './status_header';
import StatusIcons from './status_icons';
import StatusPrepend from './status_prepend';

const domParser = new DOMParser();

Expand Down Expand Up @@ -832,6 +831,14 @@ class Status extends ImmutablePureComponent {
tagLinks={settings.get('tag_misleading_links')}
rewriteMentions={settings.get('rewrite_mentions')}
/>
{/* Only show expand button if collapsed and no spoiler tag is present */}
{isCollapsed && status.get('spoiler_text').length===0 ? (
<StatusExpandButton
hidden={isCollapsed}
handleSpoilerClick={parseClick}
mediaIcons={contentMediaIcons}
/>
) : null}

{!isCollapsed || !(muted || !settings.getIn(['collapsed', 'show_action_bar'])) ? (
<StatusActionBar
Expand Down
57 changes: 22 additions & 35 deletions app/javascript/flavours/glitch/components/status_content.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { connect } from 'react-redux';
import { Icon } from 'flavours/glitch/components/icon';
import { autoPlayGif, languages as preloadedLanguages } from 'flavours/glitch/initial_state';
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
import StatusExpandButton from './status_expand_button';

import Permalink from './permalink';

Expand Down Expand Up @@ -235,12 +236,28 @@ class StatusContent extends PureComponent {
}
};

_renderMathJax() {
const {status} = this.props;
const contentHtml = status.get('contentHtml');
if(this.last_contentHtml == contentHtml) {
return;
}
this.last_contentHtml = contentHtml;
try {
MathJax.typeset([this.contentsNode]);
} catch(e) {
console.error(e);
}
}

componentDidMount () {
this._updateStatusLinks();
this._renderMathJax();
}

componentDidUpdate () {
this._updateStatusLinks();
this._renderMathJax();
if (this.props.onUpdate) this.props.onUpdate();
}

Expand Down Expand Up @@ -355,38 +372,6 @@ class StatusContent extends PureComponent {
</Permalink>
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);

let toggleText = null;
if (hidden) {
toggleText = [
<FormattedMessage
id='status.show_more'
defaultMessage='Show more'
key='0'
/>,
];
if (mediaIcons) {
mediaIcons.forEach((mediaIcon, idx) => {
toggleText.push(
<Icon
fixedWidth
className='status__content__spoiler-icon'
id={mediaIcon}
aria-hidden='true'
key={`icon-${idx}`}
/>,
);
});
}
} else {
toggleText = (
<FormattedMessage
id='status.show_less'
defaultMessage='Show less'
key='0'
/>
);
}

if (hidden) {
mentionsPlaceholder = <div>{mentionLinks}</div>;
}
Expand All @@ -398,9 +383,11 @@ class StatusContent extends PureComponent {
>
<span dangerouslySetInnerHTML={spoilerContent} className='translate' lang={language} />
{' '}
<button type='button' className='status__content__spoiler-link' onClick={this.handleSpoilerClick} aria-expanded={!hidden}>
{toggleText}
</button>
<StatusExpandButton
hidden={hidden}
handleSpoilerClick={this.handleSpoilerClick}
mediaIcons={mediaIcons}
/>
</p>

{mentionsPlaceholder}
Expand Down
Loading

0 comments on commit 3d4022c

Please sign in to comment.