Call it pl-fe internally

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-08-28 13:41:08 +02:00
parent 4d5690d0c1
commit 966b04fdf0
873 changed files with 5771 additions and 6061 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/node_modules/
yarn-error.log*

View file

@ -1,7 +0,0 @@
### Environment
* Soapbox version:
* Backend (Mastodon, Pleroma, etc):
* Browser/OS:
### Bug description

View file

@ -1,8 +0,0 @@
## Summary
<!-- Describe your changes in detail -->
## Screenshots (if appropriate):
| Before | After |
| ------ | ----- |
| | |

View file

@ -1,5 +0,0 @@
## Summary
<!-- Describe your changes in detail -->
## Screenshots (if appropriate):

View file

@ -1,5 +1,5 @@
{
// Place your Soapbox workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// Place your pl-fe workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
@ -41,7 +41,7 @@
"body": [
"import React from 'react';",
"",
"import { render, screen } from 'soapbox/jest/test-helpers';",
"import { render, screen } from 'pl-fe/jest/test-helpers';",
"",
"import ${1:Component} from '${2:..}';",
"",

View file

@ -16,7 +16,7 @@ yarn-error.log*
/static/
/public/
/dist/
/soapbox.zip
/pl-fe.zip
.idea
.DS_Store

View file

@ -16,7 +16,7 @@ yarn-error.log*
/static/
/public/
/dist/
/soapbox.zip
/pl-fe.zip
.idea
.DS_Store

View file

@ -1,137 +0,0 @@
image: node:21
variables:
NODE_ENV: test
DS_EXCLUDED_ANALYZERS: gemnasium-python
default:
interruptible: true
cache: &cache
key:
files:
- yarn.lock
paths:
- node_modules/
policy: pull
stages:
- deps
- test
- deploy
- release
deps:
stage: deps
script: yarn install --ignore-scripts
only:
changes:
- yarn.lock
cache:
<<: *cache
policy: push
lint:
stage: test
script: yarn lint
only:
changes:
- "**/*.js"
- "**/*.jsx"
- "**/*.cjs"
- "**/*.mjs"
- "**/*.ts"
- "**/*.tsx"
- "**/*.scss"
- "**/*.css"
- ".eslintignore"
- ".eslintrc.json"
- ".stylelintrc.json"
build:
stage: test
before_script:
- apt-get update -y && apt-get install -y zip
script:
- yarn build
- cp dist/index.html dist/404.html
- cd dist && zip -r ../soapbox.zip . && cd ..
variables:
NODE_ENV: production
artifacts:
paths:
- soapbox.zip
i18n:
stage: test
script:
- yarn i18n
- git diff --quiet || (echo "Locale files are out of date. Please run `yarn i18n`" && exit 1)
docs-deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add curl
script:
- curl -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' https://gitlab.com/api/v4/projects/15685485/trigger/pipeline
only:
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
changes:
- "docs/**/*"
review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.git.soapbox.pub
before_script:
- apt-get update -y && apt-get install -y unzip
script:
- unzip soapbox.zip -d dist
- npx -y surge dist $CI_COMMIT_REF_SLUG.git.soapbox.pub
allow_failure: true
pages:
stage: deploy
before_script:
- apt-get update -y && apt-get install -y unzip
script:
# artifacts are kept between jobs
- unzip soapbox.zip -d public
variables:
NODE_ENV: production
artifacts:
paths:
- public
only:
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
docker:
stage: deploy
image: docker:25.0.3
services:
- docker:25.0.3-dind
tags:
- dind
# https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df
script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
rules:
- if: $CI_COMMIT_TAG
interruptible: false
release:
stage: release
rules:
- if: $CI_COMMIT_TAG
script:
- npx tsx ./scripts/do-release.ts
interruptible: false
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml

View file

@ -3,7 +3,7 @@ services:
build:
context: .
dockerfile: Dockerfile.dev
image: soapbox-dev
image: pl-fe-dev
ports:
- "3036:3036"
volumes:

View file

@ -1,4 +1,4 @@
# Soapbox Nginx for Docker.
# pl-fe Nginx for Docker.
# It's intended to be used by the official nginx image, which has templating functionality.
# Mount at: `/etc/nginx/templates/default.conf.template`
@ -11,7 +11,7 @@ map $http_upgrade $connection_upgrade {
# ActivityPub routing.
map $http_accept $activitypub_location {
default @soapbox;
default @pl-fe;
"application/activity+json" @backend;
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' @backend;
}
@ -57,7 +57,7 @@ server {
# Fallback route.
# Try static files, then fall back to the SPA.
location / {
try_files $uri @soapbox;
try_files $uri @pl-fe;
}
# Backend routes.
@ -72,21 +72,21 @@ server {
try_files /dev/null $activitypub_location;
}
# Soapbox build files.
# pl-fe build files.
# New builds produce hashed filenames, so these should be cached heavily.
location /packs {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Soapbox ServiceWorker.
# pl-fe ServiceWorker.
location = /sw.js {
add_header Cache-Control "public, max-age=0";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Soapbox SPA (Single Page App).
location @soapbox {
# pl-fe SPA (Single Page App).
location @pl-fe {
try_files /index.html /dev/null;
}

View file

@ -1,4 +1,4 @@
# Nginx configuration for Soapbox atop Mastodon.
# Nginx configuration for pl-fe atop Mastodon.
# Adapted from: https://github.com/mastodon/mastodon/blob/b4d373a3df2752d9f8bdc0d7f02350528f3789b2/dist/nginx.conf
#
# Edit this file to change occurrences of "example.com" to your own domain.
@ -14,7 +14,7 @@ map $http_upgrade $connection_upgrade {
# ActivityPub routing.
map $http_accept $activitypub_location {
default @soapbox;
default @pl-fe;
"application/activity+json" @mastodon;
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' @mastodon;
}
@ -33,7 +33,7 @@ server {
listen 80;
listen [::]:80;
server_name example.com;
root /opt/soapbox;
root /opt/pl-fe;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
@ -58,7 +58,7 @@ server {
sendfile on;
client_max_body_size 80m;
root /opt/soapbox;
root /opt/pl-fe;
gzip on;
gzip_disable "msie6";
@ -93,7 +93,7 @@ server {
try_files /dev/null $activitypub_location;
}
# Soapbox & Mastodon (frontend) build files.
# pl-fe & Mastodon (frontend) build files.
# New builds produce hashed filenames, so these should be cached heavily.
location /packs {
add_header Cache-Control "public, max-age=31536000, immutable";
@ -108,7 +108,7 @@ server {
try_files $uri @mastodon-packs;
}
# Soapbox configuration files.
# pl-fe configuration files.
# Enable CORS so we can fetch them.
location /instance {
add_header Access-Control-Allow-Origin "*";
@ -119,22 +119,22 @@ server {
}
}
# Soapbox ServiceWorker.
# pl-fe ServiceWorker.
location = /sw.js {
add_header Cache-Control "public, max-age=0";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Soapbox SPA (Single Page App).
location @soapbox {
# pl-fe SPA (Single Page App).
location @pl-fe {
try_files /index.html /dev/null;
}
# Mastodon public files (fallback to Soapbox SPA).
# Mastodon public files (fallback to pl-fe SPA).
# https://github.com/mastodon/mastodon/tree/main/public
location @mastodon-public {
root /home/mastodon/live/public;
try_files $uri @soapbox;
try_files $uri @pl-fe;
}
# Like Mastodon public, without fallback to SPA.
@ -142,8 +142,8 @@ server {
root /home/mastodon/live/public;
}
# Soapbox & Mastodon static files.
# Try Soapbox first, Mastodon, then fall back to the SPA.
# pl-fe & Mastodon static files.
# Try pl-fe first, Mastodon, then fall back to the SPA.
location @static-files {
try_files $uri @mastodon-public;
}

View file

@ -261,7 +261,7 @@
"morefollows.following_label": "…and {count} more {count, plural, one {follow} other {follows}} on remote sites.",
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.admin_settings": "Admin settings",
"navigation_bar.soapbox_config": "Soapbox config",
"navigation_bar.plfe_config": "Soapbox config",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new post",
@ -740,7 +740,7 @@
"morefollows.following_label": "…and {count} more {count, plural, one {follow} other {follows}} on remote sites.",
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.admin_settings": "Admin settings",
"navigation_bar.soapbox_config": "Soapbox config",
"navigation_bar.plfe_config": "Soapbox config",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new post",

View file

@ -1,119 +0,0 @@
{
"allowedEmoji": [
"👍",
"❤️",
"😆",
"😮",
"😢",
"😡",
"😩"
],
"brandColor": "#990099",
"copyright": "♡2021. Copying is an act of love. Please copy and share.",
"cryptoAddresses": [
{
"address": "bc1qv7lk3algpfg4zpyuhvxfm0uza9ck4parz3y3l5",
"note": "",
"ticker": "btc"
},
{
"address": "0xadc66B63bFee7677CD27CFb81b16a8860f1A1226",
"note": "",
"ticker": "eth"
},
{
"address": "DSf7UmRf7DGGsjh4QYhzQaqtjJMTXZ8k79",
"note": "",
"ticker": "doge"
},
{
"address": "ltc1q642pnkuvw0gpuuvddw6vafvl9hhp3efyl9mnqz",
"note": "",
"ticker": "ltc"
},
{
"address": "t1faHDsoa4bd3pGaLjaU7DiuUtBPzbnEEse",
"note": "",
"ticker": "zec"
},
{
"address": "XchTLkcSMsDoZGESwr4tqtxSU5dideAZVQ",
"note": "",
"ticker": "dash"
},
{
"address": "bitcoincash:qp8f80z27294phmhdk55yf05p3f0tkxl4v9r2aavw5",
"note": "",
"ticker": "bch"
}
],
"cryptoDonatePanel": {
"limit": 1
},
"customCss": [
"/instance/spinster.css"
],
"defaultSettings": {
"autoPlayGif": false,
"themeMode": "light"
},
"extensions": {
"patron": {
"enabled": true
}
},
"logo": "https://spinster.xyz/instance/images/spinster-logo.svg",
"navlinks": {
"homeFooter": [
{
"title": "About",
"url": "/about"
},
{
"title": "Terms of Service",
"url": "/about/tos"
},
{
"title": "Privacy Policy",
"url": "/about/privacy"
},
{
"title": "DMCA",
"url": "/about/dmca"
},
{
"title": "Source Code",
"url": "/about#opensource"
}
]
},
"promoPanel": {
"items": [
{
"icon": "shopping-basket",
"text": "Buy Spinster Merch",
"url": "https://shop.4w.pub/collections/spinster"
},
{
"icon": "eye-slash",
"text": "Privacy Guide",
"url": "https://4w.pub/your-guide-to-spinster-privacy-options/"
},
{
"icon": "question-circle",
"text": "Spinster FAQs",
"url": "https://spinster.xyz/about#faqs"
},
{
"icon": "bug",
"text": "Report a Bug",
"url": "https://gitlab.com/soapbox-pub/soapbox-fe/-/issues/"
},
{
"icon": "fediverse",
"text": "About the Fediverse",
"url": "https://jointhefedi.com/"
}
]
}
}

View file

@ -1,8 +1,8 @@
// import MockAdapter from 'axios-mock-adapter';
import { Map as ImmutableMap } from 'immutable';
// import { staticClient } from 'soapbox/api';
import { mockStore } from 'soapbox/jest/test-helpers';
// import { staticClient } from 'pl-fe/api';
import { mockStore } from 'pl-fe/jest/test-helpers';
import {
FETCH_ABOUT_PAGE_REQUEST,

View file

@ -1,7 +1,7 @@
import { staticFetch } from '../api';
import type { AnyAction } from 'redux';
import type { RootState } from 'soapbox/store';
import type { RootState } from 'pl-fe/store';
const FETCH_ABOUT_PAGE_REQUEST = 'FETCH_ABOUT_PAGE_REQUEST' as const;
const FETCH_ABOUT_PAGE_SUCCESS = 'FETCH_ABOUT_PAGE_SUCCESS' as const;

View file

@ -1,5 +1,5 @@
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { __stub } from 'pl-fe/api';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { submitAccountNote } from './account-notes';

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { AnyAction } from 'redux';
import type { RootState } from 'soapbox/store';
import type { RootState } from 'pl-fe/store';
const ACCOUNT_NOTE_SUBMIT_REQUEST = 'ACCOUNT_NOTE_SUBMIT_REQUEST' as const;
const ACCOUNT_NOTE_SUBMIT_SUCCESS = 'ACCOUNT_NOTE_SUBMIT_SUCCESS' as const;

View file

@ -1,10 +1,10 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { buildInstance, buildRelationship } from 'soapbox/jest/factory';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { normalizeAccount } from 'soapbox/normalizers';
import { ListRecord, ReducerRecord } from 'soapbox/reducers/user-lists';
import { __stub } from 'pl-fe/api';
import { buildInstance, buildRelationship } from 'pl-fe/jest/factory';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { normalizeAccount } from 'pl-fe/normalizers';
import { ListRecord, ReducerRecord } from 'pl-fe/reducers/user-lists';
import {
authorizeFollowRequest,
@ -95,7 +95,7 @@ describe('fetchAccount()', () => {
});
describe('with a successful API request', async () => {
const account = await import('soapbox/__fixtures__/pleroma-account.json');
const account = await import('pl-fe/__fixtures__/pleroma-account.json');
beforeEach(() => {
const state = rootState;

View file

@ -1,18 +1,18 @@
import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api';
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { selectAccount } from 'soapbox/selectors';
import { isLoggedIn } from 'soapbox/utils/auth';
import { importEntities } from 'pl-fe/entity-store/actions';
import { Entities } from 'pl-fe/entity-store/entities';
import { selectAccount } from 'pl-fe/selectors';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient, type PlfeResponse } from '../api';
import { importFetchedAccount, importFetchedAccounts } from './importer';
import type { Map as ImmutableMap } from 'immutable';
import type { MinifiedStatus } from 'soapbox/reducers/statuses';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { History } from 'soapbox/types/history';
import type { MinifiedStatus } from 'pl-fe/reducers/statuses';
import type { AppDispatch, RootState } from 'pl-fe/store';
import type { History } from 'pl-fe/types/history';
const ACCOUNT_CREATE_REQUEST = 'ACCOUNT_CREATE_REQUEST' as const;
const ACCOUNT_CREATE_SUCCESS = 'ACCOUNT_CREATE_SUCCESS' as const;

View file

@ -1,13 +1,13 @@
import { fetchRelationships } from 'soapbox/actions/accounts';
import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer';
import { accountIdsToAccts } from 'soapbox/selectors';
import { filterBadges, getTagDiff } from 'soapbox/utils/badges';
import { fetchRelationships } from 'pl-fe/actions/accounts';
import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'pl-fe/actions/importer';
import { accountIdsToAccts } from 'pl-fe/selectors';
import { filterBadges, getTagDiff } from 'pl-fe/utils/badges';
import { getClient } from '../api';
import type { Account, AdminGetAccountsParams, AdminGetReportsParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const ADMIN_CONFIG_FETCH_REQUEST = 'ADMIN_CONFIG_FETCH_REQUEST' as const;
const ADMIN_CONFIG_FETCH_SUCCESS = 'ADMIN_CONFIG_FETCH_SUCCESS' as const;
@ -89,7 +89,7 @@ const updateConfig = (configs: Record<string, any>[]) =>
});
};
const updateSoapboxConfig = (data: Record<string, any>) =>
const updatePlFeConfig = (data: Record<string, any>) =>
(dispatch: AppDispatch) => {
const params = [{
group: ':pleroma',
@ -380,7 +380,7 @@ export {
ADMIN_USER_INDEX_QUERY_SET,
fetchConfig,
updateConfig,
updateSoapboxConfig,
updatePlFeConfig,
fetchReports,
closeReport,
fetchUsers,

View file

@ -1,15 +1,15 @@
import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import { importFetchedAccounts } from './importer';
import type { Account as BaseAccount } from 'pl-api';
import type { Account } from 'soapbox/normalizers';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Account } from 'pl-fe/normalizers';
import type { AppDispatch, RootState } from 'pl-fe/store';
const ALIASES_FETCH_REQUEST = 'ALIASES_FETCH_REQUEST' as const;
const ALIASES_FETCH_SUCCESS = 'ALIASES_FETCH_SUCCESS' as const;

View file

@ -2,13 +2,13 @@
* Apps: manage OAuth applications.
* Particularly useful for auth.
* https://docs.joinmastodon.org/methods/apps/
* @module soapbox/actions/apps
* @see module:soapbox/actions/auth
* @module pl-fe/actions/apps
* @see module:pl-fe/actions/auth
*/
import { PlApiClient, type CreateApplicationParams } from 'pl-api';
import * as BuildConfig from 'soapbox/build-config';
import * as BuildConfig from 'pl-fe/build-config';
import type { AnyAction } from 'redux';

View file

@ -1,37 +1,37 @@
/**
* Auth: login & registration workflow.
* This file contains abstractions over auth concepts.
* @module soapbox/actions/auth
* @see module:soapbox/actions/apps
* @see module:soapbox/actions/oauth
* @see module:soapbox/actions/security
* @module pl-fe/actions/auth
* @see module:pl-fe/actions/apps
* @see module:pl-fe/actions/oauth
* @see module:pl-fe/actions/security
*/
import { credentialAccountSchema, PlApiClient, type CreateAccountParams, type Token } from 'pl-api';
import { defineMessages } from 'react-intl';
import { createAccount } from 'soapbox/actions/accounts';
import { createApp } from 'soapbox/actions/apps';
import { fetchMeSuccess, fetchMeFail } from 'soapbox/actions/me';
import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
import { startOnboarding } from 'soapbox/actions/onboarding';
import * as BuildConfig from 'soapbox/build-config';
import { custom } from 'soapbox/custom';
import { queryClient } from 'soapbox/queries/client';
import { selectAccount } from 'soapbox/selectors';
import { unsetSentryAccount } from 'soapbox/sentry';
import KVStore from 'soapbox/storage/kv-store';
import toast from 'soapbox/toast';
import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { normalizeUsername } from 'soapbox/utils/input';
import { getScopes } from 'soapbox/utils/scopes';
import { isStandalone } from 'soapbox/utils/state';
import { createAccount } from 'pl-fe/actions/accounts';
import { createApp } from 'pl-fe/actions/apps';
import { fetchMeSuccess, fetchMeFail } from 'pl-fe/actions/me';
import { obtainOAuthToken, revokeOAuthToken } from 'pl-fe/actions/oauth';
import { startOnboarding } from 'pl-fe/actions/onboarding';
import * as BuildConfig from 'pl-fe/build-config';
import { custom } from 'pl-fe/custom';
import { queryClient } from 'pl-fe/queries/client';
import { selectAccount } from 'pl-fe/selectors';
import { unsetSentryAccount } from 'pl-fe/sentry';
import KVStore from 'pl-fe/storage/kv-store';
import toast from 'pl-fe/toast';
import { getLoggedInAccount, parseBaseURL } from 'pl-fe/utils/auth';
import sourceCode from 'pl-fe/utils/code';
import { normalizeUsername } from 'pl-fe/utils/input';
import { getScopes } from 'pl-fe/utils/scopes';
import { isStandalone } from 'pl-fe/utils/state';
import { type PlfeResponse, getClient } from '../api';
import { importFetchedAccount } from './importer';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT' as const;

View file

@ -1,6 +1,6 @@
import { getClient } from '../api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const BACKUPS_FETCH_REQUEST = 'BACKUPS_FETCH_REQUEST' as const;
const BACKUPS_FETCH_SUCCESS = 'BACKUPS_FETCH_SUCCESS' as const;

View file

@ -3,7 +3,7 @@ import { getClient } from '../api';
import { importFetchedStatuses } from './importer';
import type { PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const BOOKMARKED_STATUSES_FETCH_REQUEST = 'BOOKMARKED_STATUSES_FETCH_REQUEST' as const;
const BOOKMARKED_STATUSES_FETCH_SUCCESS = 'BOOKMARKED_STATUSES_FETCH_SUCCESS' as const;

View file

@ -1,6 +1,6 @@
import { getSettings, changeSetting } from 'soapbox/actions/settings';
import { getSettings, changeSetting } from 'pl-fe/actions/settings';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const toggleMainWindow = () =>
(dispatch: AppDispatch, getState: () => RootState) => {

View file

@ -1,9 +1,9 @@
// Loosely adapted from twitter-interaction-circles, licensed under MIT License
// https://github.com/duiker101/twitter-interaction-circles
import { getClient } from 'soapbox/api';
import { getClient } from 'pl-fe/api';
import type { PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
interface Interaction {
acct: string;

View file

@ -1,8 +1,8 @@
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { buildInstance } from 'soapbox/jest/factory';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { ReducerCompose } from 'soapbox/reducers/compose';
import { buildInstance } from 'pl-fe/jest/factory';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { ReducerCompose } from 'pl-fe/reducers/compose';
import { uploadCompose, submitCompose } from './compose';
import { STATUS_CREATE_REQUEST } from './statuses';

View file

@ -1,14 +1,14 @@
import throttle from 'lodash/throttle';
import { defineMessages, IntlShape } from 'react-intl';
import { getClient } from 'soapbox/api';
import { isNativeEmoji } from 'soapbox/features/emoji';
import emojiSearch from 'soapbox/features/emoji/search';
import { Language } from 'soapbox/features/preferences';
import { selectAccount, selectOwnAccount, makeGetAccount } from 'soapbox/selectors';
import { tagHistory } from 'soapbox/settings';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getClient } from 'pl-fe/api';
import { isNativeEmoji } from 'pl-fe/features/emoji';
import emojiSearch from 'pl-fe/features/emoji/search';
import { Language } from 'pl-fe/features/preferences';
import { selectAccount, selectOwnAccount, makeGetAccount } from 'pl-fe/selectors';
import { tagHistory } from 'pl-fe/settings';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { chooseEmoji } from './emojis';
import { importFetchedAccounts } from './importer';
@ -20,11 +20,11 @@ import { createStatus } from './statuses';
import type { EditorState } from 'lexical';
import type { Account as BaseAccount, BackendVersion, CreateStatusParams, Group, MediaAttachment, Status as BaseStatus, Tag, Poll, ScheduledStatus } from 'pl-api';
import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
import type { Emoji } from 'soapbox/features/emoji';
import type { Account, Status } from 'soapbox/normalizers';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { History } from 'soapbox/types/history';
import type { AutoSuggestion } from 'pl-fe/components/autosuggest-input';
import type { Emoji } from 'pl-fe/features/emoji';
import type { Account, Status } from 'pl-fe/normalizers';
import type { AppDispatch, RootState } from 'pl-fe/store';
import type { History } from 'pl-fe/types/history';
let cancelFetchComposeSuggestions = new AbortController();

View file

@ -1,13 +1,13 @@
import queryString from 'query-string';
import * as BuildConfig from 'soapbox/build-config';
import { isURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { getScopes } from 'soapbox/utils/scopes';
import * as BuildConfig from 'pl-fe/build-config';
import { isURL } from 'pl-fe/utils/auth';
import sourceCode from 'pl-fe/utils/code';
import { getScopes } from 'pl-fe/utils/scopes';
import { createApp } from './apps';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const createProviderApp = () =>
async(dispatch: AppDispatch, getState: () => RootState) => {

View file

@ -1,4 +1,4 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@ -9,7 +9,7 @@ import {
} from './importer';
import type { Account, Conversation, PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const CONVERSATIONS_MOUNT = 'CONVERSATIONS_MOUNT' as const;
const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT' as const;

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { CustomEmoji } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const CUSTOM_EMOJIS_FETCH_REQUEST = 'CUSTOM_EMOJIS_FETCH_REQUEST' as const;
const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS' as const;

View file

@ -4,7 +4,7 @@ import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import type { Account, ProfileDirectoryParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const DIRECTORY_FETCH_REQUEST = 'DIRECTORY_FETCH_REQUEST' as const;
const DIRECTORY_FETCH_SUCCESS = 'DIRECTORY_FETCH_SUCCESS' as const;

View file

@ -1,12 +1,12 @@
import { Entities } from 'soapbox/entity-store/entities';
import { isLoggedIn } from 'soapbox/utils/auth';
import { Entities } from 'pl-fe/entity-store/entities';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import type { PaginatedResponse } from 'pl-api';
import type { EntityStore } from 'soapbox/entity-store/types';
import type { Account } from 'soapbox/normalizers';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { EntityStore } from 'pl-fe/entity-store/types';
import type { Account } from 'pl-fe/normalizers';
import type { AppDispatch, RootState } from 'pl-fe/store';
const DOMAIN_BLOCK_REQUEST = 'DOMAIN_BLOCK_REQUEST' as const;
const DOMAIN_BLOCK_SUCCESS = 'DOMAIN_BLOCK_SUCCESS' as const;

View file

@ -1,9 +1,9 @@
import { v4 as uuid } from 'uuid';
import { makeGetAccount } from 'soapbox/selectors';
import KVStore from 'soapbox/storage/kv-store';
import { makeGetAccount } from 'pl-fe/selectors';
import KVStore from 'pl-fe/storage/kv-store';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS';

View file

@ -1,4 +1,4 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@ -6,7 +6,7 @@ import { importFetchedStatus } from './importer';
import { favourite, unfavourite } from './interactions';
import type { EmojiReaction, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const EMOJI_REACT_REQUEST = 'EMOJI_REACT_REQUEST' as const;
const EMOJI_REACT_SUCCESS = 'EMOJI_REACT_SUCCESS' as const;

View file

@ -1,7 +1,7 @@
import { saveSettings } from './settings';
import type { Emoji } from 'soapbox/features/emoji';
import type { AppDispatch } from 'soapbox/store';
import type { Emoji } from 'pl-fe/features/emoji';
import type { AppDispatch } from 'pl-fe/store';
const EMOJI_CHOOSE = 'EMOJI_CHOOSE';

View file

@ -1,7 +1,7 @@
import { defineMessages, IntlShape } from 'react-intl';
import { getClient } from 'soapbox/api';
import toast from 'soapbox/toast';
import { getClient } from 'pl-fe/api';
import toast from 'pl-fe/toast';
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
import { uploadFile } from './media';
@ -13,8 +13,8 @@ import {
} from './statuses';
import type { Account, CreateEventParams, MediaAttachment, PaginatedResponse, Status } from 'pl-api';
import type { MinifiedStatus } from 'soapbox/reducers/statuses';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { MinifiedStatus } from 'pl-fe/reducers/statuses';
import type { AppDispatch, RootState } from 'pl-fe/store';
const LOCATION_SEARCH_REQUEST = 'LOCATION_SEARCH_REQUEST' as const;
const LOCATION_SEARCH_SUCCESS = 'LOCATION_SEARCH_SUCCESS' as const;

View file

@ -1,11 +1,11 @@
import { defineMessages } from 'react-intl';
import { getClient } from 'soapbox/api';
import { normalizeAccount } from 'soapbox/normalizers';
import toast from 'soapbox/toast';
import { getClient } from 'pl-fe/api';
import { normalizeAccount } from 'pl-fe/normalizers';
import toast from 'pl-fe/toast';
import type { Account, PaginatedResponse } from 'pl-api';
import type { RootState } from 'soapbox/store';
import type { RootState } from 'pl-fe/store';
const EXPORT_FOLLOWS_REQUEST = 'EXPORT_FOLLOWS_REQUEST' as const;
const EXPORT_FOLLOWS_SUCCESS = 'EXPORT_FOLLOWS_SUCCESS' as const;

View file

@ -1,22 +1,22 @@
/**
* External Auth: workflow for logging in to remote servers.
* @module soapbox/actions/external_auth
* @see module:soapbox/actions/auth
* @see module:soapbox/actions/apps
* @see module:soapbox/actions/oauth
* @module pl-fe/actions/external_auth
* @see module:pl-fe/actions/auth
* @see module:pl-fe/actions/apps
* @see module:pl-fe/actions/oauth
*/
import { instanceSchema, PlApiClient, type Instance } from 'pl-api';
import { createApp } from 'soapbox/actions/apps';
import { authLoggedIn, verifyCredentials, switchAccount } from 'soapbox/actions/auth';
import { obtainOAuthToken } from 'soapbox/actions/oauth';
import { parseBaseURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { getQuirks } from 'soapbox/utils/quirks';
import { getInstanceScopes } from 'soapbox/utils/scopes';
import { createApp } from 'pl-fe/actions/apps';
import { authLoggedIn, verifyCredentials, switchAccount } from 'pl-fe/actions/auth';
import { obtainOAuthToken } from 'pl-fe/actions/oauth';
import { parseBaseURL } from 'pl-fe/utils/auth';
import sourceCode from 'pl-fe/utils/code';
import { getQuirks } from 'pl-fe/utils/quirks';
import { getInstanceScopes } from 'pl-fe/utils/scopes';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch } from 'pl-fe/store';
const fetchExternalInstance = (baseURL: string) =>
(new PlApiClient(baseURL)).instance.getInstance()

View file

@ -1,4 +1,4 @@
import { AppDispatch, RootState } from 'soapbox/store';
import { AppDispatch, RootState } from 'pl-fe/store';
import { getClient } from '../api';

View file

@ -1,11 +1,11 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import { importFetchedStatuses } from './importer';
import type { PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST' as const;
const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS' as const;

View file

@ -1,12 +1,12 @@
import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import type { FilterContext } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST' as const;
const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS' as const;

View file

@ -3,7 +3,7 @@ import { getClient } from '../api';
import { importFetchedAccounts } from './importer';
import type { Account, PaginatedResponse } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const GROUP_BLOCKS_FETCH_REQUEST = 'GROUP_BLOCKS_FETCH_REQUEST' as const;
const GROUP_BLOCKS_FETCH_SUCCESS = 'GROUP_BLOCKS_FETCH_SUCCESS' as const;

View file

@ -1,9 +1,9 @@
import { getClient } from 'soapbox/api';
import { getClient } from 'pl-fe/api';
import { importFetchedAccounts } from './importer';
import type { StatusEdit } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const HISTORY_FETCH_REQUEST = 'HISTORY_FETCH_REQUEST' as const;
const HISTORY_FETCH_SUCCESS = 'HISTORY_FETCH_SUCCESS' as const;

View file

@ -1,10 +1,10 @@
import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import toast from 'pl-fe/toast';
import { getClient } from '../api';
import type { RootState } from 'soapbox/store';
import type { RootState } from 'pl-fe/store';
const IMPORT_FOLLOWS_REQUEST = 'IMPORT_FOLLOWS_REQUEST' as const;
const IMPORT_FOLLOWS_SUCCESS = 'IMPORT_FOLLOWS_SUCCESS' as const;

View file

@ -1,9 +1,9 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { normalizeAccount, normalizeGroup } from 'soapbox/normalizers';
import { importEntities } from 'pl-fe/entity-store/actions';
import { Entities } from 'pl-fe/entity-store/entities';
import { normalizeAccount, normalizeGroup } from 'pl-fe/normalizers';
import type { Account as BaseAccount, Group, Poll, Status as BaseStatus } from 'pl-api';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch } from 'pl-fe/store';
const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';

View file

@ -1,9 +1,9 @@
import { getAuthUserUrl, getMeUrl } from 'soapbox/utils/auth';
import { getAuthUserUrl, getMeUrl } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import type { Instance } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const INSTANCE_FETCH_SUCCESS = 'INSTANCE_FETCH_SUCCESS' as const;
const INSTANCE_FETCH_FAIL = 'INSTANCE_FETCH_FAIL' as const;

View file

@ -1,7 +1,7 @@
import { defineMessages } from 'react-intl';
import toast, { type IToastOptions } from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import toast, { type IToastOptions } from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@ -10,7 +10,7 @@ import { importFetchedAccounts, importFetchedStatus } from './importer';
import { openModal } from './modals';
import type { Account, EmojiReaction, PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const REBLOG_REQUEST = 'REBLOG_REQUEST' as const;
const REBLOG_SUCCESS = 'REBLOG_SUCCESS' as const;

View file

@ -1,6 +1,6 @@
import { saveSettings } from './settings';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch } from 'pl-fe/store';
const LANGUAGE_USE = 'LANGUAGE_USE' as const;

View file

@ -1,13 +1,13 @@
import { selectAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { selectAccount } from 'pl-fe/selectors';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import { importFetchedAccounts } from './importer';
import type { Account, List, PaginatedResponse } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST' as const;
const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS' as const;

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { SaveMarkersParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const MARKER_FETCH_REQUEST = 'MARKER_FETCH_REQUEST' as const;
const MARKER_FETCH_SUCCESS = 'MARKER_FETCH_SUCCESS' as const;

View file

@ -1,9 +1,9 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { buildAccount } from 'soapbox/jest/factory';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { AuthUserRecord, ReducerRecord } from 'soapbox/reducers/auth';
import { __stub } from 'pl-fe/api';
import { buildAccount } from 'pl-fe/jest/factory';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { AuthUserRecord, ReducerRecord } from 'pl-fe/reducers/auth';
import { fetchMe, patchMe } from './me';

View file

@ -1,7 +1,7 @@
import { selectAccount } from 'soapbox/selectors';
import { setSentryAccount } from 'soapbox/sentry';
import KVStore from 'soapbox/storage/kv-store';
import { getAuthUserId, getAuthUserUrl } from 'soapbox/utils/auth';
import { selectAccount } from 'pl-fe/selectors';
import { setSentryAccount } from 'pl-fe/sentry';
import KVStore from 'pl-fe/storage/kv-store';
import { getAuthUserId, getAuthUserUrl } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@ -9,7 +9,7 @@ import { loadCredentials } from './auth';
import { importFetchedAccount } from './importer';
import type { CredentialAccount, UpdateCredentialsParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const ME_FETCH_REQUEST = 'ME_FETCH_REQUEST' as const;
const ME_FETCH_SUCCESS = 'ME_FETCH_SUCCESS' as const;

View file

@ -1,14 +1,14 @@
import { defineMessages, type IntlShape } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { formatBytes, getVideoDuration } from 'soapbox/utils/media';
import resizeImage from 'soapbox/utils/resize-image';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { formatBytes, getVideoDuration } from 'pl-fe/utils/media';
import resizeImage from 'pl-fe/utils/resize-image';
import { getClient } from '../api';
import type { MediaAttachment, UploadMediaParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const messages = defineMessages({
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },

View file

@ -1,6 +1,6 @@
import { getClient } from '../api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const MFA_FETCH_REQUEST = 'MFA_FETCH_REQUEST' as const;
const MFA_FETCH_SUCCESS = 'MFA_FETCH_SUCCESS' as const;

View file

@ -1,37 +1,37 @@
import { AppDispatch } from 'soapbox/store';
import { AppDispatch } from 'pl-fe/store';
import type { ICryptoAddress } from 'soapbox/features/crypto-donate/components/crypto-address';
import type { ModalType } from 'soapbox/features/ui/components/modal-root';
import type { AccountModerationModalProps } from 'soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal';
import type { BoostModalProps } from 'soapbox/features/ui/components/modals/boost-modal';
import type { CompareHistoryModalProps } from 'soapbox/features/ui/components/modals/compare-history-modal';
import type { ComponentModalProps } from 'soapbox/features/ui/components/modals/component-modal';
import type { ComposeModalProps } from 'soapbox/features/ui/components/modals/compose-modal';
import type { ConfirmationModalProps } from 'soapbox/features/ui/components/modals/confirmation-modal';
import type { DislikesModalProps } from 'soapbox/features/ui/components/modals/dislikes-modal';
import type { EditAnnouncementModalProps } from 'soapbox/features/ui/components/modals/edit-announcement-modal';
import type { EditBookmarkFolderModalProps } from 'soapbox/features/ui/components/modals/edit-bookmark-folder-modal';
import type { EditDomainModalProps } from 'soapbox/features/ui/components/modals/edit-domain-modal';
import type { EditFederationModalProps } from 'soapbox/features/ui/components/modals/edit-federation-modal';
import type { EditRuleModalProps } from 'soapbox/features/ui/components/modals/edit-rule-modal';
import type { EmbedModalProps } from 'soapbox/features/ui/components/modals/embed-modal';
import type { EventMapModalProps } from 'soapbox/features/ui/components/modals/event-map-modal';
import type { EventParticipantsModalProps } from 'soapbox/features/ui/components/modals/event-participants-modal';
import type { FamiliarFollowersModalProps } from 'soapbox/features/ui/components/modals/familiar-followers-modal';
import type { FavouritesModalProps } from 'soapbox/features/ui/components/modals/favourites-modal';
import type { JoinEventModalProps } from 'soapbox/features/ui/components/modals/join-event-modal';
import type { ListAdderModalProps } from 'soapbox/features/ui/components/modals/list-adder-modal';
import type { ListEditorModalProps } from 'soapbox/features/ui/components/modals/list-editor-modal';
import type { MediaModalProps } from 'soapbox/features/ui/components/modals/media-modal';
import type { MentionsModalProps } from 'soapbox/features/ui/components/modals/mentions-modal';
import type { MissingDescriptionModalProps } from 'soapbox/features/ui/components/modals/missing-description-modal';
import type { ReactionsModalProps } from 'soapbox/features/ui/components/modals/reactions-modal';
import type { ReblogsModalProps } from 'soapbox/features/ui/components/modals/reblogs-modal';
import type { ReplyMentionsModalProps } from 'soapbox/features/ui/components/modals/reply-mentions-modal';
import type { SelectBookmarkFolderModalProps } from 'soapbox/features/ui/components/modals/select-bookmark-folder-modal';
import type { TextFieldModalProps } from 'soapbox/features/ui/components/modals/text-field-modal';
import type { UnauthorizedModalProps } from 'soapbox/features/ui/components/modals/unauthorized-modal';
import type { VideoModalProps } from 'soapbox/features/ui/components/modals/video-modal';
import type { ICryptoAddress } from 'pl-fe/features/crypto-donate/components/crypto-address';
import type { ModalType } from 'pl-fe/features/ui/components/modal-root';
import type { AccountModerationModalProps } from 'pl-fe/features/ui/components/modals/account-moderation-modal/account-moderation-modal';
import type { BoostModalProps } from 'pl-fe/features/ui/components/modals/boost-modal';
import type { CompareHistoryModalProps } from 'pl-fe/features/ui/components/modals/compare-history-modal';
import type { ComponentModalProps } from 'pl-fe/features/ui/components/modals/component-modal';
import type { ComposeModalProps } from 'pl-fe/features/ui/components/modals/compose-modal';
import type { ConfirmationModalProps } from 'pl-fe/features/ui/components/modals/confirmation-modal';
import type { DislikesModalProps } from 'pl-fe/features/ui/components/modals/dislikes-modal';
import type { EditAnnouncementModalProps } from 'pl-fe/features/ui/components/modals/edit-announcement-modal';
import type { EditBookmarkFolderModalProps } from 'pl-fe/features/ui/components/modals/edit-bookmark-folder-modal';
import type { EditDomainModalProps } from 'pl-fe/features/ui/components/modals/edit-domain-modal';
import type { EditFederationModalProps } from 'pl-fe/features/ui/components/modals/edit-federation-modal';
import type { EditRuleModalProps } from 'pl-fe/features/ui/components/modals/edit-rule-modal';
import type { EmbedModalProps } from 'pl-fe/features/ui/components/modals/embed-modal';
import type { EventMapModalProps } from 'pl-fe/features/ui/components/modals/event-map-modal';
import type { EventParticipantsModalProps } from 'pl-fe/features/ui/components/modals/event-participants-modal';
import type { FamiliarFollowersModalProps } from 'pl-fe/features/ui/components/modals/familiar-followers-modal';
import type { FavouritesModalProps } from 'pl-fe/features/ui/components/modals/favourites-modal';
import type { JoinEventModalProps } from 'pl-fe/features/ui/components/modals/join-event-modal';
import type { ListAdderModalProps } from 'pl-fe/features/ui/components/modals/list-adder-modal';
import type { ListEditorModalProps } from 'pl-fe/features/ui/components/modals/list-editor-modal';
import type { MediaModalProps } from 'pl-fe/features/ui/components/modals/media-modal';
import type { MentionsModalProps } from 'pl-fe/features/ui/components/modals/mentions-modal';
import type { MissingDescriptionModalProps } from 'pl-fe/features/ui/components/modals/missing-description-modal';
import type { ReactionsModalProps } from 'pl-fe/features/ui/components/modals/reactions-modal';
import type { ReblogsModalProps } from 'pl-fe/features/ui/components/modals/reblogs-modal';
import type { ReplyMentionsModalProps } from 'pl-fe/features/ui/components/modals/reply-mentions-modal';
import type { SelectBookmarkFolderModalProps } from 'pl-fe/features/ui/components/modals/select-bookmark-folder-modal';
import type { TextFieldModalProps } from 'pl-fe/features/ui/components/modals/text-field-modal';
import type { UnauthorizedModalProps } from 'pl-fe/features/ui/components/modals/unauthorized-modal';
import type { VideoModalProps } from 'pl-fe/features/ui/components/modals/video-modal';
const MODAL_OPEN = 'MODAL_OPEN' as const;
const MODAL_CLOSE = 'MODAL_CLOSE' as const;

View file

@ -1,16 +1,16 @@
import React from 'react';
import { defineMessages, IntlShape } from 'react-intl';
import { fetchAccountByUsername } from 'soapbox/actions/accounts';
import { deactivateUser, deleteUser, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin';
import { openModal } from 'soapbox/actions/modals';
import OutlineBox from 'soapbox/components/outline-box';
import { Stack, Text } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import { selectAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import { fetchAccountByUsername } from 'pl-fe/actions/accounts';
import { deactivateUser, deleteUser, deleteStatus, toggleStatusSensitivity } from 'pl-fe/actions/admin';
import { openModal } from 'pl-fe/actions/modals';
import OutlineBox from 'pl-fe/components/outline-box';
import { Stack, Text } from 'pl-fe/components/ui';
import AccountContainer from 'pl-fe/containers/account-container';
import { selectAccount } from 'pl-fe/selectors';
import toast from 'pl-fe/toast';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const messages = defineMessages({
deactivateUserHeading: { id: 'confirmations.admin.deactivate_user.heading', defaultMessage: 'Deactivate @{acct}' },

View file

@ -1,11 +1,11 @@
import { Set as ImmutableSet } from 'immutable';
import ConfigDB from 'soapbox/utils/config-db';
import ConfigDB from 'pl-fe/utils/config-db';
import { fetchConfig, updateConfig } from './admin';
import type { MRFSimple } from 'soapbox/schemas/pleroma';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { MRFSimple } from 'pl-fe/schemas/pleroma';
import type { AppDispatch, RootState } from 'pl-fe/store';
const simplePolicyMerge = (simplePolicy: MRFSimple, host: string, restrictions: Record<string, any>) => {
const entries = Object.entries(simplePolicy).map(([key, hosts]) => {

View file

@ -1,7 +1,7 @@
import { openModal } from './modals';
import type { Account } from 'soapbox/normalizers';
import type { AppDispatch } from 'soapbox/store';
import type { Account } from 'pl-fe/normalizers';
import type { AppDispatch } from 'pl-fe/store';
const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL';
const MUTES_TOGGLE_HIDE_NOTIFICATIONS = 'MUTES_TOGGLE_HIDE_NOTIFICATIONS';

View file

@ -1,8 +1,8 @@
import { OrderedMap as ImmutableOrderedMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { normalizeNotification } from 'soapbox/normalizers';
import { __stub } from 'pl-fe/api';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { normalizeNotification } from 'pl-fe/normalizers';
import { markReadNotifications } from './notifications';

View file

@ -2,15 +2,15 @@ import IntlMessageFormat from 'intl-messageformat';
import 'intl-pluralrules';
import { defineMessages } from 'react-intl';
import { getClient } from 'soapbox/api';
import { getNotificationStatus } from 'soapbox/features/notifications/components/notification';
import { normalizeNotification, normalizeNotifications, type Notification } from 'soapbox/normalizers';
import { getFilters, regexFromFilters } from 'soapbox/selectors';
import { isLoggedIn } from 'soapbox/utils/auth';
import { compareId } from 'soapbox/utils/comparators';
import { unescapeHTML } from 'soapbox/utils/html';
import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'soapbox/utils/notification';
import { joinPublicPath } from 'soapbox/utils/static';
import { getClient } from 'pl-fe/api';
import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification';
import { normalizeNotification, normalizeNotifications, type Notification } from 'pl-fe/normalizers';
import { getFilters, regexFromFilters } from 'pl-fe/selectors';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { compareId } from 'pl-fe/utils/comparators';
import { unescapeHTML } from 'pl-fe/utils/html';
import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'pl-fe/utils/notification';
import { joinPublicPath } from 'pl-fe/utils/static';
import { fetchRelationships } from './accounts';
import {
@ -23,7 +23,7 @@ import { saveMarker } from './markers';
import { getSettings, saveSettings } from './settings';
import type { Account, Notification as BaseNotification, PaginatedResponse, Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE' as const;
const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP' as const;

View file

@ -2,16 +2,16 @@
* OAuth: create and revoke tokens.
* Tokens can be used by users and apps.
* https://docs.joinmastodon.org/methods/apps/oauth/
* @module soapbox/actions/oauth
* @see module:soapbox/actions/auth
* @module pl-fe/actions/oauth
* @see module:pl-fe/actions/auth
*/
import { PlApiClient, type GetTokenParams, type RevokeTokenParams } from 'pl-api';
import * as BuildConfig from 'soapbox/build-config';
import { getBaseURL } from 'soapbox/utils/state';
import * as BuildConfig from 'pl-fe/build-config';
import { getBaseURL } from 'pl-fe/utils/state';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const OAUTH_TOKEN_CREATE_REQUEST = 'OAUTH_TOKEN_CREATE_REQUEST' as const;
const OAUTH_TOKEN_CREATE_SUCCESS = 'OAUTH_TOKEN_CREATE_SUCCESS' as const;

View file

@ -1,4 +1,4 @@
import { mockStore, mockWindowProperty, rootState } from 'soapbox/jest/test-helpers';
import { mockStore, mockWindowProperty, rootState } from 'pl-fe/jest/test-helpers';
import { checkOnboardingStatus, startOnboarding, endOnboarding } from './onboarding';

View file

@ -1,11 +1,11 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import { importFetchedStatuses } from './importer';
import type { Status } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST' as const;
const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS' as const;

View file

@ -0,0 +1,21 @@
import { rootState } from 'pl-fe/jest/test-helpers';
import { RootState } from 'pl-fe/store';
import { getPlFeConfig } from './pl-fe';
const ASCII_HEART = '❤'; // '\u2764\uFE0F'
const RED_HEART_RGI = '❤️'; // '\u2764'
describe('getPlFeConfig()', () => {
it('returns RGI heart on Pleroma > 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.3.0)') as RootState;
expect(getPlFeConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(true);
expect(getPlFeConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(false);
});
it('returns an ASCII heart on Pleroma < 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.0.0)') as RootState;
expect(getPlFeConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(true);
expect(getPlFeConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(false);
});
});

View file

@ -0,0 +1,109 @@
import { createSelector } from 'reselect';
import { getHost } from 'pl-fe/actions/instance';
import { normalizePlFeConfig } from 'pl-fe/normalizers';
import KVStore from 'pl-fe/storage/kv-store';
import { getClient, staticFetch } from '../api';
import type { AppDispatch, RootState } from 'pl-fe/store';
import type { APIEntity } from 'pl-fe/types/entities';
const PLFE_CONFIG_REQUEST_SUCCESS = 'PLFE_CONFIG_REQUEST_SUCCESS' as const;
const PLFE_CONFIG_REQUEST_FAIL = 'PLFE_CONFIG_REQUEST_FAIL' as const;
const PLFE_CONFIG_REMEMBER_SUCCESS = 'PLFE_CONFIG_REMEMBER_SUCCESS' as const;
const getPlFeConfig = createSelector([
(state: RootState) => state.plfe,
(state: RootState) => state.auth.client.features,
], (plfe, features) => {
// Do some additional normalization with the state
return normalizePlFeConfig(plfe);
});
const rememberPlFeConfig = (host: string | null) =>
(dispatch: AppDispatch) => {
return KVStore.getItemOrError(`plfe_config:${host}`).then(plFeConfig => {
dispatch({ type: PLFE_CONFIG_REMEMBER_SUCCESS, host, plFeConfig });
return plFeConfig;
}).catch(() => {});
};
const fetchFrontendConfigurations = () =>
(dispatch: AppDispatch, getState: () => RootState) =>
getClient(getState).instance.getFrontendConfigurations();
/** Conditionally fetches pl-fe config depending on backend features */
const fetchPlFeConfig = (host: string | null) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const features = getState().auth.client.features;
if (features.frontendConfigurations) {
return dispatch(fetchFrontendConfigurations()).then(data => {
if (data.pl_fe) {
dispatch(importPlFeConfig(data.pl_fe, host));
return data.pl_fe;
} else {
return dispatch(fetchPlFeJson(host));
}
});
} else {
return dispatch(fetchPlFeJson(host));
}
};
/** Tries to remember the config from browser storage before fetching it */
const loadPlFeConfig = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const host = getHost(getState());
return dispatch(rememberPlFeConfig(host)).then(() =>
dispatch(fetchPlFeConfig(host)),
);
};
const fetchPlFeJson = (host: string | null) =>
(dispatch: AppDispatch) =>
staticFetch('/instance/pl-fe.json').then(({ json: data }) => {
if (!isObject(data)) throw 'pl-fe.json failed';
dispatch(importPlFeConfig(data, host));
return data;
}).catch(error => {
dispatch(plFeConfigFail(error, host));
});
const importPlFeConfig = (plFeConfig: APIEntity, host: string | null) => {
if (!plFeConfig.brandColor) {
plFeConfig.brandColor = '#0482d8';
}
return {
type: PLFE_CONFIG_REQUEST_SUCCESS,
plFeConfig,
host,
};
};
const plFeConfigFail = (error: unknown, host: string | null) => ({
type: PLFE_CONFIG_REQUEST_FAIL,
error,
skipAlert: true,
host,
});
// https://stackoverflow.com/a/46663081
const isObject = (o: any) => o instanceof Object && o.constructor === Object;
export {
PLFE_CONFIG_REQUEST_SUCCESS,
PLFE_CONFIG_REQUEST_FAIL,
PLFE_CONFIG_REMEMBER_SUCCESS,
getPlFeConfig,
rememberPlFeConfig,
fetchFrontendConfigurations,
fetchPlFeConfig,
loadPlFeConfig,
fetchPlFeJson,
importPlFeConfig,
plFeConfigFail,
};

View file

@ -3,7 +3,7 @@ import { getClient } from '../api';
import { importFetchedPoll } from './importer';
import type { Poll } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const POLL_VOTE_REQUEST = 'POLL_VOTE_REQUEST' as const;
const POLL_VOTE_SUCCESS = 'POLL_VOTE_SUCCESS' as const;

View file

@ -1,7 +1,7 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { mockStore } from 'soapbox/jest/test-helpers';
import { __stub } from 'pl-fe/api';
import { mockStore } from 'pl-fe/jest/test-helpers';
import { VERIFY_CREDENTIALS_REQUEST } from './auth';
import { ACCOUNTS_IMPORT } from './importer';
@ -12,7 +12,7 @@ import {
describe('preloadMastodon()', () => {
it('creates the expected actions', async () => {
const data = await import('soapbox/__fixtures__/mastodon_initial_state.json');
const data = await import('pl-fe/__fixtures__/mastodon_initial_state.json');
__stub(mock => {
mock.onGet('/api/v1/accounts/verify_credentials')

View file

@ -3,7 +3,7 @@ import mapValues from 'lodash/mapValues';
import { verifyCredentials } from './auth';
import { importFetchedAccounts } from './importer';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch } from 'pl-fe/store';
const PLEROMA_PRELOAD_IMPORT = 'PLEROMA_PRELOAD_IMPORT' as const;
const MASTODON_PRELOAD_IMPORT = 'MASTODON_PRELOAD_IMPORT' as const;

View file

@ -7,7 +7,7 @@ import {
setAlerts,
} from './setter';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch } from 'pl-fe/store';
const changeAlerts = (path: Array<string>, value: any) =>
(dispatch: AppDispatch) => {

View file

@ -1,12 +1,12 @@
import { createPushSubscription, updatePushSubscription } from 'soapbox/actions/push-subscriptions';
import { pushNotificationsSetting } from 'soapbox/settings';
import { getVapidKey } from 'soapbox/utils/auth';
import { decode as decodeBase64 } from 'soapbox/utils/base64';
import { createPushSubscription, updatePushSubscription } from 'pl-fe/actions/push-subscriptions';
import { pushNotificationsSetting } from 'pl-fe/settings';
import { getVapidKey } from 'pl-fe/utils/auth';
import { decode as decodeBase64 } from 'pl-fe/utils/base64';
import { setBrowserSupport, setSubscription, clearSubscription } from './setter';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Me } from 'soapbox/types/soapbox';
import type { AppDispatch, RootState } from 'pl-fe/store';
import type { Me } from 'pl-fe/types/pl-fe';
// Taken from https://www.npmjs.com/package/web-push
const urlBase64ToUint8Array = (base64String: string) => {

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { CreatePushNotificationsSubscriptionParams, UpdatePushNotificationsSubscriptionParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const createPushSubscription = (params: CreatePushNotificationsSubscriptionParams) =>
(dispatch: AppDispatch, getState: () => RootState) =>

View file

@ -1,7 +1,7 @@
import { getSettings, changeSetting } from 'soapbox/actions/settings';
import { getSettings, changeSetting } from 'pl-fe/actions/settings';
import type { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const getPinnedHosts = (state: RootState) => {
const settings = getSettings(state);

View file

@ -2,8 +2,8 @@ import { getClient } from '../api';
import { openModal } from './modals';
import type { Account, Status } from 'soapbox/normalizers';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Account, Status } from 'pl-fe/normalizers';
import type { AppDispatch, RootState } from 'pl-fe/store';
const REPORT_INIT = 'REPORT_INIT' as const;
const REPORT_CANCEL = 'REPORT_CANCEL' as const;

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { PaginatedResponse, ScheduledStatus } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const SCHEDULED_STATUSES_FETCH_REQUEST = 'SCHEDULED_STATUSES_FETCH_REQUEST' as const;
const SCHEDULED_STATUSES_FETCH_SUCCESS = 'SCHEDULED_STATUSES_FETCH_SUCCESS' as const;

View file

@ -4,8 +4,8 @@ import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
import type { Search } from 'pl-api';
import type { SearchFilter } from 'soapbox/reducers/search';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { SearchFilter } from 'pl-fe/reducers/search';
import type { AppDispatch, RootState } from 'pl-fe/store';
const SEARCH_CLEAR = 'SEARCH_CLEAR' as const;
const SEARCH_SHOW = 'SEARCH_SHOW' as const;

View file

@ -1,17 +1,17 @@
/**
* Security: Pleroma-specific account management features.
* @module soapbox/actions/security
* @see module:soapbox/actions/auth
* @module pl-fe/actions/security
* @see module:pl-fe/actions/auth
*/
import { getClient } from 'soapbox/api';
import toast from 'soapbox/toast';
import { getLoggedInAccount } from 'soapbox/utils/auth';
import { normalizeUsername } from 'soapbox/utils/input';
import { getClient } from 'pl-fe/api';
import toast from 'pl-fe/toast';
import { getLoggedInAccount } from 'pl-fe/utils/auth';
import { normalizeUsername } from 'pl-fe/utils/input';
import { AUTH_LOGGED_OUT, messages } from './auth';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const FETCH_TOKENS_REQUEST = 'FETCH_TOKENS_REQUEST' as const;
const FETCH_TOKENS_SUCCESS = 'FETCH_TOKENS_SUCCESS' as const;

View file

@ -2,15 +2,15 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrde
import { defineMessage } from 'react-intl';
import { createSelector } from 'reselect';
import { patchMe } from 'soapbox/actions/me';
import { getClient } from 'soapbox/api';
import messages from 'soapbox/messages';
import { makeGetAccount } from 'soapbox/selectors';
import KVStore from 'soapbox/storage/kv-store';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { patchMe } from 'pl-fe/actions/me';
import { getClient } from 'pl-fe/api';
import messages from 'pl-fe/messages';
import { makeGetAccount } from 'pl-fe/selectors';
import KVStore from 'pl-fe/storage/kv-store';
import toast from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const SETTING_CHANGE = 'SETTING_CHANGE' as const;
const SETTING_SAVE = 'SETTING_SAVE' as const;
@ -133,9 +133,9 @@ const defaultSettings = ImmutableMap({
});
const getSettings = createSelector([
(state: RootState) => state.soapbox.get('defaultSettings'),
(state: RootState) => state.plfe.get('defaultSettings'),
(state: RootState) => state.settings,
], (soapboxSettings, settings) => defaultSettings.mergeDeep(soapboxSettings).mergeDeep(settings));
], (plFeSettings, settings) => defaultSettings.mergeDeep(plFeSettings).mergeDeep(settings));
interface SettingChangeAction {
type: typeof SETTING_CHANGE;

View file

@ -1,21 +0,0 @@
import { rootState } from 'soapbox/jest/test-helpers';
import { RootState } from 'soapbox/store';
import { getSoapboxConfig } from './soapbox';
const ASCII_HEART = '❤'; // '\u2764\uFE0F'
const RED_HEART_RGI = '❤️'; // '\u2764'
describe('getSoapboxConfig()', () => {
it('returns RGI heart on Pleroma > 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.3.0)') as RootState;
expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(true);
expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(false);
});
it('returns an ASCII heart on Pleroma < 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.0.0)') as RootState;
expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(true);
expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(false);
});
});

View file

@ -1,109 +0,0 @@
import { createSelector } from 'reselect';
import { getHost } from 'soapbox/actions/instance';
import { normalizeSoapboxConfig } from 'soapbox/normalizers';
import KVStore from 'soapbox/storage/kv-store';
import { getClient, staticFetch } from '../api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
const SOAPBOX_CONFIG_REQUEST_SUCCESS = 'SOAPBOX_CONFIG_REQUEST_SUCCESS' as const;
const SOAPBOX_CONFIG_REQUEST_FAIL = 'SOAPBOX_CONFIG_REQUEST_FAIL' as const;
const SOAPBOX_CONFIG_REMEMBER_SUCCESS = 'SOAPBOX_CONFIG_REMEMBER_SUCCESS' as const;
const getSoapboxConfig = createSelector([
(state: RootState) => state.soapbox,
(state: RootState) => state.auth.client.features,
], (soapbox, features) => {
// Do some additional normalization with the state
return normalizeSoapboxConfig(soapbox);
});
const rememberSoapboxConfig = (host: string | null) =>
(dispatch: AppDispatch) => {
return KVStore.getItemOrError(`soapbox_config:${host}`).then(soapboxConfig => {
dispatch({ type: SOAPBOX_CONFIG_REMEMBER_SUCCESS, host, soapboxConfig });
return soapboxConfig;
}).catch(() => {});
};
const fetchFrontendConfigurations = () =>
(dispatch: AppDispatch, getState: () => RootState) =>
getClient(getState).instance.getFrontendConfigurations();
/** Conditionally fetches Soapbox config depending on backend features */
const fetchSoapboxConfig = (host: string | null) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const features = getState().auth.client.features;
if (features.frontendConfigurations) {
return dispatch(fetchFrontendConfigurations()).then(data => {
if (data.pl_fe) {
dispatch(importSoapboxConfig(data.pl_fe, host));
return data.pl_fe;
} else {
return dispatch(fetchSoapboxJson(host));
}
});
} else {
return dispatch(fetchSoapboxJson(host));
}
};
/** Tries to remember the config from browser storage before fetching it */
const loadSoapboxConfig = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const host = getHost(getState());
return dispatch(rememberSoapboxConfig(host)).then(() =>
dispatch(fetchSoapboxConfig(host)),
);
};
const fetchSoapboxJson = (host: string | null) =>
(dispatch: AppDispatch) =>
staticFetch('/instance/soapbox.json').then(({ json: data }) => {
if (!isObject(data)) throw 'soapbox.json failed';
dispatch(importSoapboxConfig(data, host));
return data;
}).catch(error => {
dispatch(soapboxConfigFail(error, host));
});
const importSoapboxConfig = (soapboxConfig: APIEntity, host: string | null) => {
if (!soapboxConfig.brandColor) {
soapboxConfig.brandColor = '#0482d8';
}
return {
type: SOAPBOX_CONFIG_REQUEST_SUCCESS,
soapboxConfig,
host,
};
};
const soapboxConfigFail = (error: unknown, host: string | null) => ({
type: SOAPBOX_CONFIG_REQUEST_FAIL,
error,
skipAlert: true,
host,
});
// https://stackoverflow.com/a/46663081
const isObject = (o: any) => o instanceof Object && o.constructor === Object;
export {
SOAPBOX_CONFIG_REQUEST_SUCCESS,
SOAPBOX_CONFIG_REQUEST_FAIL,
SOAPBOX_CONFIG_REMEMBER_SUCCESS,
getSoapboxConfig,
rememberSoapboxConfig,
fetchFrontendConfigurations,
fetchSoapboxConfig,
loadSoapboxConfig,
fetchSoapboxJson,
importSoapboxConfig,
soapboxConfigFail,
};

View file

@ -1,8 +1,8 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { StatusListRecord } from 'soapbox/reducers/status-lists';
import { __stub } from 'pl-fe/api';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { StatusListRecord } from 'pl-fe/reducers/status-lists';
import { fetchStatusQuotes, expandStatusQuotes } from './status-quotes';
@ -32,7 +32,7 @@ describe('fetchStatusQuotes()', () => {
describe('with a successful API request', () => {
beforeEach(async () => {
const quotes = await import('soapbox/__fixtures__/status-quotes.json');
const quotes = await import('pl-fe/__fixtures__/status-quotes.json');
__stub((mock) => {
mock.onGet(`/api/v1/pleroma/statuses/${statusId}/quotes`).reply(200, quotes, {
@ -104,7 +104,7 @@ describe('expandStatusQuotes()', () => {
describe('with a successful API request', () => {
beforeEach(async () => {
const quotes = await import('soapbox/__fixtures__/status-quotes.json');
const quotes = await import('pl-fe/__fixtures__/status-quotes.json');
__stub((mock) => {
mock.onGet('example').reply(200, quotes, {

View file

@ -3,7 +3,7 @@ import { getClient } from '../api';
import { importFetchedStatuses } from './importer';
import type { Status as BaseStatus, PaginatedResponse } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const STATUS_QUOTES_FETCH_REQUEST = 'STATUS_QUOTES_FETCH_REQUEST' as const;
const STATUS_QUOTES_FETCH_SUCCESS = 'STATUS_QUOTES_FETCH_SUCCESS' as const;

View file

@ -1,15 +1,15 @@
import { fromJS, Map as ImmutableMap } from 'immutable';
import { STATUSES_IMPORT } from 'soapbox/actions/importer';
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { normalizeStatus } from 'soapbox/normalizers/status';
import { STATUSES_IMPORT } from 'pl-fe/actions/importer';
import { __stub } from 'pl-fe/api';
import { mockStore, rootState } from 'pl-fe/jest/test-helpers';
import { normalizeStatus } from 'pl-fe/normalizers/status';
import { deleteStatus, fetchContext } from './statuses';
describe('fetchContext()', () => {
it('handles Mitra context', async () => {
const statuses = await import('soapbox/__fixtures__/mitra-context.json');
const statuses = await import('pl-fe/__fixtures__/mitra-context.json');
__stub(mock => {
mock.onGet('/api/v1/statuses/017ed505-5926-392f-256a-f86d5075df70/context')
@ -61,7 +61,7 @@ describe('deleteStatus()', () => {
let status: any;
beforeEach(async () => {
status = await import('soapbox/__fixtures__/pleroma-status-deleted.json');
status = await import('pl-fe/__fixtures__/pleroma-status-deleted.json');
__stub((mock) => {
mock.onDelete(`/api/v1/statuses/${statusId}`).reply(200, status);

View file

@ -1,5 +1,5 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { shouldHaveCard } from 'soapbox/utils/status';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { shouldHaveCard } from 'pl-fe/utils/status';
import { getClient } from '../api';
@ -11,9 +11,9 @@ import { deleteFromTimelines } from './timelines';
import type { CreateStatusParams, Status as BaseStatus } from 'pl-api';
import type { IntlShape } from 'react-intl';
import type { Status } from 'soapbox/normalizers';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
import type { Status } from 'pl-fe/normalizers';
import type { AppDispatch, RootState } from 'pl-fe/store';
import type { APIEntity } from 'pl-fe/types/entities';
const STATUS_CREATE_REQUEST = 'STATUS_CREATE_REQUEST' as const;
const STATUS_CREATE_SUCCESS = 'STATUS_CREATE_SUCCESS' as const;

View file

@ -1,4 +1,4 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@ -6,7 +6,7 @@ import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import { insertSuggestionsIntoTimeline } from './timelines';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const SUGGESTIONS_FETCH_REQUEST = 'SUGGESTIONS_FETCH_REQUEST' as const;
const SUGGESTIONS_FETCH_SUCCESS = 'SUGGESTIONS_FETCH_SUCCESS' as const;

View file

@ -1,7 +1,7 @@
import { getClient } from '../api';
import type { PaginatedResponse, Tag } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const HASHTAG_FETCH_REQUEST = 'HASHTAG_FETCH_REQUEST' as const;
const HASHTAG_FETCH_SUCCESS = 'HASHTAG_FETCH_SUCCESS' as const;

View file

@ -1,14 +1,14 @@
import { Map as ImmutableMap } from 'immutable';
import { getLocale, getSettings } from 'soapbox/actions/settings';
import { shouldFilter } from 'soapbox/utils/timelines';
import { getLocale, getSettings } from 'pl-fe/actions/settings';
import { shouldFilter } from 'pl-fe/utils/timelines';
import { getClient } from '../api';
import { importFetchedStatus, importFetchedStatuses } from './importer';
import type { PaginatedResponse, Status as BaseStatus, PublicTimelineParams, HomeTimelineParams, ListTimelineParams, HashtagTimelineParams, GetAccountStatusesParams, GroupTimelineParams } from 'pl-api';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const TIMELINE_UPDATE = 'TIMELINE_UPDATE' as const;
const TIMELINE_DELETE = 'TIMELINE_DELETE' as const;

View file

@ -2,7 +2,7 @@ import { getClient } from '../api';
import { importFetchedStatuses } from './importer';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'pl-fe/store';
const TRENDING_STATUSES_FETCH_REQUEST = 'TRENDING_STATUSES_FETCH_REQUEST' as const;
const TRENDING_STATUSES_FETCH_SUCCESS = 'TRENDING_STATUSES_FETCH_SUCCESS' as const;

View file

@ -2,10 +2,10 @@ import { type Account as BaseAccount, accountSchema } from 'pl-api';
import { useEffect, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useAppSelector, useClient, useFeatures, useLoggedIn } from 'soapbox/hooks';
import { type Account, normalizeAccount } from 'soapbox/normalizers';
import { Entities } from 'pl-fe/entity-store/entities';
import { useEntity } from 'pl-fe/entity-store/hooks';
import { useAppSelector, useClient, useFeatures, useLoggedIn } from 'pl-fe/hooks';
import { type Account, normalizeAccount } from 'pl-fe/normalizers';
import { useRelationship } from './useRelationship';

View file

@ -1,14 +1,14 @@
import { useInfiniteQuery } from '@tanstack/react-query';
import { Entities } from 'soapbox/entity-store/entities';
import { useClient } from 'soapbox/hooks';
import { type Account, normalizeAccount } from 'soapbox/normalizers';
import { flattenPages } from 'soapbox/utils/queries';
import { Entities } from 'pl-fe/entity-store/entities';
import { useClient } from 'pl-fe/hooks';
import { type Account, normalizeAccount } from 'pl-fe/normalizers';
import { flattenPages } from 'pl-fe/utils/queries';
import { useRelationships } from './useRelationships';
import type { PaginatedResponse, Account as BaseAccount } from 'pl-api';
import type { EntityFn } from 'soapbox/entity-store/hooks/types';
import type { EntityFn } from 'pl-fe/entity-store/hooks/types';
const useAccountList = (listKey: string[], entityFn: EntityFn<void>) => {
const getAccounts = async (pageParam?: Pick<PaginatedResponse<BaseAccount>, 'next'>) => {

View file

@ -2,10 +2,10 @@ import { accountSchema, type Account as BaseAccount } from 'pl-api';
import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityLookup } from 'soapbox/entity-store/hooks';
import { useClient, useFeatures, useLoggedIn } from 'soapbox/hooks';
import { type Account, normalizeAccount } from 'soapbox/normalizers';
import { Entities } from 'pl-fe/entity-store/entities';
import { useEntityLookup } from 'pl-fe/entity-store/hooks';
import { useClient, useFeatures, useLoggedIn } from 'pl-fe/hooks';
import { type Account, normalizeAccount } from 'pl-fe/normalizers';
import { useRelationship } from './useRelationship';

View file

@ -1,7 +1,7 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { useTransaction } from 'soapbox/entity-store/hooks';
import { useAppDispatch, useClient, useLoggedIn } from 'soapbox/hooks';
import { importEntities } from 'pl-fe/entity-store/actions';
import { Entities } from 'pl-fe/entity-store/entities';
import { useTransaction } from 'pl-fe/entity-store/hooks';
import { useAppDispatch, useClient, useLoggedIn } from 'pl-fe/hooks';
interface FollowOpts {
reblogs?: boolean;

View file

@ -1,9 +1,9 @@
import { type Relationship, relationshipSchema } from 'pl-api';
import { z } from 'zod';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useClient } from 'soapbox/hooks';
import { Entities } from 'pl-fe/entity-store/entities';
import { useEntity } from 'pl-fe/entity-store/hooks';
import { useClient } from 'pl-fe/hooks';
interface UseRelationshipOpts {
enabled?: boolean;

View file

@ -1,8 +1,8 @@
import { type Relationship, relationshipSchema } from 'pl-api';
import { Entities } from 'soapbox/entity-store/entities';
import { useBatchedEntities } from 'soapbox/entity-store/hooks/useBatchedEntities';
import { useClient, useLoggedIn } from 'soapbox/hooks';
import { Entities } from 'pl-fe/entity-store/entities';
import { useBatchedEntities } from 'pl-fe/entity-store/hooks/useBatchedEntities';
import { useClient, useLoggedIn } from 'pl-fe/hooks';
const useRelationships = (listKey: string[], accountIds: string[]) => {
const client = useClient();

View file

@ -1,8 +1,8 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'soapbox/hooks';
import { queryClient } from 'soapbox/queries/client';
import { adminAnnouncementSchema, type AdminAnnouncement } from 'soapbox/schemas';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { adminAnnouncementSchema, type AdminAnnouncement } from 'pl-fe/schemas';
import { useAnnouncements as useUserAnnouncements } from '../announcements';

View file

@ -1,8 +1,8 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'soapbox/hooks';
import { queryClient } from 'soapbox/queries/client';
import { domainSchema, type Domain } from 'soapbox/schemas';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { domainSchema, type Domain } from 'pl-fe/schemas';
interface CreateDomainParams {
domain: string;

View file

@ -1,7 +1,7 @@
import { useInfiniteQuery } from '@tanstack/react-query';
import { useClient } from 'soapbox/hooks';
import { moderationLogEntrySchema, type ModerationLogEntry } from 'soapbox/schemas';
import { useClient } from 'pl-fe/hooks';
import { moderationLogEntrySchema, type ModerationLogEntry } from 'pl-fe/schemas';
interface ModerationLogResult {
items: ModerationLogEntry[];

View file

@ -1,8 +1,8 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'soapbox/hooks';
import { queryClient } from 'soapbox/queries/client';
import { relaySchema, type Relay } from 'soapbox/schemas';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { relaySchema, type Relay } from 'pl-fe/schemas';
const useRelays = () => {
const client = useClient();

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