Merge branch 'mitra' into 'develop'

First pass at Mitra compatibility

See merge request soapbox-pub/soapbox-fe!1031
merge-requests/1032/head
Alex Gleason 3 years ago
commit 872d5135b8

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
inkscape:export-ydpi="240"
inkscape:export-xdpi="240"
inkscape:export-filename="/home/alex/Projects/docker-tribe/avi.png"
sodipodi:docname="avatar.svg"
width="120"
height="120"
viewBox="0 0 31.75 31.750001"
version="1.1"
id="svg8"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2" />
<sodipodi:namedview
inkscape:window-maximized="1"
inkscape:window-y="30"
inkscape:window-x="0"
inkscape:window-height="1019"
inkscape:window-width="1920"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.3194033"
inkscape:cx="79.987899"
inkscape:cy="64.129228"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-bbox="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
inkscape:snap-global="false"
inkscape:pagecheckerboard="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0.80272198,1.2346106)">
<rect
style="fill:#10b3d1;fill-opacity:1;stroke:none;stroke-width:1.53052;stroke-miterlimit:4;stroke-dasharray:none"
id="rect853"
width="31.75"
height="31.75"
x="-0.80272198"
y="-1.2346106" />
<path
id="path857"
style="fill:#f4962a;fill-opacity:1;stroke:#000000;stroke-width:1.48265;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 15.051525,3.9344041 A 10.434797,10.434797 0 0 0 4.6372555,14.368944 a 10.434797,10.434797 0 0 0 0,0.02075 v 0.03137 a 1.7839264,2.3625556 0 0 0 -0.9503056,-0.363423 1.7839264,2.3625556 0 0 0 -1.7838141,2.362493 1.7839264,2.3625556 0 0 0 1.7838141,2.362491 1.7839264,2.3625556 0 0 0 0.9503056,-0.363423 v 23.74268 H 25.507302 v -23.74268 a 1.7839264,2.3625556 0 0 0 0.950305,0.363423 1.7839264,2.3625556 0 0 0 1.783814,-2.362491 1.7839264,2.3625556 0 0 0 -1.783814,-2.362493 1.7839264,2.3625556 0 0 0 -0.950305,0.362941 v -0.05164 A 10.434797,10.434797 0 0 0 15.072278,3.9344041 a 10.434797,10.434797 0 0 0 -0.02075,0 z" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.900495;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path881-6"
cx="11.218504"
cy="13.292331"
r="1.3086123" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.900495;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path881-7"
cx="18.926052"
cy="13.292331"
r="1.3086123" />
<ellipse
style="fill:#f2f2f2;fill-opacity:1;stroke:#000000;stroke-width:0.88959;stroke-miterlimit:4;stroke-dasharray:none"
id="path917"
cx="15.072279"
cy="18.343904"
rx="7.1666903"
ry="4.0659413" />
<path
id="path957"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.88959;stroke-miterlimit:4;stroke-dasharray:none"
d="m 21.900069,17.108362 a 7.1666903,4.0659412 0 0 1 -6.82779,2.8304 7.1666903,4.0659412 0 0 1 -6.8277959,-2.830413" />
<path
id="path1003"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.88959;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:transform-center-y="-0.79831289"
d="m 13.062455,16.997512 c 0.457808,-1.227486 1.336486,-2.475611 2.009822,-2.475611 0.673338,0 1.552013,1.248125 2.009824,2.475611" />
<path
style="fill:none;stroke:#000000;stroke-width:0.79375;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 24.842957,6.3249745 c -1.070225,-0.4344716 -2.309802,0.1182843 -2.464817,1.0590207 0,0 -1.627232,-1.9230616 1.219705,-3.5847621"
id="path1030"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -0,0 +1,107 @@
[
{
"id": "017ed503-bc96-301a-e871-2c23b30ddd05",
"uri": "https://mitra.social/objects/017ed503-bc96-301a-e871-2c23b30ddd05",
"created_at": "2022-02-07T16:28:18.966874Z",
"account": {
"id": "017ed4f9-c121-2ae6-0805-15516cce02c3",
"username": "alex",
"acct": "alex",
"url": "https://mitra.social/users/alex",
"display_name": null,
"created_at": "2022-02-07T16:17:24.769229Z",
"note": null,
"avatar": null,
"header": null,
"fields": [],
"followers_count": 1,
"following_count": 1,
"statuses_count": 3,
"source": null,
"wallet_address": null
},
"content": "<span class=\"h-card\"><a class=\"u-url mention\" href=\"https://mitra.social/users/silverpill\">@silverpill</a></span> sup!",
"in_reply_to_id": null,
"reblog": null,
"visibility": "public",
"replies_count": 1,
"favourites_count": 0,
"reblogs_count": 0,
"media_attachments": [],
"mentions": [
{
"id": "dd4ebc18-269d-4c7b-a310-03d29c6ab551",
"username": "silverpill",
"acct": "silverpill",
"url": "https://mitra.social/users/silverpill"
}
],
"tags": [],
"favourited": false,
"reblogged": false,
"ipfs_cid": null,
"token_id": null,
"token_tx_id": null
},
{
"id": "017ed505-5926-392f-256a-f86d5075df70",
"uri": "https://mitra.social/objects/017ed505-5926-392f-256a-f86d5075df70",
"created_at": "2022-02-07T16:30:04.582771Z",
"account": {
"id": "dd4ebc18-269d-4c7b-a310-03d29c6ab551",
"username": "silverpill",
"acct": "silverpill",
"url": "https://mitra.social/users/silverpill",
"display_name": "silverpill",
"created_at": "2021-11-06T21:08:57.441927Z",
"note": "Admin of <a href=\"https://mitra.social/\" rel=\"noopener noreferrer\">mitra.social</a> instance. It is running experimental ActivityPub server <a href=\"https://codeberg.org/silverpill/mitra\" rel=\"noopener noreferrer\">Mitra</a>.",
"avatar": "https://mitra.social/media/6a785bf7dd05f61c3590e8935aa49156a499ac30fd1e402f79e7e164adb36e2c.png",
"header": null,
"fields": [
{
"name": "Matrix",
"value": "@silverpill:poa.st"
},
{
"name": "Alt",
"value": "@silverpill@poa.st"
},
{
"name": "Code",
"value": "<a href=\"https://codeberg.org/silverpill/\" rel=\"noopener noreferrer\">https://codeberg.org/silverpill/</a>"
},
{
"name": "$XMR",
"value": "884y9LmsWY7PQNsyR7bJy1dvj91tuF5spVabyCnPk4KfQtSuzFbQobTFC7xSemJgVW1FWAwnJbjTZX5zZWbBrfkv62DB62d"
}
],
"followers_count": 27,
"following_count": 15,
"statuses_count": 110,
"source": null,
"wallet_address": null
},
"content": "<span class=\"h-card\"><a class=\"u-url mention\" href=\"https://mitra.social/users/alex\">@alex</a></span> welcome",
"in_reply_to_id": "017ed503-bc96-301a-e871-2c23b30ddd05",
"reblog": null,
"visibility": "public",
"replies_count": 0,
"favourites_count": 1,
"reblogs_count": 0,
"media_attachments": [],
"mentions": [
{
"id": "017ed4f9-c121-2ae6-0805-15516cce02c3",
"username": "alex",
"acct": "alex",
"url": "https://mitra.social/users/alex"
}
],
"tags": [],
"favourited": true,
"reblogged": false,
"ipfs_cid": null,
"token_id": null,
"token_tx_id": null
}
]

