Compare commits

...

65 Commits

Author SHA1 Message Date
beatrix-bitrot
1ba51a4c35 add test 2017-10-19 22:00:03 +00:00
beatrix-bitrot
b10608299e hide mentions of muted accounts (in home col)
also cleans up some old crap
2017-10-19 21:38:41 +00:00
beatrix
f5e2469485 Merge pull request #189 from glitch-soc/scrollable-compose-area
Make the compose area optionally scrollable
2017-10-19 12:28:47 -04:00
David Yip
9423553e5c Make the compose area optionally scrollable.
On desktop, the compose text box grows to accommodate the content.  On
mobile, the text box does not grow to accommodate text context, but does
grow to accommodate images.  It is possible in both cases to overflow
the available area, which makes accessing other UI elements (e.g.
visibility setttings) difficult.

This commit makes the compose area optionally scrollable, which allows
those UI elements to remain available even if they go off-screen.
2017-10-19 10:59:50 -05:00
David Yip
90770f6d59 Merge pull request #185 from glitch-soc/fix-null-status
workaround for null status
2017-10-18 17:01:31 -05:00
beatrix
c756651278 Merge pull request #188 from glitch-soc/merge-upstream-2-0-0
Merge with upstream v2.0.0
2017-10-18 17:57:42 -04:00
Ondřej Hruška
eb907a5bab formatting fix for eslint 2017-10-18 23:44:06 +02:00
David Yip
39c9cdf7fe Remove unused filesAttached property. 2017-10-18 13:20:45 -05:00
David Yip
86cf4468af Update stylesheet imports in glitch components.
Commit 6e54719474 moved the Mastodon
variables and mixins deeper in the directory hierarchy; this commit
brings the glitch components in line with that change.
2017-10-18 11:52:34 -05:00
David Yip
42e8c8eb0e Merge tag 'v2.0.0' into gs-master 2017-10-18 11:52:04 -05:00
Sho Kusano
09d81defcd Suppress type error(not a function) on calling fastSeek (#5452) 2017-10-18 17:13:51 +02:00
Eugen Rochko
3810d98cd8 Bump version to 2.0.0 🐘 2017-10-18 13:53:56 +02:00
Renato "Lond" Cerqueira
26b2a6a71e Fix pt-BR translation strings related to advanced search. (#5449) 2017-10-18 13:53:17 +02:00
Technowix
edf9a5e4fc Revert #5438 for FR (#5450)
As said here https://github.com/tootsuite/mastodon/pull/5438 the point of shortening the timestamp is legit, and after some time of adaptation no mistakes can be mades.
2017-10-18 13:51:30 +02:00
Håkan Eriksson
c710069c12 Some typos and supplementation in sentence structures (#5441)
* Swedish file added

* Swedish file added

* Swedish file updated

* Swedish languagefile added

* Add Swedish translation

* Add Swedish translation

* Started the Swedish translation

* Added Swedish lang settings

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Swedish language completed and added

* Swedish language Simple_form added

* Swedish language Divise added

* Swedish language doorkeeper added

* Swedish language - now all file complete

* Swedish - Typos and supplementation in sentence structure

* Update simple_form.sv.yml

* Update sv.yml

* Update sv.yml

Rearranged the alphabetical order.
2017-10-18 13:50:52 +02:00
Yamagishi Kazutoshi
990d6dd565 Run i18n-tasks checked-normalized in Travis CI (#5443) 2017-10-18 11:57:02 +02:00
Yamagishi Kazutoshi
402da46ff6 Enable coverage for Jest (#5442) 2017-10-18 11:39:36 +02:00
JohnD28
e7099d8d9e fr.json typo (realtive time) (#5447)
Typo correction : https://fr.wikipedia.org/wiki/Heure#Typographie
2017-10-18 16:47:14 +09:00
Eugen Rochko
637ea3bb5b Bump version to 2.0.0rc4 2017-10-17 23:16:35 +02:00
Jeroen
363d0d3a44 Dutch: A few strings I found last minute (#5440)
* Dutch: A few strings I found last minute

* Update simple_form.nl.yml
2017-10-17 23:15:40 +02:00
YaQ
6e54719474 Make theme directory and Rename application.scss (#5336)
* Rename application.scss

* Move to 'default' directory

* Follow review

Move directory, and Rename "mastodon".

* Revert rename

* undo removal of newline
2017-10-18 05:20:07 +09:00
Eugen Rochko
f3003417c5 When unreblog arrives over streaming API, just delete in UI (#5439) 2017-10-17 22:17:02 +02:00
JeanGauthier
33ea042dec i18n better wording (OC/CA/FR) + string added in FR (#5438)
* Update oc.json

* Update fr.json

* Update ca.json

* Update fr.json

* Update simple_form.fr.yml

* Update ca.json

* Update fr.json

* Update oc.json

* Update oc.json

* Update fr.json
2017-10-17 21:49:39 +02:00
Nolan Lawson
8b22a63ab0 Fix scrolling of dropdown when offscreen (#5434) 2017-10-17 20:38:16 +02:00
Eugen Rochko
05686cc99d Fix unwanted content warning gap in CSS (#5436)
Fix #5356
2017-10-17 20:07:44 +02:00
Eugen Rochko
484208ce12 When status is fetched instead of delivered, do not stream it (#5437) 2017-10-17 20:05:21 +02:00
unarist
3bc8924940 Don't capture scheme-less URLs in the status (#5435)
Specifically, this fixes status length calculation to be same as JS side.

BTW, since this pattern used in not only preview card fetching, we
should extract it (with twitter-regex?) and write tests I think.
2017-10-17 18:32:25 +02:00
JeanGauthier
a02de9e012 i18n update (#5427) in OC/CA/FR/ES (#5431)
* Update oc.json

* Update ca.json

* Update fr.json

* Update es.json
2017-10-17 13:03:28 +02:00
unarist
2d395324e1 Fix React warning about tabIndex on status with CW (#5432) 2017-10-17 13:03:12 +02:00
Jakob Kramer
e6c9756fa9 Update German translation (#5425) 2017-10-17 12:02:47 +02:00
Yamagishi Kazutoshi
5050719fac Add Japanese translations (#5427)
* yarn manage:translations

* Add Japanese translation for #5410

* Add Japanese translation for #5393
2017-10-17 11:47:05 +02:00
Yamagishi Kazutoshi
989553c69a Normalize locale files (#5429) 2017-10-17 11:45:59 +02:00
masarakki
0e0c6b1b4b use-DB_NAME-in-development (#5430) 2017-10-17 11:45:37 +02:00
aschmitz
554c2fd8af Clean up reblog tracking keys, related improvements (#5428)
* Clean up reblog-tracking sets from FeedManager

Builds on #5419, with a few minor optimizations and cleanup of sets
after they are no longer needed.

* Update tests, fix multiply-reblogged case

Previously, we would have lost the fact that a given status was
reblogged if the displayed reblog of it was removed, now we don't.

Also added tests to make sure FeedManager#trim cleans up our reblog
tracking keys, fixed up FeedCleanupScheduler to use the right loop,
and fixed the test for it.
2017-10-17 11:45:06 +02:00
Håkan Eriksson
a2b600428c Swedish translation (#5406)
* Swedish file added

* Swedish file added

* Swedish file updated

* Swedish languagefile added

* Add Swedish translation

* Add Swedish translation

* Started the Swedish translation

* Added Swedish lang settings

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Updating Swedish language

* Swedish language completed and added

* Swedish language Simple_form added

* Swedish language Divise added

* Swedish language doorkeeper added

* Swedish language - now all file complete
2017-10-17 13:41:36 +09:00
Jeroen
df1a9c5ab5 Small update Dutch (nl) strings (#5424)
* Update Dutch strings

* Update Dutch
2017-10-17 01:00:23 +02:00
Ondřej Hruška
4421f6598f Fix dual toot button wrong behavior after compose re-design 2017-10-16 23:32:13 +02:00
beatrix
7364b26e4b Merge pull request #184 from tootsuite/master
Fix reduced motion breaking public galleries (#5423)
2017-10-16 17:05:42 -04:00
David Yip
313ba202ef Merge pull request #182 from glitch-soc/wide-tootbox-panel
Full-width tootbox panel to make room for buttons
2017-10-16 15:49:22 -05:00
David Yip
7c44ad6355 Merge pull request #181 from glitch-soc/upstream-merge-again
Merge upstream, pull in fixes for tootsuite/mastodon#{5409,5417}
2017-10-16 15:46:12 -05:00
Ondřej Hruška
37ff061d9b satisfy eslint and jest 2017-10-16 22:24:44 +02:00
Ondřej Hruška
3d7de06db4 rem a comment 2017-10-16 22:12:38 +02:00
Ondřej Hruška
26f08f0791 double-decker tootbox 2017-10-16 22:10:14 +02:00
Ondřej Hruška
8b9ee5f16b Merge remote-tracking branch 'upstream/master' into upstream-merge-again 2017-10-16 21:13:47 +02:00
Ondřej Hruška
4b397adb5b fix some lint errors 2017-10-16 21:13:34 +02:00
Nolan Lawson
8980aa804f Fix reduced motion breaking public galleries (#5423) 2017-10-16 21:08:01 +02:00
Eugen Rochko
34118169ac Keep references to all reblogs of a status on home feed (#5419)
* Keep references to all reblogs of a status on home feed

When inserting reblog: Add to set of reblogs of this status on
the feed, if original status was present in the feed, add it to
that set as well.

When removing a reblog: Remove it from that set. Take random
remaining item from the set. If one exists, re-insert it into feed,
otherwise do not re-insert anything.

Fix #4210

* When original is removed, toss out reblog references
2017-10-16 20:44:31 +02:00
Daigo 3 Dango
4fd7aebd5e Fix typo in a db:rollback script (#5422)
Reported at
https://don.inux39.me/@inux39/1406082
https://don.inux39.me/@inux39/1406134
2017-10-16 20:29:49 +02:00
David Yip
65154869df Merge remote-tracking branch 'upstream/master' into upstream-merge-again 2017-10-16 09:54:16 -05:00
Eugen Rochko
bc89995f65 Bump version to 2.0.0rc3 2017-10-16 16:29:00 +02:00
David Yip
7e9d93472c Merge remote-tracking branch 'upstream/master' into gs-master 2017-10-16 09:27:01 -05:00
David Yip
dbb1fce94d Merge remote-tracking branch 'upstream/master' into gs-master 2017-10-16 09:23:59 -05:00
Eugen Rochko
7cc71748ce Ensure that feed renegeration restores non-zero items (#5409)
Fix #5398

Ordering the home timeline query by account_id meant that the first
100 items belonged to a single account. There was also no reason to
reverse-iterate over the statuses. Assuming the user accesses the
feed halfway-through, it's better to have recent statuses already
available at the top. Therefore working from newer->older is ideal.

If the algorithm ends up filtering all items out during last-mile
filtering, repeat again a page further. The algorithm terminates
when either at least one item has been added, or if the database
query returns nothing (end of data reached)
2017-10-16 16:08:51 +02:00
Eugen Rochko
aec70b44fc Filter out duplicate IDs in timelines reducer (#5417)
Possibly the cause of #5379, #5377
2017-10-16 15:59:30 +02:00
unarist
6f490b4bfe Fix un-reblogged status being at wrong position in the home timeline (#5418)
We've changed un-reblogging behavior when we implement Snowflake, to insert un-reblogged status at the position reblogging status existed.

However, our API expects home timeline is ordered by status ids, and max_id/since_id filters by zset score. Due to this, un-reblogged status appears as a last item of result set, and timeline expansion may skips many statuses.

So this reverts that change...reblogged status inserted at corresponding position to its id.
2017-10-16 15:58:23 +02:00
voidSatisfaction
03975dbde4 Add up-to-date korean translation on client (#5402)
* chore: add Korean translation for client

* fix: change unlisted and embed Korean words
2017-10-16 14:39:28 +02:00
KY
f72936b4e6 Fix #5082 - disable retweet link for followers only toot (#5397)
* Fix #5082 - disable retweet link for followers only toot

* Hide reblog count when it is a direct message
2017-10-16 14:10:12 +02:00
Marcin Mikołajczak
3c530d95f6 i18n: Update Polish translation (#5416)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2017-10-16 14:09:51 +02:00
JeanGauthier
1e7b3bf625 i18n ultim hour «More» dropdown title + reduce motion (#5415)
* Correction fem. form

* More dropdown title

* More dropdown title

* More dropdown title

* Add option to reduce motion (#5393)
2017-10-16 14:09:26 +02:00
Yamagishi Kazutoshi
bf0ee1a25c Enable ESLint rules import/* (#5414)
* Enable ESLint rules import/*

* fix
2017-10-16 11:12:09 +02:00
Nolan Lawson
fa0be3f834 Add option to reduce motion (#5393)
* Add option to reduce motion

* Use HOC to wrap all Motion calls

* fix case-sensitive issue

* Avoid updating too frequently

* Get rid of unnecessary change to _simple_status.html.haml
2017-10-16 09:36:15 +02:00
Nolan Lawson
981e20b03a Fix offline-plugin warning in dev mode (#5411) 2017-10-16 09:33:50 +02:00
Yamagishi Kazutoshi
d5b767c374 Replace JavaScript Testing Framework from Mocha to Jest (#5412) 2017-10-16 09:33:08 +02:00
Nolan Lawson
93b54b8d4b i18n "More" dropdown title (#5410) 2017-10-16 09:31:47 +02:00
Nolan Lawson
e7ab9bf8b4 Refactor and simplify icon_button.js (#5413) 2017-10-16 09:30:09 +02:00
165 changed files with 3247 additions and 1072 deletions

View File

@@ -5,12 +5,14 @@ env:
browser: true
node: true
es6: true
jest: true
parser: babel-eslint
plugins:
- react
- jsx-a11y
- import
parserOptions:
sourceType: module
@@ -21,8 +23,14 @@ parserOptions:
modules: true
spread: true
rules:
settings:
import/extensions:
- .js
import/ignore:
- node_modules
- \\.(css|scss|json)$
rules:
brace-style: warn
comma-dangle:
- error
@@ -125,3 +133,17 @@ rules:
jsx-a11y/role-supports-aria-props: off
jsx-a11y/scope: warn
jsx-a11y/tabindex-no-positive: warn
import/extensions:
- error
- always
- js: never
import/newline-after-import: error
import/no-extraneous-dependencies:
- error
- devDependencies:
- "config/webpack/**"
- "app/javascript/mastodon/test_setup.js"
- "app/javascript/**/__tests__/**"
import/no-unresolved: error
import/no-webpack-loader-syntax: error

View File

@@ -53,5 +53,5 @@ before_script:
script:
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
- npm test
- bundle exec i18n-tasks unused
- yarn test
- bundle exec i18n-tasks check-normalized && bundle exec i18n-tasks unused

View File

@@ -39,6 +39,7 @@ class Settings::PreferencesController < ApplicationController
:setting_boost_modal,
:setting_delete_modal,
:setting_auto_play_gif,
:setting_reduce_motion,
:setting_system_font_ui,
:setting_noindex,
:setting_theme,

View File

@@ -27,6 +27,7 @@ module SettingsHelper
pt: 'Português',
'pt-BR': 'Português do Brasil',
ru: 'Русский',
sv: 'Svenska',
th: 'ภาษาไทย',
tr: 'Türkçe',
uk: 'Українська',

View File

@@ -48,7 +48,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
// Mastodon imports //
import emojify from 'mastodon/features/emoji/emoji';
import emojify from '../../../mastodon/features/emoji/emoji';
import IconButton from '../../../mastodon/components/icon_button';
import Avatar from '../../../mastodon/components/avatar';

View File

@@ -2,10 +2,10 @@
import { connect } from 'react-redux';
// Mastodon imports //
import { closeModal } from 'mastodon/actions/modal';
import { closeModal } from '../../../mastodon/actions/modal';
// Our imports //
import { changeLocalSetting } from 'glitch/actions/local_settings';
import { changeLocalSetting } from '../../../glitch/actions/local_settings';
import LocalSettings from '.';
const mapStateToProps = state => ({

View File

@@ -8,7 +8,7 @@ import LocalSettingsPage from './page';
import LocalSettingsNavigation from './navigation';
// Stylesheet imports
import './style';
import './style.scss';
export default class LocalSettings extends React.PureComponent {

View File

@@ -7,7 +7,7 @@ import { injectIntl, defineMessages } from 'react-intl';
import LocalSettingsNavigationItem from './item';
// Stylesheet imports
import './style';
import './style.scss';
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
// Stylesheet imports
import './style';
import './style.scss';
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

View File

@@ -1,4 +1,4 @@
@import 'styles/variables';
@import 'styles/mastodon/variables';
.glitch.local-settings__navigation__item {
display: block;

View File

@@ -1,4 +1,4 @@
@import 'styles/variables';
@import 'styles/mastodon/variables';
.glitch.local-settings__navigation {
background: $primary-text-color;

View File

@@ -8,7 +8,7 @@ import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import LocalSettingsPageItem from './item';
// Stylesheet imports
import './style';
import './style.scss';
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
// Stylesheet imports
import './style';
import './style.scss';
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

View File

@@ -1,4 +1,4 @@
@import 'styles/variables';
@import 'styles/mastodon/variables';
.glitch.local-settings__page__item {
select {

View File

@@ -1,4 +1,4 @@
@import 'styles/variables';
@import 'styles/mastodon/variables';
.glitch.local-settings__page {
display: block;

View File

@@ -1,4 +1,4 @@
@import 'styles/variables';
@import 'styles/mastodon/variables';
.glitch.local-settings {
position: relative;

View File

@@ -1,5 +1,5 @@
import 'intl';
import 'intl/locale-data/jsonp/en.js';
import 'intl/locale-data/jsonp/en';
import 'es6-symbol/implement';
import includes from 'array-includes';
import assign from 'object-assign';

View File

@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
<div
className="account__avatar"
data-avatar-of="@alice"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
Object {
"backgroundImage": "url(/animated/alice.gif)",
"backgroundSize": "100px 100px",
"height": "100px",
"width": "100px",
}
}
/>
`;
exports[`<Avatar /> Still renders a still avatar 1`] = `
<div
className="account__avatar"
data-avatar-of="@alice"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
Object {
"backgroundImage": "url(/static/alice.jpg)",
"backgroundSize": "100px 100px",
"height": "100px",
"width": "100px",
}
}
/>
`;

View File

@@ -0,0 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<AvatarOverlay renders a overlay avatar 1`] = `
<div
className="account__avatar-overlay"
>
<div
className="account__avatar-overlay-base"
data-avatar-of="@alice"
style={
Object {
"backgroundImage": "url(/static/alice.jpg)",
}
}
/>
<div
className="account__avatar-overlay-overlay"
data-avatar-of="@eve@blackhat.lair"
style={
Object {
"backgroundImage": "url(/static/eve.jpg)",
}
}
/>
</div>
`;

View File

@@ -0,0 +1,114 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] = `
<button
className="button button-secondary"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
/>
`;
exports[`<Button /> renders a button element 1`] = `
<button
className="button"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
/>
`;
exports[`<Button /> renders a disabled attribute if props.disabled given 1`] = `
<button
className="button"
disabled={true}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
/>
`;
exports[`<Button /> renders class="button--block" if props.block given 1`] = `
<button
className="button button--block"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
/>
`;
exports[`<Button /> renders the children 1`] = `
<button
className="button"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
>
<p>
children
</p>
</button>
`;
exports[`<Button /> renders the given text 1`] = `
<button
className="button"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
>
foo
</button>
`;
exports[`<Button /> renders the props.text instead of children 1`] = `
<button
className="button"
disabled={undefined}
onClick={[Function]}
style={
Object {
"height": "36px",
"lineHeight": "36px",
"padding": "0 16px",
}
}
>
foo
</button>
`;

View File

@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<DisplayName /> renders display name + account name 1`] = `
<span
className="display-name"
>
<strong
className="display-name__html"
dangerouslySetInnerHTML={
Object {
"__html": "<p>Foo</p>",
}
}
/>
<span
className="display-name__account"
>
@
bar@baz
</span>
</span>
`;

View File

@@ -0,0 +1,36 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { fromJS } from 'immutable';
import Avatar from '../avatar';
describe('<Avatar />', () => {
const account = fromJS({
username: 'alice',
acct: 'alice',
display_name: 'Alice',
avatar: '/animated/alice.gif',
avatar_static: '/static/alice.jpg',
});
const size = 100;
describe('Autoplay', () => {
it('renders a animated avatar', () => {
const component = renderer.create(<Avatar account={account} animate size={size} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('Still', () => {
it('renders a still avatar', () => {
const component = renderer.create(<Avatar account={account} size={size} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
// TODO add autoplay test if possible
});

View File

@@ -0,0 +1,29 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { fromJS } from 'immutable';
import AvatarOverlay from '../avatar_overlay';
describe('<AvatarOverlay', () => {
const account = fromJS({
username: 'alice',
acct: 'alice',
display_name: 'Alice',
avatar: '/animated/alice.gif',
avatar_static: '/static/alice.jpg',
});
const friend = fromJS({
username: 'eve',
acct: 'eve@blackhat.lair',
display_name: 'Evelyn',
avatar: '/animated/eve.gif',
avatar_static: '/static/eve.jpg',
});
it('renders a overlay avatar', () => {
const component = renderer.create(<AvatarOverlay account={account} friend={friend} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,75 @@
import { shallow } from 'enzyme';
import React from 'react';
import renderer from 'react-test-renderer';
import Button from '../button';
describe('<Button />', () => {
it('renders a button element', () => {
const component = renderer.create(<Button />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders the given text', () => {
const text = 'foo';
const component = renderer.create(<Button text={text} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('handles click events using the given handler', () => {
const handler = jest.fn();
const button = shallow(<Button onClick={handler} />);
button.find('button').simulate('click');
expect(handler.mock.calls.length).toEqual(1);
});
it('does not handle click events if props.disabled given', () => {
const handler = jest.fn();
const button = shallow(<Button onClick={handler} disabled />);
button.find('button').simulate('click');
expect(handler.mock.calls.length).toEqual(0);
});
it('renders a disabled attribute if props.disabled given', () => {
const component = renderer.create(<Button disabled />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders the children', () => {
const children = <p>children</p>;
const component = renderer.create(<Button>{children}</Button>);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders the props.text instead of children', () => {
const text = 'foo';
const children = <p>children</p>;
const component = renderer.create(<Button text={text}>{children}</Button>);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders class="button--block" if props.block given', () => {
const component = renderer.create(<Button block />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
it('adds class "button-secondary" if props.secondary given', () => {
const component = renderer.create(<Button secondary />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,18 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { fromJS } from 'immutable';
import DisplayName from '../display_name';
describe('<DisplayName />', () => {
it('renders display name + account name', () => {
const account = fromJS({
username: 'bar',
acct: 'bar@baz',
display_name_html: '<p>Foo</p>',
});
const component = renderer.create(<DisplayName account={account} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -1,5 +1,5 @@
import React from 'react';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from './icon_button';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import detectPassiveEvents from 'detect-passive-events';

View File

@@ -1,7 +1,8 @@
import React from 'react';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export default class IconButton extends React.PureComponent {
@@ -56,27 +57,26 @@ export default class IconButton extends React.PureComponent {
style.textAlign = 'left';
}
const classes = ['icon-button'];
const {
active,
animate,
className,
disabled,
expanded,
icon,
inverted,
overlay,
pressed,
tabIndex,
title,
} = this.props;
if (this.props.active) {
classes.push('active');
}
if (this.props.disabled) {
classes.push('disabled');
}
if (this.props.inverted) {
classes.push('inverted');
}
if (this.props.overlay) {
classes.push('overlayed');
}
if (this.props.className) {
classes.push(this.props.className);
}
const classes = classNames(className, 'icon-button', {
active,
disabled,
inverted,
overlayed: overlay,
});
const flipDeg = this.props.flip ? -180 : -360;
const rotateDeg = this.props.active ? flipDeg : 0;
@@ -90,23 +90,23 @@ export default class IconButton extends React.PureComponent {
damping: 7,
};
const motionStyle = {
rotate: this.props.animate ? spring(rotateDeg, springOpts) : 0,
rotate: animate ? spring(rotateDeg, springOpts) : 0,
};
return (
<Motion defaultStyle={motionDefaultStyle} style={motionStyle}>
{({ rotate }) =>
<button
aria-label={this.props.title}
aria-pressed={this.props.pressed}
aria-expanded={this.props.expanded}
title={this.props.title}
className={classes.join(' ')}
aria-label={title}
aria-pressed={pressed}
aria-expanded={expanded}
title={title}
className={classes}
onClick={this.handleClick}
style={style}
tabIndex={this.props.tabIndex}
tabIndex={tabIndex}
>
<i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />
<i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
{this.props.label}
</button>
}

View File

@@ -16,6 +16,7 @@ const messages = defineMessages({
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
reply: { id: 'status.reply', defaultMessage: 'Reply' },
share: { id: 'status.share', defaultMessage: 'Share' },
more: { id: 'status.more', defaultMessage: 'More' },
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
@@ -182,7 +183,7 @@ export default class StatusActionBar extends ImmutablePureComponent {
{shareButton}
<div className='status__action-bar-dropdown'>
<DropdownMenuContainer disabled={anonymousAccess} status={status} items={menu} icon='ellipsis-h' size={18} direction='right' ariaLabel='More' />
<DropdownMenuContainer disabled={anonymousAccess} status={status} items={menu} icon='ellipsis-h' size={18} direction='right' ariaLabel={intl.formatMessage(messages.more)} />
</div>
</div>
);

View File

@@ -125,6 +125,7 @@ export default class StatusContent extends React.PureComponent {
const directionStyle = { direction: 'ltr' };
const classNames = classnames('status__content', {
'status__content--with-action': this.props.onClick && this.context.router,
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
});
if (isRtl(status.get('search_index'))) {
@@ -156,7 +157,7 @@ export default class StatusContent extends React.PureComponent {
{mentionsPlaceholder}
<div tabIndex={!hidden && 0} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
<div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
</div>
);
} else if (this.props.onClick) {

View File

@@ -10,6 +10,7 @@ import { hydrateStore } from '../actions/store';
import { connectUserStream } from '../actions/streaming';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
const { localeData, messages } = getLocale();
addLocaleData(localeData);

View File

@@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import IconButton from '../../../components/icon_button';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { connect } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';

View File

@@ -58,7 +58,6 @@ export default class ComposeForm extends ImmutablePureComponent {
onPickEmoji: PropTypes.func.isRequired,
showSearch: PropTypes.bool,
settings : ImmutablePropTypes.map.isRequired,
filesAttached : PropTypes.bool,
};
static defaultProps = {
@@ -156,13 +155,12 @@ export default class ComposeForm extends ImmutablePureComponent {
}
render () {
const { intl, onPaste, showSearch, filesAttached } = this.props;
const { intl, onPaste, showSearch } = this.props;
const disabled = this.props.is_submitting;
const maybeEye = (this.props.advanced_options && this.props.advanced_options.do_not_federate) ? ' 👁️' : '';
const text = [this.props.spoiler_text, countableText(this.props.text), maybeEye].join('');
const secondaryVisibility = this.props.settings.get('side_arm');
const isWideView = this.props.settings.get('stretch');
let showSideArm = secondaryVisibility !== 'none';
let publishText = '';
@@ -182,14 +180,9 @@ export default class ComposeForm extends ImmutablePureComponent {
{
<i
className={`fa fa-${privacyIcons[this.props.privacy]}`}
style={{
paddingRight: (filesAttached || !isWideView) ? '0' : '5px',
}}
style={{ paddingRight: '5px' }}
/>
}{
(filesAttached || !isWideView) ? '' :
intl.formatMessage(messages.publish)
}
}{intl.formatMessage(messages.publish)}
</span>
);
@@ -247,7 +240,6 @@ export default class ComposeForm extends ImmutablePureComponent {
<UploadFormContainer />
</div>
<div className='compose-form__buttons-wrapper'>
<div className='compose-form__buttons'>
<UploadButtonContainer />
<DoodleButtonContainer />
@@ -274,12 +266,10 @@ export default class ComposeForm extends ImmutablePureComponent {
text={publishText}
onClick={this.handleSubmit}
disabled={submitDisabled}
block
/>
</div>
</div>
</div>
</div>
);
}

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl';
import IconButton from '../../../components/icon_button';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import detectPassiveEvents from 'detect-passive-events';
import classNames from 'classnames';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
const messages = defineMessages({

View File

@@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import IconButton from '../../../components/icon_button';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl } from 'react-intl';

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { FormattedMessage } from 'react-intl';

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
export default class Warning extends React.PureComponent {

View File

@@ -1,15 +0,0 @@
import { connect } from 'react-redux';
import AutosuggestStatus from '../components/autosuggest_status';
import { makeGetStatus } from '../../../selectors';
const makeMapStateToProps = () => {
const getStatus = makeGetStatus();
const mapStateToProps = (state, { id }) => ({
status: getStatus(state, id),
});
return mapStateToProps;
};
export default connect(makeMapStateToProps)(AutosuggestStatus);

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
import IconButton from '../../../components/icon_button';
import { changeComposeSensitivity } from '../../../actions/compose';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { injectIntl, defineMessages } from 'react-intl';

View File

@@ -10,7 +10,7 @@ import { changeLocalSetting } from '../../../glitch/actions/local_settings';
import { Link } from 'react-router-dom';
import { injectIntl, defineMessages } from 'react-intl';
import SearchContainer from './containers/search_container';
import Motion from 'react-motion/lib/Motion';
import Motion from '../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import SearchResultsContainer from './containers/search_results_container';
import { changeComposing } from '../../actions/compose';
@@ -105,7 +105,7 @@ export default class Compose extends React.PureComponent {
<SearchContainer />
<div className='drawer__pager'>
<div className='drawer__inner' onFocus={this.onFocus}>
<div className='drawer__inner scrollable optionally-scrollable' onFocus={this.onFocus}>
<NavigationContainer onClose={this.onBlur} />
<ComposeFormContainer />
</div>

View File

@@ -0,0 +1,61 @@
import emojify from '../emoji';
describe('emoji', () => {
describe('.emojify', () => {
it('ignores unknown shortcodes', () => {
expect(emojify(':foobarbazfake:')).toEqual(':foobarbazfake:');
});
it('ignores shortcodes inside of tags', () => {
expect(emojify('<p data-foo=":smile:"></p>')).toEqual('<p data-foo=":smile:"></p>');
});
it('works with unclosed tags', () => {
expect(emojify('hello>')).toEqual('hello>');
expect(emojify('<hello')).toEqual('<hello');
});
it('works with unclosed shortcodes', () => {
expect(emojify('smile:')).toEqual('smile:');
expect(emojify(':smile')).toEqual(':smile');
});
it('does unicode', () => {
expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual(
'<img draggable="false" class="emojione" alt="👩‍👩‍👦‍👦" title=":woman-woman-boy-boy:" src="/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg" />');
expect(emojify('👨‍👩‍👧‍👧')).toEqual(
'<img draggable="false" class="emojione" alt="👨‍👩‍👧‍👧" title=":man-woman-girl-girl:" src="/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg" />');
expect(emojify('👩‍👩‍👦')).toEqual('<img draggable="false" class="emojione" alt="👩‍👩‍👦" title=":woman-woman-boy:" src="/emoji/1f469-200d-1f469-200d-1f466.svg" />');
expect(emojify('\u2757')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />');
});
it('does multiple unicode', () => {
expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />');
expect(emojify('\u2757#\uFE0F\u20E3')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /><img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />');
expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />');
expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual(
'foo <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> bar');
});
it('ignores unicode inside of tags', () => {
expect(emojify('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>')).toEqual('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>');
});
it('does multiple emoji properly (issue 5188)', () => {
expect(emojify('👌🌈💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /><img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />');
expect(emojify('👌 🌈 💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /> <img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /> <img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />');
});
it('does an emoji that has no shortcode', () => {
expect(emojify('🕉️')).toEqual('<img draggable="false" class="emojione" alt="🕉️" title="" src="/emoji/1f549.svg" />');
});
it('does an emoji whose filename is irregular', () => {
expect(emojify('↙️')).toEqual('<img draggable="false" class="emojione" alt="↙️" title=":arrow_lower_left:" src="/emoji/2199.svg" />');
});
});
});

View File

@@ -0,0 +1,130 @@
import { pick } from 'lodash';
import { emojiIndex } from 'emoji-mart';
import { search } from '../emoji_mart_search_light';
const trimEmojis = emoji => pick(emoji, ['id', 'unified', 'native', 'custom']);
describe('emoji_index', () => {
it('should give same result for emoji_index_light and emoji-mart', () => {
const expected = [
{
id: 'pineapple',
unified: '1f34d',
native: '🍍',
},
];
expect(search('pineapple').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('pineapple').map(trimEmojis)).toEqual(expected);
});
it('orders search results correctly', () => {
const expected = [
{
id: 'apple',
unified: '1f34e',
native: '🍎',
},
{
id: 'pineapple',
unified: '1f34d',
native: '🍍',
},
{
id: 'green_apple',
unified: '1f34f',
native: '🍏',
},
{
id: 'iphone',
unified: '1f4f1',
native: '📱',
},
];
expect(search('apple').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('apple').map(trimEmojis)).toEqual(expected);
});
it('handles custom emoji', () => {
const custom = [
{
id: 'mastodon',
name: 'mastodon',
short_names: ['mastodon'],
text: '',
emoticons: [],
keywords: ['mastodon'],
imageUrl: 'http://example.com',
custom: true,
},
];
search('', { custom });
emojiIndex.search('', { custom });
const expected = [
{
id: 'mastodon',
custom: true,
},
];
expect(search('masto').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('masto').map(trimEmojis)).toEqual(expected);
});
it('should filter only emojis we care about, exclude pineapple', () => {
const emojisToShowFilter = unified => unified !== '1F34D';
expect(search('apple', { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain('pineapple');
expect(emojiIndex.search('apple', { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain('pineapple');
});
it('can include/exclude categories', () => {
expect(search('flag', { include: ['people'] })).toEqual([]);
expect(emojiIndex.search('flag', { include: ['people'] })).toEqual([]);
});
it('does an emoji whose unified name is irregular', () => {
const expected = [
{
'id': 'water_polo',
'unified': '1f93d',
'native': '🤽',
},
{
'id': 'man-playing-water-polo',
'unified': '1f93d-200d-2642-fe0f',
'native': '🤽‍♂️',
},
{
'id': 'woman-playing-water-polo',
'unified': '1f93d-200d-2640-fe0f',
'native': '🤽‍♀️',
},
];
expect(search('polo').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('polo').map(trimEmojis)).toEqual(expected);
});
it('can search for thinking_face', () => {
const expected = [
{
id: 'thinking_face',
unified: '1f914',
native: '🤔',
},
];
expect(search('thinking_fac').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('thinking_fac').map(trimEmojis)).toEqual(expected);
});
it('can search for woman-facepalming', () => {
const expected = [
{
id: 'woman-facepalming',
unified: '1f926-200d-2640-fe0f',
native: '🤦‍♀️',
},
];
expect(search('woman-facep').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('woman-facep').map(trimEmojis)).toEqual(expected);
});
});

View File

@@ -9,7 +9,8 @@ const { unicodeToFilename } = require('./unicode_to_filename');
const { unicodeToUnifiedName } = require('./unicode_to_unified_name');
const emojiMap = require('./emoji_map.json');
const { emojiIndex } = require('emoji-mart');
const emojiMartData = require('emoji-mart/dist/data').default;
const { default: emojiMartData } = require('emoji-mart/dist/data');
const excluded = ['®', '©', '™'];
const skins = ['🏻', '🏼', '🏽', '🏾', '🏿'];
const shortcodeMap = {};

View File

@@ -48,6 +48,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
let media = '';
let mediaIcon = null;
let applicationLink = '';
let reblogLink = '';
let reblogIcon = 'retweet';
if (status.get('media_attachments').size > 0) {
if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
@@ -85,6 +87,23 @@ export default class DetailedStatus extends ImmutablePureComponent {
applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener'>{status.getIn(['application', 'name'])}</a></span>;
}
if (status.get('visibility') === 'direct') {
reblogIcon = 'envelope';
} else if (status.get('visibility') === 'private') {
reblogIcon = 'lock';
}
if (status.get('visibility') === 'private') {
reblogLink = <i className={`fa fa-${reblogIcon}`} />;
} else {
reblogLink = (<Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
<i className={`fa fa-${reblogIcon}`} />
<span className='detailed-status__reblogs'>
<FormattedNumber value={status.get('reblogs_count')} />
</span>
</Link>);
}
return (
<div className='detailed-status'>
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
@@ -101,12 +120,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{applicationLink} · <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
<i className='fa fa-retweet' />
<span className='detailed-status__reblogs'>
<FormattedNumber value={status.get('reblogs_count')} />
</span>
</Link> · <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
</a>{applicationLink} · {reblogLink} · <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
<i className='fa fa-star' />
<span className='detailed-status__favorites'>
<FormattedNumber value={status.get('favourites_count')} />

View File

@@ -1,14 +1,18 @@
import { expect } from 'chai';
import { mount } from 'enzyme';
import sinon from 'sinon';
import React from 'react';
import Column from '../../../../../../app/javascript/mastodon/features/ui/components/column';
import ColumnHeader from '../../../../../../app/javascript/mastodon/features/ui/components/column_header';
import { mount } from 'enzyme';
import Column from '../column';
import ColumnHeader from '../column_header';
describe('<Column />', () => {
describe('<ColumnHeader /> click handler', () => {
const originalRaf = global.requestAnimationFrame;
beforeEach(() => {
global.requestAnimationFrame = sinon.spy();
global.requestAnimationFrame = jest.fn();
});
afterAll(() => {
global.requestAnimationFrame = originalRaf;
});
it('runs the scroll animation if the column contains scrollable content', () => {
@@ -18,13 +22,13 @@ describe('<Column />', () => {
</Column>
);
wrapper.find(ColumnHeader).simulate('click');
expect(global.requestAnimationFrame.called).to.equal(true);
expect(global.requestAnimationFrame.mock.calls.length).toEqual(1);
});
it('does not try to scroll if there is no scrollable content', () => {
const wrapper = mount(<Column heading='notifications' />);
wrapper.find(ColumnHeader).simulate('click');
expect(global.requestAnimationFrame.called).to.equal(false);
expect(global.requestAnimationFrame.mock.calls.length).toEqual(0);
});
});
});

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { FormattedMessage } from 'react-intl';

View File

@@ -0,0 +1,56 @@
// Like react-motion's Motion, but checks to see if the user prefers
// reduced motion and uses a cross-fade in those cases.
import React from 'react';
import Motion from 'react-motion/lib/Motion';
import PropTypes from 'prop-types';
const stylesToKeep = ['opacity', 'backgroundOpacity'];
let reduceMotion;
const extractValue = (value) => {
// This is either an object with a "val" property or it's a number
return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
};
class OptionalMotion extends React.Component {
static propTypes = {
defaultStyle: PropTypes.object,
style: PropTypes.object,
children: PropTypes.func,
}
render() {
const { style, defaultStyle, children } = this.props;
if (typeof reduceMotion !== 'boolean') {
// This never changes without a page reload, so we can just grab it
// once from the body classes as opposed to using Redux's connect(),
// which would unnecessarily update every state change
reduceMotion = document.body.classList.contains('reduce-motion');
}
if (reduceMotion) {
Object.keys(style).forEach(key => {
if (stylesToKeep.includes(key)) {
return;
}
// If it's setting an x or height or scale or some other value, we need
// to preserve the end-state value without actually animating it
style[key] = defaultStyle[key] = extractValue(style[key]);
});
}
return (
<Motion style={style} defaultStyle={defaultStyle}>
{children}
</Motion>
);
}
}
export default OptionalMotion;

View File

@@ -82,7 +82,6 @@
"empty_column.community": "الخط الزمني المحلي فارغ. اكتب شيئا ما للعامة كبداية.",
"empty_column.hashtag": "ليس هناك بعدُ أي محتوى ذو علاقة بهذا الوسم.",
"empty_column.home": "إنك لا تتبع بعد أي شخص إلى حد الآن. زر {public} أو استخدام حقل البحث لكي تبدأ على التعرف على مستخدمين آخرين.",
"empty_column.home.inactivity": "صفحتك فارغة. لقد كنت غائبا لفترة طويلة عن الشبكة. سوف تملأ تلقائيا في وقت قريب.",
"empty_column.home.public_timeline": "الخيط العام",
"empty_column.notifications": "لم تتلق أي إشعار بعدُ. تفاعل مع المستخدمين الآخرين لإنشاء محادثة.",
"empty_column.public": "لا يوجد شيء هنا ! قم بتحرير شيء ما بشكل عام، أو اتبع مستخدمين آخرين في الخوادم المثيلة الأخرى لملء خيط المحادثات العام.",
@@ -160,6 +159,11 @@
"privacy.public.short": "للعامة",
"privacy.unlisted.long": "لا تقم بإدراجه على الخيوط العامة",
"privacy.unlisted.short": "غير مدرج",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "إلغاء",
"report.placeholder": "تعليقات إضافية",
"report.submit": "إرسال",
@@ -179,6 +183,7 @@
"status.load_more": "حمّل المزيد",
"status.media_hidden": "الصورة مستترة",
"status.mention": "أذكُر @{name}",
"status.more": "More",
"status.mute_conversation": "كتم المحادثة",
"status.open": "وسع هذه المشاركة",
"status.pin": "تدبيس على الملف الشخصي",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Отказ",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Споменаване",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per fer rodar la pilota!",
"empty_column.hashtag": "Encara no hi ha res amb aquesta etiqueta.",
"empty_column.home": "Encara no segueixes ningú. Visita {public} o fes cerca per començar i conèixer altres usuaris.",
"empty_column.home.inactivity": "La línia Inici és buida. si has estat inactiu durant un temps es regenerarà aviat.",
"empty_column.home.public_timeline": "la línia de temps pública",
"empty_column.notifications": "Encara no tens notificacions. Interactua amb altres per iniciar la conversa.",
"empty_column.public": "No hi ha res aquí! Escriu alguna cosa públicament o segueix manualment usuaris d'altres instàncies per omplir-ho",
@@ -160,11 +159,11 @@
"privacy.public.short": "Públic",
"privacy.unlisted.long": "No publicar en línies de temps públiques",
"privacy.unlisted.short": "No llistat",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"relative_time.days": "fa {number} jorns",
"relative_time.hours": "fa {number} hores",
"relative_time.just_now": "ara",
"relative_time.minutes": "fa {number} minutes",
"relative_time.seconds": "fa {number} segondes",
"reply_indicator.cancel": "Cancel·lar",
"report.placeholder": "Comentaris addicionals",
"report.submit": "Enviar",
@@ -184,6 +183,7 @@
"status.load_more": "Carrega més",
"status.media_hidden": "Multimèdia amagat",
"status.mention": "Esmentar @{name}",
"status.more": "Més",
"status.mute_conversation": "Silenciar conversació",
"status.open": "Ampliar aquest estat",
"status.pin": "Fixat en el perfil",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe einen öffentlichen Beitrag, um den Ball ins Rollen zu bringen!",
"empty_column.hashtag": "Unter diesem Hashtag gibt es noch nichts.",
"empty_column.home": "Deine Startseite ist leer! Besuche {public} oder nutze die Suche, um loszulegen und andere Leute zu finden.",
"empty_column.home.inactivity": "Deine Zeitleiste ist leer. Falls du eine längere Zeit inaktiv warst, wird sie für dich so schnell wie möglich neu erstellt.",
"empty_column.home.public_timeline": "die öffentliche Zeitleiste",
"empty_column.notifications": "Du hast noch keine Mitteilungen. Interagiere mit anderen, um ins Gespräch zu kommen.",
"empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas öffentlich oder folge Profilen von anderen Instanzen, um die Zeitleiste aufzufüllen",
@@ -160,6 +159,11 @@
"privacy.public.short": "Öffentlich",
"privacy.unlisted.long": "Nicht in öffentlichen Zeitleisten anzeigen",
"privacy.unlisted.short": "Nicht gelistet",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Abbrechen",
"report.placeholder": "Zusätzliche Kommentare",
"report.submit": "Absenden",
@@ -179,6 +183,7 @@
"status.load_more": "Weitere laden",
"status.media_hidden": "Medien versteckt",
"status.mention": "@{name} erwähnen",
"status.more": "Mehr",
"status.mute_conversation": "Thread stummschalten",
"status.open": "Diesen Beitrag öffnen",
"status.pin": "Im Profil anheften",

View File

@@ -183,6 +183,10 @@
"defaultMessage": "Share",
"id": "status.share"
},
{
"defaultMessage": "More",
"id": "status.more"
},
{
"defaultMessage": "Reply to thread",
"id": "status.replyAll"
@@ -907,10 +911,6 @@
"defaultMessage": "Home",
"id": "column.home"
},
{
"defaultMessage": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"id": "empty_column.home.inactivity"
},
{
"defaultMessage": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"id": "empty_column.home"

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not post to public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Rezigni",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mencii @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!",
"empty_column.hashtag": "No hay nada en este hashtag aún.",
"empty_column.home": "No estás siguiendo a nadie aún. Visita {public} o haz búsquedas para empezar y conocer gente nueva.",
"empty_column.home.inactivity": "Tus notificaciones están vacías. Si has estado inactivo por un tiempo, se regenerará para ti pronto.",
"empty_column.home.public_timeline": "la línea de tiempo pública",
"empty_column.notifications": "No tienes ninguna notificación aún. Interactúa con otros para empezar una conversación.",
"empty_column.public": "¡No hay nada aquí! Escribe algo públicamente, o sigue usuarios de otras instancias manualmente para llenarlo.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Público",
"privacy.unlisted.long": "No mostrar en la historia federada",
"privacy.unlisted.short": "Sin federar",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "ahora",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancelar",
"report.placeholder": "Comentarios adicionales",
"report.submit": "Publicar",
@@ -179,6 +183,7 @@
"status.load_more": "Cargar más",
"status.media_hidden": "Contenido multimedia oculto",
"status.mention": "Mencionar",
"status.more": "Más",
"status.mute_conversation": "Silenciar conversación",
"status.open": "Expandir estado",
"status.pin": "Fijar",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "فهرست نوشته‌های محلی خالی است. چیزی بنویسید تا چرخش بچرخد!",
"empty_column.hashtag": "هنوز هیچ چیزی با این هشتگ نیست.",
"empty_column.home": "شما هنوز پیگیر کسی نیستید. {public} را ببینید یا چیزی را جستجو کنید تا کاربران دیگر را ببینید.",
"empty_column.home.inactivity": "فهرست پی‌گیری‌های شما خالی است. اگر مدتی است که غیرفعال بودید، این فهرست به زودی برایتان پر می‌شود.",
"empty_column.home.public_timeline": "فهرست نوشته‌های همه‌جا",
"empty_column.notifications": "هنوز هیچ اعلانی ندارید. به نوشته‌های دیگران واکنش نشان دهید تا گفتگو آغاز شود.",
"empty_column.public": "این‌جا هنوز چیزی نیست! خودتان چیزی بنویسید یا کاربران دیگر را پی بگیرید تا این‌جا پر شود",
@@ -160,6 +159,11 @@
"privacy.public.short": "عمومی",
"privacy.unlisted.long": "عمومی، ولی فهرست نکن",
"privacy.unlisted.short": "فهرست‌نشده",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "لغو",
"report.placeholder": "توضیح اضافه",
"report.submit": "بفرست",
@@ -179,6 +183,7 @@
"status.load_more": "بیشتر نشان بده",
"status.media_hidden": "تصویر پنهان شده",
"status.mention": "نام‌بردن از @{name}",
"status.more": "More",
"status.mute_conversation": "بی‌صداکردن گفتگو",
"status.open": "این نوشته را باز کن",
"status.pin": "نوشتهٔ ثابت نمایه",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Peruuta",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mainitse @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -63,7 +63,7 @@
"confirmations.mute.message": "Confirmez-vous le masquage de {name}?",
"confirmations.unfollow.confirm": "Ne plus suivre",
"confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name}?",
"embed.instructions": "Intégrez ce statut à votre site en copiant ce code ci-dessous.",
"embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.",
"embed.preview": "Il apparaîtra comme cela:",
"emoji_button.activity": "Activités",
"emoji_button.custom": "Personnalisés",
@@ -82,7 +82,6 @@
"empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir!",
"empty_column.hashtag": "Il ny a encore aucun contenu associé à ce hashtag",
"empty_column.home": "Vous ne suivez encore personne. Visitez {public} ou bien utilisez la recherche pour vous connecter à dautres utilisateur⋅ice⋅s.",
"empty_column.home.inactivity": "Votre accueil est vide. Si vous ne vous êtes pas connecté⋅e depuis un moment, il se remplira automatiquement très bientôt.",
"empty_column.home.public_timeline": "le fil public",
"empty_column.notifications": "Vous navez pas encore de notification. Interagissez avec dautres utilisateur⋅ice⋅s pour débuter la conversation.",
"empty_column.public": "Il ny a rien ici! Écrivez quelque chose publiquement, ou bien suivez manuellement des utilisateur⋅ice⋅s dautres instances pour remplir le fil public.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Ne pas afficher dans les fils publics",
"privacy.unlisted.short": "Non-listé",
"relative_time.days": "{number} j",
"relative_time.hours": "{number} h",
"relative_time.just_now": "à linstant",
"relative_time.minutes": "{number} min",
"relative_time.seconds": "{number} s",
"reply_indicator.cancel": "Annuler",
"report.placeholder": "Commentaires additionnels",
"report.submit": "Envoyer",
@@ -179,6 +183,7 @@
"status.load_more": "Charger plus",
"status.media_hidden": "Média caché",
"status.mention": "Mentionner",
"status.more": "Plus",
"status.mute_conversation": "Masquer la conversation",
"status.open": "Déplier ce statut",
"status.pin": "Épingler sur le profil",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
"empty_column.hashtag": "אין כלום בהאשתג הזה עדיין.",
"empty_column.home": "אף אחד לא במעקב עדיין. אפשר לבקר ב{public} או להשתמש בחיפוש כדי להתחיל ולהכיר חצוצרנים אחרים.",
"empty_column.home.inactivity": "ציר זמן הבית שלך ריק. אם לא הייתה פעילות מצידך לאחרונה, הוא יתמלא מחדש בקרוב.",
"empty_column.home.public_timeline": "ציר זמן בין-קהילתי",
"empty_column.notifications": "אין התראות עדיין. יאללה, הגיע הזמן להתחיל להתערבב!",
"empty_column.public": "אין פה כלום! כדי למלא את הטור הזה אפשר לכתוב משהו, או להתחיל לעקוב אחרי אנשים מקהילות אחרות.",
@@ -160,6 +159,11 @@
"privacy.public.short": "פומבי",
"privacy.unlisted.long": "לא יופיע בפידים הציבוריים המשותפים",
"privacy.unlisted.short": "לא לפיד הכללי",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "ביטול",
"report.placeholder": "הערות נוספות",
"report.submit": "שליחה",
@@ -179,6 +183,7 @@
"status.load_more": "עוד",
"status.media_hidden": "מדיה מוסתרת",
"status.mention": "פניה אל @{name}",
"status.more": "More",
"status.mute_conversation": "השתקת שיחה",
"status.open": "הרחבת הודעה",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!",
"empty_column.hashtag": "Još ne postoji ništa s ovim hashtagom.",
"empty_column.home": "Još ne slijediš nikoga. Posjeti {public} ili koristi tražilicu kako bi počeo i upoznao druge korisnike.",
"empty_column.home.inactivity": "Tvoj home feed je prazan. Ako si neko vrijeme bio neaktivan, uskoro ćese regenerirati.",
"empty_column.home.public_timeline": "javni timeline",
"empty_column.notifications": "Još nemaš notifikacija. Komuniciraj sa drugima kako bi započeo razgovor.",
"empty_column.public": "Ovdje nema ništa! Napiši nešto javno, ili ručno slijedi korisnike sa drugih instanci kako bi popunio",
@@ -160,6 +159,11 @@
"privacy.public.short": "Javno",
"privacy.unlisted.long": "Ne prikazuj u javnim timelineovima",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Otkaži",
"report.placeholder": "Dodatni komentari",
"report.submit": "Pošalji",
@@ -179,6 +183,7 @@
"status.load_more": "Učitaj više",
"status.media_hidden": "Sakriven media sadržaj",
"status.mention": "Spomeni @{name}",
"status.more": "More",
"status.mute_conversation": "Utišaj razgovor",
"status.open": "Proširi ovaj status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Mégsem",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Említés",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!",
"empty_column.hashtag": "Tidak ada apapun dalam hashtag ini.",
"empty_column.home": "Anda sedang tidak mengikuti siapapun. Kunjungi {public} atau gunakan pencarian untuk memulai dan bertemu pengguna lain.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "linimasa publik",
"empty_column.notifications": "Anda tidak memiliki notifikasi apapun. Berinteraksi dengan orang lain untuk memulai percakapan.",
"empty_column.public": "Tidak ada apapun disini! Tulis sesuatu, atau ikuti pengguna lain dari server lain untuk mengisinya secara manual",
@@ -160,6 +159,11 @@
"privacy.public.short": "Publik",
"privacy.unlisted.long": "Tidak ditampilkan di linimasa publik",
"privacy.unlisted.short": "Tak Terdaftar",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Batal",
"report.placeholder": "Komentar tambahan",
"report.submit": "Kirim",
@@ -179,6 +183,7 @@
"status.load_more": "Tampilkan semua",
"status.media_hidden": "Media disembunyikan",
"status.mention": "Balasan @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Tampilkan status ini",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "La lokala tempolineo esas vakua. Skribez ulo publike por iniciar la agiveso!",
"empty_column.hashtag": "Esas ankore nulo en ta gretovorto.",
"empty_column.home": "Tu sequas ankore nulu. Vizitez {public} od uzez la serchilo por komencar e renkontrar altra uzeri.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "la publika tempolineo",
"empty_column.notifications": "Tu havas ankore nula savigo. Komunikez kun altri por debutar la konverso.",
"empty_column.public": "Esas nulo hike! Skribez ulo publike, o manuale sequez uzeri de altra instaluri por plenigar ol.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Publike",
"privacy.unlisted.long": "Ne montrar en publika tempolinei",
"privacy.unlisted.short": "Ne enlistigota",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Nihiligar",
"report.placeholder": "Plusa komenti",
"report.submit": "Sendar",
@@ -179,6 +183,7 @@
"status.load_more": "Kargar pluse",
"status.media_hidden": "Kontenajo celita",
"status.mention": "Mencionar @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Detaligar ca mesajo",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!",
"empty_column.hashtag": "Non c'è ancora nessun post con questo hashtag.",
"empty_column.home": "Non stai ancora seguendo nessuno. Visita {public} o usa la ricerca per incontrare nuove persone.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "la timeline pubblica",
"empty_column.notifications": "Non hai ancora nessuna notifica. Interagisci con altri per iniziare conversazioni.",
"empty_column.public": "Qui non c'è nulla! Scrivi qualcosa pubblicamente, o aggiungi utenti da altri server per riempire questo spazio.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Pubblico",
"privacy.unlisted.long": "Non mostrare sulla timeline pubblica",
"privacy.unlisted.short": "Non elencato",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Annulla",
"report.placeholder": "Commenti aggiuntivi",
"report.submit": "Invia",
@@ -179,6 +183,7 @@
"status.load_more": "Mostra di più",
"status.media_hidden": "Allegato nascosto",
"status.mention": "Nomina @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Espandi questo post",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",
"empty_column.hashtag": "このハッシュタグはまだ使われていません。",
"empty_column.home": "まだ誰もフォローしていません。{public}を見に行くか、検索を使って他のユーザーを見つけましょう。",
"empty_column.home.inactivity": "あなたのホームフィードにはなにもありません。あなたがしばらくの間アクティブではなかった場合はすぐ元通りになります。",
"empty_column.home.public_timeline": "連合タイムライン",
"empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
"empty_column.public": "ここにはまだ何もありません!公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう!",
@@ -184,6 +183,7 @@
"status.load_more": "もっと見る",
"status.media_hidden": "非表示のメディア",
"status.mention": "返信",
"status.more": "もっと見る",
"status.mute_conversation": "会話をミュート",
"status.open": "詳細を表示",
"status.pin": "プロフィールに固定表示",

View File

@@ -18,7 +18,7 @@
"account.unblock_domain": "{domain} 숨김 해제",
"account.unfollow": "팔로우 해제",
"account.unmute": "뮤트 해제",
"account.view_full_profile": "View full profile",
"account.view_full_profile": "전체 프로필 보기",
"boost_modal.combo": "다음부터 {combo}를 누르면 이 과정을 건너뛸 수 있습니다.",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",
@@ -33,7 +33,7 @@
"column.home": "홈",
"column.mutes": "뮤트 중인 사용자",
"column.notifications": "알림",
"column.pins": "고정된 Toot",
"column.pins": "고정된 ",
"column.public": "연합 타임라인",
"column_back_button.label": "돌아가기",
"column_header.hide_settings": "Hide settings",
@@ -47,7 +47,7 @@
"compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.",
"compose_form.lock_disclaimer.lock": "비공개",
"compose_form.placeholder": "지금 무엇을 하고 있나요?",
"compose_form.publish": "Toot",
"compose_form.publish": "",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive": "이 미디어를 민감한 미디어로 취급",
"compose_form.spoiler": "텍스트 숨기기",
@@ -63,8 +63,8 @@
"confirmations.mute.message": "정말로 {name}를 뮤트하시겠습니까?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"embed.instructions": "Embed this status on your website by copying the code below.",
"embed.preview": "Here is what it will look like:",
"embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 퍼가세요.",
"embed.preview": "다음과 같이 표시됩니다:",
"emoji_button.activity": "활동",
"emoji_button.custom": "Custom",
"emoji_button.flags": "국기",
@@ -82,7 +82,6 @@
"empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!",
"empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.",
"empty_column.home": "아직 아무도 팔로우 하고 있지 않습니다. {public}를 보러 가거나, 검색하여 다른 사용자를 찾아 보세요.",
"empty_column.home.inactivity": "홈 피드에 아무 것도 없습니다. 한동안 활동하지 않은 경우 곧 원래대로 돌아올 것입니다.",
"empty_column.home.public_timeline": "연합 타임라인",
"empty_column.notifications": "아직 알림이 없습니다. 다른 사람과 대화를 시작해 보세요!",
"empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 인스턴스 유저를 팔로우 해서 가득 채워보세요!",
@@ -113,7 +112,7 @@
"navigation_bar.info": "이 인스턴스에 대해서",
"navigation_bar.logout": "로그아웃",
"navigation_bar.mutes": "뮤트 중인 사용자",
"navigation_bar.pins": "고정된 Toot",
"navigation_bar.pins": "고정된 ",
"navigation_bar.preferences": "사용자 설정",
"navigation_bar.public_timeline": "연합 타임라인",
"notification.favourite": "{name}님이 즐겨찾기 했습니다",
@@ -159,29 +158,35 @@
"privacy.public.long": "공개 타임라인에 표시",
"privacy.public.short": "공개",
"privacy.unlisted.long": "공개 타임라인에 표시하지 않음",
"privacy.unlisted.short": "Unlisted",
"privacy.unlisted.short": "타임라인에 비표시",
"relative_time.days": "{number}일 전",
"relative_time.hours": "{number}시간 전",
"relative_time.just_now": "방금",
"relative_time.minutes": "{number}분 전",
"relative_time.seconds": "{number}초 전",
"reply_indicator.cancel": "취소",
"report.placeholder": "코멘트",
"report.submit": "신고하기",
"report.target": "문제가 된 사용자",
"search.placeholder": "검색",
"search_popout.search_format": "Advanced search format",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user",
"search_popout.search_format": "고급 검색 방법",
"search_popout.tips.hashtag": "해시태그",
"search_popout.tips.status": "",
"search_popout.tips.text": "단순한 텍스트 검색은 관계된 프로필 이름, 유저 이름 그리고 해시태그를 표시합니다",
"search_popout.tips.user": "유저",
"search_results.total": "{count, number}건의 결과",
"standalone.public_title": "A look inside...",
"status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
"status.delete": "삭제",
"status.embed": "Embed",
"status.embed": "공유하기",
"status.favourite": "즐겨찾기",
"status.load_more": "더 보기",
"status.media_hidden": "미디어 숨겨짐",
"status.mention": "답장",
"status.more": "More",
"status.mute_conversation": "이 대화를 뮤트",
"status.open": "상세 정보 표시",
"status.pin": "Pin on profile",
"status.pin": "고정",
"status.reblog": "부스트",
"status.reblogged_by": "{name}님이 부스트 했습니다",
"status.reply": "답장",
@@ -193,7 +198,7 @@
"status.show_less": "숨기기",
"status.show_more": "더 보기",
"status.unmute_conversation": "이 대화의 뮤트 해제하기",
"status.unpin": "Unpin from profile",
"status.unpin": "고정 해제",
"tabs_bar.compose": "포스트",
"tabs_bar.federated_timeline": "연합",
"tabs_bar.home": "홈",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "De lokale tijdlijn is nog leeg. Toot iets in het openbaar om de bal aan het rollen te krijgen!",
"empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.",
"empty_column.home": "Jij volgt nog niemand. Bezoek {public} of gebruik het zoekvenster om andere mensen te ontmoeten.",
"empty_column.home.inactivity": "Deze tijdlijn is leeg. Wanneer je een tijdje inactief bent geweest wordt deze snel opnieuw aangemaakt.",
"empty_column.home.public_timeline": "de globale tijdlijn",
"empty_column.notifications": "Je hebt nog geen meldingen. Heb interactie met andere mensen om het gesprek aan te gaan.",
"empty_column.public": "Er is hier helemaal niks! Toot iets in het openbaar of volg mensen van andere Mastodon-servers om het te vullen.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Openbaar",
"privacy.unlisted.long": "Niet op openbare tijdlijnen tonen",
"privacy.unlisted.short": "Minder openbaar",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Annuleren",
"report.placeholder": "Extra opmerkingen",
"report.submit": "Verzenden",
@@ -179,6 +183,7 @@
"status.load_more": "Meer laden",
"status.media_hidden": "Media verborgen",
"status.mention": "Vermeld @{name}",
"status.more": "Meer",
"status.mute_conversation": "Negeer conversatie",
"status.open": "Toot volledig tonen",
"status.pin": "Aan profielpagina vastmaken",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Den lokale tidslinjen er tom. Skriv noe offentlig for å få snøballen til å rulle!",
"empty_column.hashtag": "Det er ingenting i denne hashtagen ennå.",
"empty_column.home": "Du har ikke fulgt noen ennå. Besøk {publlic} eller bruk søk for å komme i gang og møte andre brukere.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "en offentlig tidslinje",
"empty_column.notifications": "Du har ingen varsler ennå. Kommuniser med andre for å begynne samtalen.",
"empty_column.public": "Det er ingenting her! Skriv noe offentlig, eller følg brukere manuelt fra andre instanser for å fylle den opp",
@@ -160,6 +159,11 @@
"privacy.public.short": "Offentlig",
"privacy.unlisted.long": "Ikke vis i offentlige tidslinjer",
"privacy.unlisted.short": "Uoppført",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Avbryt",
"report.placeholder": "Tilleggskommentarer",
"report.submit": "Send inn",
@@ -179,6 +183,7 @@
"status.load_more": "Last mer",
"status.media_hidden": "Media skjult",
"status.mention": "Nevn @{name}",
"status.more": "More",
"status.mute_conversation": "Demp samtale",
"status.open": "Utvid denne statusen",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir!",
"empty_column.hashtag": "I a pas encara de contengut ligat a aqueste hashtag",
"empty_column.home": "Vòstre flux dacuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a dautras personas.",
"empty_column.home.inactivity": "Vòstra pagina dacuèlh es voida. Se sètz estat inactiu per un moment, serà tornada generar per vos dins una estona.",
"empty_column.home.public_timeline": "lo flux public",
"empty_column.notifications": "Avètz pas encara de notificacions. Respondètz a qualquun per començar una conversacion.",
"empty_column.public": "I a pas res aquí! Escrivètz quicòm de public, o seguètz de personas dautras instàncias per garnir lo flux public.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Mostrar pas dins los fluxes publics",
"privacy.unlisted.short": "Pas-listat",
"relative_time.days": "fa {number}j",
"relative_time.hours": "fa {number}h",
"relative_time.just_now": "ara",
"relative_time.minutes": "fa {number} minutas",
"relative_time.seconds": "fa {number} segondas",
"reply_indicator.cancel": "Anullar",
"report.placeholder": "Comentaris addicionals",
"report.submit": "Mandar",
@@ -179,6 +183,7 @@
"status.load_more": "Cargar mai",
"status.media_hidden": "Mèdia rescondut",
"status.mention": "Mencionar",
"status.more": "Mai",
"status.mute_conversation": "Rescondre la conversacion",
"status.open": "Desplegar aqueste estatut",
"status.pin": "Penjar al perfil",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Lokalna oś czasu jest pusta. Napisz coś publicznie, aby zagaić!",
"empty_column.hashtag": "Nie ma wpisów oznaczonych tym hashtagiem. Możesz napisać pierwszy!",
"empty_column.home": "Nie śledzisz nikogo. Odwiedź publiczną oś czasu lub użyj wyszukiwarki, aby znaleźć interesujące Cię profile.",
"empty_column.home.inactivity": "Strumień jest pusty. Jeżeli nie było Cię tu ostatnio, zostanie on wypełniony wkrótce.",
"empty_column.home.public_timeline": "publiczna oś czasu",
"empty_column.notifications": "Nie masz żadnych powiadomień. Rozpocznij interakcje z innymi użytkownikami.",
"empty_column.public": "Tu nic nie ma! Napisz coś publicznie, lub dodaj ludzi z innych instancji, aby to wyświetlić.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Publiczny",
"privacy.unlisted.long": "Niewidoczny na publicznych osiach czasu",
"privacy.unlisted.short": "Niewidoczny",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Anuluj",
"report.placeholder": "Dodatkowe komentarze",
"report.submit": "Wyślij",
@@ -179,6 +183,7 @@
"status.load_more": "Załaduj więcej",
"status.media_hidden": "Zawartość multimedialna ukryta",
"status.mention": "Wspomnij o @{name}",
"status.more": "Więcej",
"status.mute_conversation": "Wycisz konwersację",
"status.open": "Rozszerz ten wpis",
"status.pin": "Przypnij do profilu",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "A timeline local está vazia. Escreva algo publicamente para começar!",
"empty_column.hashtag": "Ainda não há qualquer conteúdo com essa hashtag",
"empty_column.home": "Você ainda não segue usuário algo. Visite a timeline {public} ou use o buscador para procurar e conhecer outros usuários.",
"empty_column.home.inactivity": "A sua página inicial está vazia. Se você esteve inativo por um tempo, ela irá se regenerar em alguns intantes.",
"empty_column.home.public_timeline": "global",
"empty_column.notifications": "Você ainda não possui notificações. Interaja com outros usuários para começar a conversar!",
"empty_column.public": "Não há nada aqui! Escreva algo publicamente ou siga manualmente usuários de outras instâncias.",
@@ -160,16 +159,21 @@
"privacy.public.short": "Pública",
"privacy.unlisted.long": "Não publicar em feeds públicos",
"privacy.unlisted.short": "Não listada",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancelar",
"report.placeholder": "Comentários adicionais",
"report.submit": "Enviar",
"report.target": "Denunciar",
"search.placeholder": "Pesquisar",
"search_popout.search_format": "Advanced search format",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.search_format": "Formato de busca avançado",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Texto simples retorna nomes de exibição, usuários e hashtags correspondentes",
"search_popout.tips.user": "user",
"search_popout.tips.user": "usuário",
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
"standalone.public_title": "Dê uma espiada...",
"status.cannot_reblog": "Esta postagem não pode ser compartilhada",
@@ -179,6 +183,7 @@
"status.load_more": "Carregar mais",
"status.media_hidden": "Mídia escondida",
"status.mention": "Mencionar @{name}",
"status.more": "More",
"status.mute_conversation": "Silenciar conversa",
"status.open": "Expandir",
"status.pin": "Fixar no perfil",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Ainda não existem conteúdo local para mostrar!",
"empty_column.hashtag": "Ainda não existe qualquer conteúdo com essa hashtag",
"empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "global",
"empty_column.notifications": "Não tens notificações. Interage com outros utilizadores para iniciar uma conversa.",
"empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para ver aqui os conteúdos públicos.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Público",
"privacy.unlisted.long": "Não publicar nos feeds públicos",
"privacy.unlisted.short": "Não listar",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancelar",
"report.placeholder": "Comentários adicionais",
"report.submit": "Enviar",
@@ -179,6 +183,7 @@
"status.load_more": "Carregar mais",
"status.media_hidden": "Media escondida",
"status.mention": "Mencionar @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expandir",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
"empty_column.hashtag": "Статусов с таким хэштегом еще не существует.",
"empty_column.home": "Пока Вы ни на кого не подписаны. Полистайте {public} или используйте поиск, чтобы освоиться и завести новые знакомства.",
"empty_column.home.inactivity": "Ваша домашняя лента пуста. Если Вы некоторое время были неактивны, она будет сгенерирована для Вас в ближайшее время.",
"empty_column.home.public_timeline": "публичные ленты",
"empty_column.notifications": "У Вас еще нет уведомлений. Заведите знакомство с другими пользователями, чтобы начать разговор.",
"empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Публичный",
"privacy.unlisted.long": "Не показывать в лентах",
"privacy.unlisted.short": "Скрытый",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Отмена",
"report.placeholder": "Комментарий",
"report.submit": "Отправить",
@@ -179,6 +183,7 @@
"status.load_more": "Показать еще",
"status.media_hidden": "Медиаконтент скрыт",
"status.mention": "Упомянуть @{name}",
"status.more": "More",
"status.mute_conversation": "Заглушить тред",
"status.open": "Развернуть статус",
"status.pin": "Pin on profile",

View File

@@ -0,0 +1,217 @@
{
"account.block": "Blockera @{name}",
"account.block_domain": "Dölj allt från {domain}",
"account.disclaimer_full": "Informationen nedan kan spegla användarens profil ofullständigt.",
"account.edit_profile": "Redigera profil",
"account.follow": "Följ",
"account.followers": "Följare",
"account.follows": "Följer",
"account.follows_you": "Följer dig",
"account.media": "Media",
"account.mention": "Nämna @{name}",
"account.mute": "Tysta @{name}",
"account.posts": "Inlägg",
"account.report": "Rapportera @{name}",
"account.requested": "Inväntar godkännande. Klicka för att avbryta följförfrågan",
"account.share": "Dela @{name}'s profil",
"account.unblock": "Avblockera @{name}",
"account.unblock_domain": "Ta fram {domain}",
"account.unfollow": "Sluta följa",
"account.unmute": "Ta bort tystad @{name}",
"account.view_full_profile": "Visa hela profilen",
"boost_modal.combo": "Du kan trycka {combo} för att slippa denna nästa gång",
"bundle_column_error.body": "Något gick fel när du laddade denna komponent.",
"bundle_column_error.retry": "Försök igen",
"bundle_column_error.title": "Nätverksfel",
"bundle_modal_error.close": "Stäng",
"bundle_modal_error.message": "Något gick fel när du laddade denna komponent.",
"bundle_modal_error.retry": "Försök igen",
"column.blocks": "Blockerade användare",
"column.community": "Lokal tidslinje",
"column.favourites": "Favoriter",
"column.follow_requests": "Följ förfrågningar",
"column.home": "Hem",
"column.mutes": "Tystade användare",
"column.notifications": "Meddelanden",
"column.pins": "Nålade toots",
"column.public": "Förenad tidslinje",
"column_back_button.label": "Tillbaka",
"column_header.hide_settings": "Dölj inställningar",
"column_header.moveLeft_settings": "Flytta kolumnen till vänster",
"column_header.moveRight_settings": "Flytta kolumnen till höger",
"column_header.pin": "Fäst",
"column_header.show_settings": "Visa inställningar",
"column_header.unpin": "Ångra fäst",
"column_subheading.navigation": "Navigation",
"column_subheading.settings": "Inställningar",
"compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vemsomhelst kan följa dig och även se dina inlägg skrivna för endast dina följare.",
"compose_form.lock_disclaimer.lock": "låst",
"compose_form.placeholder": "Vad funderar du på?",
"compose_form.publish": "Toot",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive": "Markera media som känslig",
"compose_form.spoiler": "Dölj text bakom varning",
"compose_form.spoiler_placeholder": "Skriv din varning här",
"confirmation_modal.cancel": "Ångra",
"confirmations.block.confirm": "Blockera",
"confirmations.block.message": "Är du säker att du vill blockera {name}?",
"confirmations.delete.confirm": "Ta bort",
"confirmations.delete.message": "Är du säker att du vill ta bort denna status?",
"confirmations.domain_block.confirm": "Blockera hela domänen",
"confirmations.domain_block.message": "Är du verkligen, verkligen säker på att du vill blockera hela {domain}? I de flesta fall är några riktade blockeringar eller nedtystade tillräckligt och föredras.",
"confirmations.mute.confirm": "Tysta",
"confirmations.mute.message": "Är du säker du vill tysta ner {name}?",
"confirmations.unfollow.confirm": "Sluta följa",
"confirmations.unfollow.message": "Är du säker på att du vill sluta följa {name}?",
"embed.instructions": "Bädda in den här statusen på din webbplats genom att kopiera koden nedan.",
"embed.preview": "Här ser du hur det kommer att se ut:",
"emoji_button.activity": "Aktivitet",
"emoji_button.custom": "Specialgjord",
"emoji_button.flags": "Flaggor",
"emoji_button.food": "Mat & Dryck",
"emoji_button.label": "Lägg till emoji",
"emoji_button.nature": "Natur",
"emoji_button.not_found": "Inga emojos!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objekt",
"emoji_button.people": "Människor",
"emoji_button.recent": "Ofta använda",
"emoji_button.search": "Sök...",
"emoji_button.search_results": "Sökresultat",
"emoji_button.symbols": "Symboler",
"emoji_button.travel": "Resor & Platser",
"empty_column.community": "Den lokala tidslinjen är tom. Skriv något offentligt för att få bollen att rulla!",
"empty_column.hashtag": "Det finns inget i denna hashtag ännu.",
"empty_column.home": "Din hemma-tidslinje är tom! Besök {public} eller använd sökning för att komma igång och träffa andra användare.",
"empty_column.home.inactivity": "Ditt hemmafeed är tomt. Om du har varit inaktiv ett tag kommer det att regenereras för dig snart.",
"empty_column.home.public_timeline": "den publika tidslinjen",
"empty_column.notifications": "Du har inga meddelanden än. Interagera med andra för att starta konversationen.",
"empty_column.public": "Det finns inget här! Skriv något offentligt, eller följ manuellt användarna från andra instanser för att fylla på det",
"follow_request.authorize": "Godkänn",
"follow_request.reject": "Avvisa",
"getting_started.appsshort": "Appar",
"getting_started.faq": "FAQ",
"getting_started.heading": "Kom igång",
"getting_started.open_source_notice": "Mastodon är programvara med öppen källkod. Du kan bidra eller rapportera problem på GitHub på {github}.",
"getting_started.userguide": "Användarguide",
"home.column_settings.advanced": "Avancerad",
"home.column_settings.basic": "Grundläggande",
"home.column_settings.filter_regex": "Filtrera ut med regelbundna uttryck",
"home.column_settings.show_reblogs": "Visa knuffar",
"home.column_settings.show_replies": "Visa svar",
"home.settings": "Kolumninställningar",
"lightbox.close": "Stäng",
"lightbox.next": "Nästa",
"lightbox.previous": "Tidigare",
"loading_indicator.label": "Laddar...",
"media_gallery.toggle_visible": "Växla synlighet",
"missing_indicator.label": "Hittades inte",
"navigation_bar.blocks": "Blockerade användare",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.edit_profile": "Redigera profil",
"navigation_bar.favourites": "Favoriter",
"navigation_bar.follow_requests": "Följförfrågningar",
"navigation_bar.info": "Om denna instans",
"navigation_bar.logout": "Logga ut",
"navigation_bar.mutes": "Tystade användare",
"navigation_bar.pins": "Nålade inlägg (toots)",
"navigation_bar.preferences": "Inställningar",
"navigation_bar.public_timeline": "Förenad tidslinje",
"notification.favourite": "{name} favoriserade din status",
"notification.follow": "{name} följer dig",
"notification.mention": "{name} nämnde dig",
"notification.reblog": "{name} knuffade din status",
"notifications.clear": "Rensa meddelanden",
"notifications.clear_confirmation": "Är du säker på att du vill radera alla dina meddelanden permanent?",
"notifications.column_settings.alert": "Skrivbordsmeddelanden",
"notifications.column_settings.favourite": "Favoriter:",
"notifications.column_settings.follow": "Nya följare:",
"notifications.column_settings.mention": "Omnämningar:",
"notifications.column_settings.push": "Push meddelanden",
"notifications.column_settings.push_meta": "Denna anordning",
"notifications.column_settings.reblog": "Knuffar:",
"notifications.column_settings.show": "Visa i kolumnen",
"notifications.column_settings.sound": "Spela upp ljud",
"onboarding.done": "Klart",
"onboarding.next": "Nästa",
"onboarding.page_five.public_timelines": "Den lokala tidslinjen visar offentliga inlägg från alla på {domain}. Den förenade tidslinjen visar offentliga inlägg från alla personer på {domain} som följer. Dom här offentliga tidslinjerna är ett bra sätt att upptäcka nya människor.",
"onboarding.page_four.home": "Hemmatidslinjen visar inlägg från personer du följer.",
"onboarding.page_four.notifications": "Meddelandekolumnen visar när någon interagerar med dig.",
"onboarding.page_one.federation": "Mastodon är ett nätverk av oberoende servrar som ansluter för att skapa ett större socialt nätverk. Vi kallar dessa servrar instanser.",
"onboarding.page_one.handle": "Du är på {domain}, så din fulla hantering är {handle}",
"onboarding.page_one.welcome": "Välkommen till Mastodon!",
"onboarding.page_six.admin": "Din instansadmin är {admin}.",
"onboarding.page_six.almost_done": "Snart klart...",
"onboarding.page_six.appetoot": "Bon Appetoot!",
"onboarding.page_six.apps_available": "Det finns {apps} tillgängligt för iOS, Android och andra plattformar.",
"onboarding.page_six.github": "Mastodon är fri programvara med öppen källkod. Du kan rapportera fel, efterfråga funktioner eller bidra till koden på {github}.",
"onboarding.page_six.guidelines": "gemenskapsriktlinjer",
"onboarding.page_six.read_guidelines": "Vänligen läs {domain}'s {guidelines}!",
"onboarding.page_six.various_app": "mobilappar",
"onboarding.page_three.profile": "Redigera din profil för att ändra ditt avatar, bio och visningsnamn. Där hittar du även andra inställningar.",
"onboarding.page_three.search": "Använd sökfältet för att hitta personer och titta på hashtags, till exempel {illustration} och {introductions}. För att leta efter en person som inte befinner sig i detta fall använd deras fulla handhavande.",
"onboarding.page_two.compose": "Skriv inlägg från skrivkolumnen. Du kan ladda upp bilder, ändra integritetsinställningar och lägga till varningar med ikonerna nedan.",
"onboarding.skip": "Hoppa över",
"privacy.change": "Justera status sekretess",
"privacy.direct.long": "Skicka endast till nämnda användare",
"privacy.direct.short": "Direkt",
"privacy.private.long": "Skicka endast till följare",
"privacy.private.short": "Endast följare",
"privacy.public.long": "Skicka till publik tidslinje",
"privacy.public.short": "Publik",
"privacy.unlisted.long": "Skicka inte till publik tidslinje",
"privacy.unlisted.short": "Olistad",
"reply_indicator.cancel": "Ångra",
"report.placeholder": "Ytterligare kommentarer",
"report.submit": "Skicka",
"report.target": "Rapporterar {target}",
"search.placeholder": "Sök",
"search_popout.search_format": "Avancerat sökformat",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Enkel text returnerar matchande visningsnamn, användarnamn och hashtags",
"search_popout.tips.user": "användare",
"search_results.total": "{count, number} {count, plural, ett {result} andra {results}}",
"standalone.public_title": "En titt inuti...",
"status.cannot_reblog": "Detta inlägg kan inte knuffas",
"status.delete": "Ta bort",
"status.embed": "Bädda in",
"status.favourite": "Favorit",
"status.load_more": "Ladda fler",
"status.media_hidden": "Media dold",
"status.mention": "Omnämn @{name}",
"status.mute_conversation": "Tysta konversation",
"status.open": "Utvidga denna status",
"status.pin": "Fäst i profil",
"status.reblog": "Knuff",
"status.reblogged_by": "{name} knuffade",
"status.reply": "Svara",
"status.replyAll": "Svara på tråden",
"status.report": "Rapportera @{name}",
"status.sensitive_toggle": "Klicka för att se",
"status.sensitive_warning": "Känsligt innehåll",
"status.share": "Dela",
"status.show_less": "Visa mindre",
"status.show_more": "Visa mer",
"status.unmute_conversation": "Öppna konversation",
"status.unpin": "Ångra fäst i profil",
"tabs_bar.compose": "Skriv",
"tabs_bar.federated_timeline": "Förenad",
"tabs_bar.home": "Hem",
"tabs_bar.local_timeline": "Lokal",
"tabs_bar.notifications": "Meddelanden",
"upload_area.title": "Dra & släpp för att ladda upp",
"upload_button.label": "Lägg till media",
"upload_form.description": "Beskriv för synskadade",
"upload_form.undo": "Ångra",
"upload_progress.label": "Laddar upp...",
"video.close": "Stäng video",
"video.exit_fullscreen": "Stäng helskärm",
"video.expand": "Expandera video",
"video.fullscreen": "Helskärm",
"video.hide": "Dölj video",
"video.mute": "Tysta ljud",
"video.pause": "Pause",
"video.play": "Spela upp",
"video.unmute": "Spela upp ljud"
}

View File

@@ -82,7 +82,6 @@
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
@@ -160,6 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not post to public timelines",
"privacy.unlisted.short": "Unlisted",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
@@ -179,6 +183,7 @@
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Yerel zaman tüneliniz boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın.",
"empty_column.hashtag": "Henüz bu hashtage sahip hiçbir gönderi yok.",
"empty_column.home": "Henüz kimseyi takip etmiyorsunuz. {public} ziyaret edebilir veya arama kısmını kullanarak diğer kullanıcılarla iletişime geçebilirsiniz.",
"empty_column.home.inactivity": "Your home feed is empty. If you have been inactive for a while, it will be regenerated for you soon.",
"empty_column.home.public_timeline": "herkese açık zaman tüneli",
"empty_column.notifications": "Henüz hiçbir bildiriminiz yok. Diğer insanlarla sobhet edebilmek için etkileşime geçebilirsiniz.",
"empty_column.public": "Burada hiçbir gönderi yok! Herkese açık bir şeyler yazın, veya diğer sunucudaki insanları takip ederek bu alanın dolmasını sağlayın",
@@ -160,6 +159,11 @@
"privacy.public.short": "Herkese açık",
"privacy.unlisted.long": "Herkese açık zaman tüneline gönderme",
"privacy.unlisted.short": "Listelenmemiş",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "İptal",
"report.placeholder": "Ek yorumlar",
"report.submit": "Gönder",
@@ -179,6 +183,7 @@
"status.load_more": "Daha fazla",
"status.media_hidden": "Gizli görsel",
"status.mention": "Bahset @{name}",
"status.more": "More",
"status.mute_conversation": "Mute conversation",
"status.open": "Bu gönderiyi genişlet",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",
"empty_column.hashtag": "Дописів з цим хештегом поки не існує.",
"empty_column.home": "Ви поки ні на кого не підписані. Погортайте {public}, або скористуйтесь пошуком, щоб освоїтися та познайомитися з іншими користувачами.",
"empty_column.home.inactivity": "Ваша домашня стрічка пуста. Якщо ви були неактивні протягом деякого часу, вона скоро буде згенерована для Вас.",
"empty_column.home.public_timeline": "публічні стрічки",
"empty_column.notifications": "У вас ще немає сповіщень. Переписуйтесь з іншими користувачами, щоб почати розмову.",
"empty_column.public": "Тут поки нічого немає! Опублікуйте щось, або вручну підпишіться на користувачів інших інстанцій, щоб заповнити стрічку.",
@@ -160,6 +159,11 @@
"privacy.public.short": "Публічний",
"privacy.unlisted.long": "Не показувати у публічних стрічках",
"privacy.unlisted.short": "Прихований",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Відмінити",
"report.placeholder": "Додаткові коментарі",
"report.submit": "Відправити",
@@ -179,6 +183,7 @@
"status.load_more": "Завантажити більше",
"status.media_hidden": "Медіаконтент приховано",
"status.mention": "Згадати",
"status.more": "More",
"status.mute_conversation": "Заглушити діалог",
"status.open": "Розгорнути допис",
"status.pin": "Pin on profile",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "本站时间轴暂时未有内容,快嘟几个来抢头香啊!",
"empty_column.hashtag": "这个标签暂时未有内容。",
"empty_column.home": "你还没有关注任何用户。快看看{public},向其他用户搭讪吧。",
"empty_column.home.inactivity": "你的主页暂时没有内容。也许你太久没有来了?如果是这样,文章会慢慢出来,请稍后再看。",
"empty_column.home.public_timeline": "公共时间轴",
"empty_column.notifications": "你没有任何通知纪录,快向其他用户搭讪吧。",
"empty_column.public": "跨站公共时间轴暂时没有内容!快写一些公共的嘟文,或者关注另一些服务器实例的用户吧!你和本站、友站的交流,将决定这里出现的内容。",
@@ -160,6 +159,11 @@
"privacy.public.short": "公共",
"privacy.unlisted.long": "公开,但不在公共时间轴显示",
"privacy.unlisted.short": "公开",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "取消",
"report.placeholder": "额外消息",
"report.submit": "提交",
@@ -179,6 +183,7 @@
"status.load_more": "加载更多",
"status.media_hidden": "隐藏媒体内容",
"status.mention": "提及 @{name}",
"status.more": "More",
"status.mute_conversation": "静音对话",
"status.open": "展开嘟文",
"status.pin": "置顶到资料",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "本站時間軸暫時未有內容,快文章來搶頭香啊!",
"empty_column.hashtag": "這個標籤暫時未有內容。",
"empty_column.home": "你還沒有關注任何用戶。快看看{public},向其他用戶搭訕吧。",
"empty_column.home.inactivity": "你的主頁暫時沒有內容。也許你太久沒有來?如果是這樣,文章會慢慢出來,請稍後再看。",
"empty_column.home.public_timeline": "公共時間軸",
"empty_column.notifications": "你沒有任何通知紀錄,快向其他用戶搭訕吧。",
"empty_column.public": "跨站時間軸暫時沒有內容!快寫一些公共的文章,或者關注另一些服務站的用戶吧!你和本站、友站的交流,將決定這裏出現的內容。",
@@ -160,6 +159,11 @@
"privacy.public.short": "公共",
"privacy.unlisted.long": "公開,但不在公共時間軸顯示",
"privacy.unlisted.short": "公開",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "取消",
"report.placeholder": "額外訊息",
"report.submit": "提交",
@@ -179,6 +183,7 @@
"status.load_more": "載入更多",
"status.media_hidden": "隱藏媒體內容",
"status.mention": "提及 @{name}",
"status.more": "More",
"status.mute_conversation": "靜音對話",
"status.open": "展開文章",
"status.pin": "置頂到資料頁",

View File

@@ -82,7 +82,6 @@
"empty_column.community": "本地時間軸是空的。公開寫點什麼吧!",
"empty_column.hashtag": "這個主題標籤下什麼都沒有。",
"empty_column.home": "你還沒關注任何人。造訪{public}或利用搜尋功能找到其他用者。",
"empty_column.home.inactivity": "你家的訊息摘要是空的。如果你很久沒活動了,很快它就會重新產生。",
"empty_column.home.public_timeline": "公開時間軸",
"empty_column.notifications": "還沒有任何通知。和別的使用者互動來開始對話。",
"empty_column.public": "這裡什麼都沒有!公開寫些什麼,或是關注其他副本的使用者。",
@@ -160,6 +159,11 @@
"privacy.public.short": "公開貼",
"privacy.unlisted.long": "不要貼到公開時間軸",
"privacy.unlisted.short": "不列出來",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "取消",
"report.placeholder": "更多訊息",
"report.submit": "送出",
@@ -179,6 +183,7 @@
"status.load_more": "載入更多",
"status.media_hidden": "媒體已隱藏",
"status.mention": "提到 @{name}",
"status.more": "More",
"status.mute_conversation": "消音對話",
"status.open": "展開這個狀態",
"status.pin": "置頂到個人資訊頁",

View File

@@ -1,6 +1,5 @@
import * as OfflinePluginRuntime from 'offline-plugin/runtime';
import * as WebPushSubscription from './web_push_subscription';
import Mastodon from 'mastodon/containers/mastodon';
import Mastodon from './containers/mastodon';
import React from 'react';
import ReactDOM from 'react-dom';
import ready from './ready';
@@ -25,7 +24,7 @@ function main() {
ReactDOM.render(<Mastodon {...props} />, mountNode);
if (process.env.NODE_ENV === 'production') {
// avoid offline in dev mode because it's harder to debug
OfflinePluginRuntime.install();
require('offline-plugin/runtime').install();
WebPushSubscription.register();
}
perf.stop('main()');

View File

@@ -12,7 +12,11 @@ const createAudio = sources => {
const play = audio => {
if (!audio.paused) {
audio.pause();
if (typeof audio.fastSeek === 'function') {
audio.fastSeek(0);
} else {
audio.seek(0);
}
}
audio.play();

View File

@@ -31,10 +31,10 @@ const initialTimeline = ImmutableMap({
});
const normalizeTimeline = (state, timeline, statuses, next) => {
const ids = ImmutableList(statuses.map(status => status.get('id')));
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
const wasLoaded = state.getIn([timeline, 'loaded']);
const hadNext = state.getIn([timeline, 'next']);
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
mMap.set('loaded', true);
@@ -45,8 +45,8 @@ const normalizeTimeline = (state, timeline, statuses, next) => {
};
const appendNormalizedTimeline = (state, timeline, statuses, next) => {
const ids = ImmutableList(statuses.map(status => status.get('id')));
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
mMap.set('isLoading', false);
@@ -75,15 +75,9 @@ const updateTimeline = (state, timeline, status, references) => {
}));
};
const deleteStatus = (state, id, accountId, references, reblogOf) => {
const deleteStatus = (state, id, accountId, references) => {
state.keySeq().forEach(timeline => {
state = state.updateIn([timeline, 'items'], list => {
if (reblogOf && !list.includes(reblogOf)) {
return list.map(item => item === id ? reblogOf : item);
} else {
return list.filterNot(item => item === id);
}
});
state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
});
// Remove reblogs of deleted status

View File

@@ -0,0 +1,5 @@
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
const adapter = new Adapter();
configure({ adapter });

View File

@@ -2,7 +2,8 @@ import loadPolyfills from '../mastodon/load_polyfills';
// import default stylesheet with variables
require('font-awesome/css/font-awesome.css');
import 'styles/application';
import '../styles/application.scss';
require.context('../images/', true);

View File

@@ -1,6 +1,9 @@
import { start } from 'rails-ujs';
import 'font-awesome/css/font-awesome.css';
// import common styling
require('../styles/common.scss');
require.context('../images/', true);
start();

View File

@@ -1,20 +1,23 @@
@import 'mixins';
@import 'variables';
@import 'mastodon/mixins';
@import 'mastodon/variables';
@import 'variables-glitch';
@import 'fonts/roboto';
@import 'fonts/roboto-mono';
@import 'fonts/montserrat';
@import 'reset';
@import 'basics';
@import 'containers';
@import 'lists';
@import 'footer';
@import 'compact_header';
@import 'landing_strip';
@import 'forms';
@import 'accounts';
@import 'stream_entries';
@import 'components';
@import 'emoji_picker';
@import 'about';
@import 'tables';
@import 'admin';
@import 'rtl';
@import 'mastodon/reset';
@import 'mastodon/basics';
@import 'mastodon/containers';
@import 'mastodon/lists';
@import 'mastodon/footer';
@import 'mastodon/compact_header';
@import 'mastodon/landing_strip';
@import 'mastodon/forms';
@import 'mastodon/accounts';
@import 'mastodon/stream_entries';
@import 'mastodon/components';
@import 'mastodon/emoji_picker';
@import 'mastodon/about';
@import 'mastodon/tables';
@import 'mastodon/admin';
@import 'mastodon/rtl';

View File

@@ -30,7 +30,7 @@ body {
}
&.app-body {
position: fixed;
position: absolute;
width: 100%;
height: 100%;
padding: 0;

View File

@@ -302,7 +302,6 @@
font-family: inherit;
font-size: 14px;
background: $simple-background-color;
border-radius: 0 0 4px;
}
.compose-form__buttons-wrapper {
@@ -452,6 +451,7 @@
.compose-form__publish {
display: flex;
justify-content: flex-end;
min-width: 0;
}
@@ -468,7 +468,7 @@
.compose-form__publish__side-arm {
padding: 0 !important;
width: 4em;
width: 36px;
text-align: center;
margin-right: 2px;
}
@@ -551,6 +551,14 @@
overflow: visible;
white-space: pre-wrap;
&.status__content--with-spoiler {
white-space: normal;
.status__content__text {
white-space: pre-wrap;
}
}
.emojione {
width: 18px;
height: 18px;

Some files were not shown because too many files have changed in this diff Show More