diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 01c6314c9..cdf22dd2e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,6 +25,7 @@ deps:
cache:
<<: *cache
policy: push
+ interruptible: true
danger:
stage: test
@@ -33,6 +34,7 @@ danger:
- export CI_MERGE_REQUEST_IID=${CI_OPEN_MERGE_REQUESTS#*!}
- npx danger ci
allow_failure: true
+ interruptible: true
lint-js:
stage: test
@@ -45,6 +47,7 @@ lint-js:
- "**/*.tsx"
- ".eslintignore"
- ".eslintrc.js"
+ interruptible: true
lint-sass:
stage: test
@@ -54,6 +57,7 @@ lint-sass:
- "**/*.scss"
- "**/*.css"
- ".stylelintrc.json"
+ interruptible: true
jest:
stage: test
@@ -76,6 +80,7 @@ jest:
coverage_report:
coverage_format: cobertura
path: .coverage/cobertura-coverage.xml
+ interruptible: true
nginx-test:
stage: test
@@ -85,6 +90,7 @@ nginx-test:
only:
changes:
- "installation/mastodon.conf"
+ interruptible: true
build-production:
stage: test
@@ -94,6 +100,7 @@ build-production:
artifacts:
paths:
- static
+ interruptible: true
docs-deploy:
stage: deploy
@@ -107,6 +114,7 @@ docs-deploy:
- develop
changes:
- "docs/**/*"
+ interruptible: true
# Supposed to fail when translations are outdated, instead always passes
#
@@ -127,6 +135,7 @@ review:
script:
- npx -y surge static $CI_COMMIT_REF_SLUG.git.soapbox.pub
allow_failure: true
+ interruptible: true
pages:
stage: deploy
@@ -142,6 +151,7 @@ pages:
only:
refs:
- develop
+ interruptible: true
docker:
stage: deploy
@@ -157,4 +167,5 @@ docker:
- docker push $CI_REGISTRY_IMAGE
only:
refs:
- - develop
\ No newline at end of file
+ - develop
+ interruptible: true
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 62ceaf17b..b17e16bf9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Events: ability to create, view, and comment on Events (on Rebased).
- Onboarding: display an introduction wizard to newly registered accounts.
- Posts: translate foreign language posts into your native language (on Rebased, Mastodon; if configured by the admin).
+- Posts: ability to view quotes of a post (on Rebased).
- Posts: hover the "replying to" line to see a preview card of the parent post.
- Chats: ability to leave a chat (on Rebased, Truth Social).
- Chats: ability to disable chats for yourself.
@@ -32,10 +33,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Posts: changed the thumbs-up icon to a heart.
- Posts: move instance favicon beside username instead of post timestamp.
- Posts: changed the behavior of content warnings. CWs and sensitive media are unified into one design.
+- Posts: redesigned interaction counters to use text instead of icons.
- Profile: overhauled user profiles to be consistent with the rest of the UI.
- Composer: move emoji button alongside other composer buttons, add numerical counter.
- Birthdays: move today's birthdays out of notifications into right sidebar.
- Performance: improve scrolling/navigation between feeds by using a virtual window library.
+- Admin: reorganize UI into 3-column layout.
+- Admin: include external link to frontend repo for the running commit.
### Removed
- Theme: Halloween theme.
diff --git a/README.md b/README.md
index 754e68d4c..715703c97 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ busybox unzip soapbox.zip -o -d /opt/pleroma/instance
The change will take effect immediately, just refresh your browser tab.
It's not necessary to restart the Pleroma service.
-***For OTP releases,*** *unpack to /var/lib/pleroma instead.*
+**_For OTP releases,_** _unpack to /var/lib/pleroma instead._
To remove Soapbox and revert to the default pleroma-fe, simply `rm /opt/pleroma/instance/static/index.html` (you can delete other stuff in there too, but be careful not to delete your own HTML files).
@@ -150,15 +150,19 @@ NODE_ENV=development
```
#### Local dev server
+
- `yarn dev` - Run the local dev server.
#### Building
+
- `yarn build` - Compile without a dev server, into `/static` directory.
#### Translations
+
- `yarn manage:translations` - Normalizes translation files. Should always be run after editing i18n strings.
#### Tests
+
- `yarn test:all` - Runs all tests and linters.
- `yarn test` - Runs Jest for frontend unit tests.
@@ -174,6 +178,9 @@ NODE_ENV=development
We welcome contributions to this project.
To contribute, see [Contributing to Soapbox](docs/contributing.md).
+Translators can help by providing [translations through Weblate](http://hosted.weblate.org/soapbox-pub/soapbox/).
+Native speakers from all around the world are welcome!
+
# Customization
Soapbox supports customization of the user interface, to allow per-instance branding and other features.
@@ -205,8 +212,8 @@ the Free Software Foundation, either version 3 of the License, or
Soapbox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
-along with Soapbox. If not, see .
+along with Soapbox. If not, see .
diff --git a/app/soapbox/components/radio.tsx b/app/soapbox/components/radio.tsx
new file mode 100644
index 000000000..ef204b06f
--- /dev/null
+++ b/app/soapbox/components/radio.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+
+import List, { ListItem } from './list';
+
+interface IRadioGroup {
+ onChange: React.ChangeEventHandler
+ children: React.ReactElement<{ onChange: React.ChangeEventHandler }>[]
+}
+
+const RadioGroup = ({ onChange, children }: IRadioGroup) => {
+ const childrenWithProps = React.Children.map(children, child =>
+ React.cloneElement(child, { onChange }),
+ );
+
+ return {childrenWithProps};
+};
+
+interface IRadioItem {
+ label: React.ReactNode,
+ hint?: React.ReactNode,
+ value: string,
+ checked: boolean,
+ onChange?: React.ChangeEventHandler,
+}
+
+const RadioItem: React.FC = ({ label, hint, checked = false, onChange, value }) => {
+ return (
+
+
+
+ );
+};
+
+export {
+ RadioGroup,
+ RadioItem,
+};
\ No newline at end of file
diff --git a/app/soapbox/features/admin/components/dashcounter.tsx b/app/soapbox/features/admin/components/dashcounter.tsx
new file mode 100644
index 000000000..a42986535
--- /dev/null
+++ b/app/soapbox/features/admin/components/dashcounter.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import { FormattedNumber } from 'react-intl';
+import { Link } from 'react-router-dom';
+
+import { Text } from 'soapbox/components/ui';
+import { isNumber } from 'soapbox/utils/numbers';
+
+interface IDashCounter {
+ count: number | undefined
+ label: React.ReactNode
+ to?: string
+ percent?: boolean
+}
+
+/** Displays a (potentially clickable) dashboard statistic. */
+const DashCounter: React.FC = ({ count, label, to = '#', percent = false }) => {
+
+ if (!isNumber(count)) {
+ return null;
+ }
+
+ return (
+
+
+
+
+
+ {label}
+
+
+ );
+};
+
+interface IDashCounters {
+ children: React.ReactNode
+}
+
+/** Wrapper container for dash counters. */
+const DashCounters: React.FC = ({ children }) => {
+ return (
+