@ -0,0 +1,29 @@
import { Map as ImmutableMap } from 'immutable';
import { STATUSES_IMPORT } from 'soapbox/actions/importer';
import { __stub } from 'soapbox/api';
import { mockStore } from 'soapbox/test_helpers';
import { fetchContext } from '../statuses';
describe('fetchContext()', () => {
it('handles Mitra context', done => {
const statuses = require('soapbox/__fixtures__/mitra-context.json');
__stub(mock => {
mock.onGet('/api/v1/statuses/017ed505-5926-392f-256a-f86d5075df70/context')
.reply(200, statuses);
});
const store = mockStore(ImmutableMap());
store.dispatch(fetchContext('017ed505-5926-392f-256a-f86d5075df70')).then(context => {
const actions = store.getActions();
expect(actions[3].type).toEqual(STATUSES_IMPORT);
expect(actions[3].statuses[0].id).toEqual('017ed503-bc96-301a-e871-2c23b30ddd05');
done();
}).catch(console.error);
});
});

@ -15,6 +15,13 @@ const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => {
export function normalizeAccount(account) {
account = { ...account };
// Some backends can return null, or omit these required fields
if (!account.emojis) account.emojis = [];
if (!account.display_name) account.display_name = '';
if (!account.note) account.note = '';
if (!account.avatar) account.avatar = account.avatar_static || require('images/avatar-missing.png');
if (!account.avatar_static) account.avatar_static = account.avatar;
const emojiMap = makeEmojiMap(account);
const displayName = account.display_name.trim().length === 0 ? account.username : account.display_name;
@ -41,6 +48,10 @@ export function normalizeAccount(account) {
export function normalizeStatus(status, normalOldStatus, expandSpoilers) {
const normalStatus = { ...status };
// Some backends can return null, or omit these required fields
if (!normalStatus.emojis) normalStatus.emojis = [];
if (!normalStatus.spoiler_text) normalStatus.spoiler_text = '';
// Copy the pleroma object too, so we can modify our copy
if (status.pleroma) {
normalStatus.pleroma = { ...status.pleroma };

@ -143,10 +143,18 @@ export function fetchContext(id) {
dispatch({ type: CONTEXT_FETCH_REQUEST, id });
return api(getState).get(`/api/v1/statuses/${id}/context`).then(({ data: context }) => {
const { ancestors, descendants } = context;
const statuses = ancestors.concat(descendants);
dispatch(importFetchedStatuses(statuses));
dispatch({ type: CONTEXT_FETCH_SUCCESS, id, ancestors, descendants });
if (Array.isArray(context)) {
// Mitra: returns a list of statuses
dispatch(importFetchedStatuses(context));
} else if (typeof context === 'object') {
// Standard Mastodon API returns a map with `ancestors` and `descendants`
const { ancestors, descendants } = context;
const statuses = ancestors.concat(descendants);
dispatch(importFetchedStatuses(statuses));
dispatch({ type: CONTEXT_FETCH_SUCCESS, id, ancestors, descendants });
} else {
throw context;
}
return context;
}).catch(error => {
if (error.response && error.response.status === 404) {

@ -28,22 +28,14 @@ export default class Avatar extends React.PureComponent {
height: `${size}px`,
};
// Only render the image if src is provided
if (account.get('avatar')) {
return (
<StillImage
className={classNames('account__avatar', { 'account__avatar-inline': inline })}
style={style}
src={account.get('avatar')}
alt=''
/>
);
} else {
// Fall back on rendering an empty div
return (
<div className={classNames('account__avatar', { 'account__avatar-inline': inline })} style={style} />
);
}
return (
<StillImage
className={classNames('account__avatar', { 'account__avatar-inline': inline })}
style={style}
src={account.get('avatar')}
alt=''
/>
);
}
}

@ -168,7 +168,7 @@ class Item extends React.PureComponent {
onClick={this.handleClick}
target='_blank'
>
<StillImage src={previewUrl} alt={attachment.get('description')} />
<StillImage src={previewUrl || originalUrl} alt={attachment.get('description')} />
</a>
);
} else if (attachment.get('type') === 'gifv') {

@ -88,7 +88,7 @@ class MediaItem extends ImmutablePureComponent {
thumbnail = (
<StillImage
src={attachment.get('preview_url')}
src={attachment.get('preview_url') || attachment.get('url')}
alt={attachment.get('description')}
style={{ objectPosition: `${x}% ${y}%` }}
/>

@ -670,14 +670,12 @@ class UI extends React.PureComponent {
}
render() {
const { streamingUrl, features, soapbox } = this.props;
const { features, soapbox } = this.props;
const { draggingOver, mobile } = this.state;
const { intl, children, location, dropdownMenuIsOpen, me } = this.props;
// Wait for login to succeed or fail
if (me === null) return null;
// If login didn't fail, wait for streaming to become available
if (me !== false && !streamingUrl) return null;
const handlers = me ? {
help: this.handleHotkeyToggleHelp,

Loading…
Cancel
Save