diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cdf22dd2e..008550826 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ image: node:18 variables: NODE_ENV: test +default: + interruptible: true + cache: &cache key: files: @@ -25,7 +28,6 @@ deps: cache: <<: *cache policy: push - interruptible: true danger: stage: test @@ -33,8 +35,10 @@ danger: # https://github.com/danger/danger-js/issues/1029#issuecomment-998915436 - export CI_MERGE_REQUEST_IID=${CI_OPEN_MERGE_REQUESTS#*!} - npx danger ci + except: + refs: + - $CI_DEFAULT_BRANCH allow_failure: true - interruptible: true lint-js: stage: test @@ -47,7 +51,6 @@ lint-js: - "**/*.tsx" - ".eslintignore" - ".eslintrc.js" - interruptible: true lint-sass: stage: test @@ -57,7 +60,6 @@ lint-sass: - "**/*.scss" - "**/*.css" - ".stylelintrc.json" - interruptible: true jest: stage: test @@ -80,27 +82,30 @@ jest: coverage_report: coverage_format: cobertura path: .coverage/cobertura-coverage.xml - interruptible: true nginx-test: stage: test image: nginx:latest - before_script: cp installation/mastodon.conf /etc/nginx/conf.d/default.conf + before_script: + - cp installation/mastodon.conf /etc/nginx/conf.d/default.conf script: nginx -t only: changes: - "installation/mastodon.conf" - interruptible: true build-production: stage: test - script: yarn build + script: + - yarn build + - yarn manage:translations en + # Fail if files got changed. + # https://stackoverflow.com/a/9066385 + - git diff --quiet variables: NODE_ENV: production artifacts: paths: - static - interruptible: true docs-deploy: stage: deploy @@ -111,21 +116,9 @@ docs-deploy: - curl -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' https://gitlab.com/api/v4/projects/15685485/trigger/pipeline only: refs: - - develop + - $CI_DEFAULT_BRANCH changes: - "docs/**/*" - interruptible: true - -# Supposed to fail when translations are outdated, instead always passes -# -# i18n: -# stage: build -# script: yarn manage:translations -# variables: -# NODE_ENV: development -# before_script: -# - yarn -# - yarn build review: stage: deploy @@ -135,7 +128,6 @@ review: script: - npx -y surge static $CI_COMMIT_REF_SLUG.git.soapbox.pub allow_failure: true - interruptible: true pages: stage: deploy @@ -150,8 +142,7 @@ pages: - public only: refs: - - develop - interruptible: true + - $CI_DEFAULT_BRANCH docker: stage: deploy @@ -167,5 +158,8 @@ docker: - docker push $CI_REGISTRY_IMAGE only: refs: - - develop - interruptible: true \ No newline at end of file + - $CI_DEFAULT_BRANCH + +include: + - template: Jobs/Dependency-Scanning.gitlab-ci.yml + - template: Security/License-Scanning.gitlab-ci.yml \ No newline at end of file diff --git a/.gitlab/merge_request_templates/BeforeAndAfter.md b/.gitlab/merge_request_templates/BeforeAndAfter.md new file mode 100644 index 000000000..6e457a708 --- /dev/null +++ b/.gitlab/merge_request_templates/BeforeAndAfter.md @@ -0,0 +1,8 @@ +## Summary + + + +## Screenshots (if appropriate): +| Before | After | +| ------ | ----- | +| | | diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 57a35ab4f..d1762aa9a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,6 +3,7 @@ "dbaeumer.vscode-eslint", "bradlc.vscode-tailwindcss", "stylelint.vscode-stylelint", - "wix.vscode-import-cost" + "wix.vscode-import-cost", + "redhat.vscode-yaml" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a7155a74..d7ca13345 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,15 @@ "*.conf.template": "properties" }, "files.eol": "\n", - "files.insertFinalNewline": false + "files.insertFinalNewline": false, + "json.schemas": [ + { + "fileMatch": [".lintstagedrc.json"], + "url": "https://json.schemastore.org/lintstagedrc.schema.json" + }, + { + "fileMatch": ["renovate.json"], + "url": "https://docs.renovatebot.com/renovate-schema.json" + } + ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 268d5caad..490404721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Compatibility: rudimentary support for Takahē. ### Changed +- Posts: letterbox images to 19:6 again. ### Fixed +- Layout: use accent color for "floating action button" (mobile compose button). +- ServiceWorker: don't serve favicon, robots.txt, and others from ServiceWorker. ## [3.0.0] - 2022-12-25 diff --git a/app/soapbox/actions/scheduled-statuses.ts b/app/soapbox/actions/scheduled-statuses.ts index ddc550105..33e763701 100644 --- a/app/soapbox/actions/scheduled-statuses.ts +++ b/app/soapbox/actions/scheduled-statuses.ts @@ -1,3 +1,5 @@ +import { getFeatures } from 'soapbox/utils/features'; + import api, { getLinks } from '../api'; import type { AxiosError } from 'axios'; @@ -18,10 +20,17 @@ const SCHEDULED_STATUS_CANCEL_FAIL = 'SCHEDULED_STATUS_CANCEL_FAIL'; const fetchScheduledStatuses = () => (dispatch: AppDispatch, getState: () => RootState) => { - if (getState().status_lists.get('scheduled_statuses')?.isLoading) { + const state = getState(); + + if (state.status_lists.get('scheduled_statuses')?.isLoading) { return; } + const instance = state.instance; + const features = getFeatures(instance); + + if (!features.scheduledStatuses) return; + dispatch(fetchScheduledStatusesRequest()); api(getState).get('/api/v1/scheduled_statuses').then(response => { diff --git a/app/soapbox/actions/trending-statuses.ts b/app/soapbox/actions/trending-statuses.ts index 435fcf6df..7ccab27ab 100644 --- a/app/soapbox/actions/trending-statuses.ts +++ b/app/soapbox/actions/trending-statuses.ts @@ -17,6 +17,8 @@ const fetchTrendingStatuses = () => const instance = state.instance; const features = getFeatures(instance); + if (!features.trendingStatuses && !features.trendingTruths) return; + dispatch({ type: TRENDING_STATUSES_FETCH_REQUEST }); return api(getState).get(features.trendingTruths ? '/api/v1/truth/trending/truths' : '/api/v1/trends/statuses').then(({ data: statuses }) => { dispatch(importFetchedStatuses(statuses)); diff --git a/app/soapbox/api/index.ts b/app/soapbox/api/index.ts index 840c0322a..c7fcb6230 100644 --- a/app/soapbox/api/index.ts +++ b/app/soapbox/api/index.ts @@ -62,7 +62,6 @@ export const baseClient = (accessToken?: string | null, baseURL: string = ''): A headers: Object.assign(accessToken ? { 'Authorization': `Bearer ${accessToken}`, } : {}), - transformResponse: [maybeParseJSON], }); }; diff --git a/app/soapbox/components/autosuggest-account-input.tsx b/app/soapbox/components/autosuggest-account-input.tsx index b2a205e3c..dc05b8be2 100644 --- a/app/soapbox/components/autosuggest-account-input.tsx +++ b/app/soapbox/components/autosuggest-account-input.tsx @@ -53,8 +53,7 @@ const AutosuggestAccountInput: React.FC = ({ setAccountIds(ImmutableOrderedSet(accountIds)); }) .catch(noOp); - - }, 900, { leading: true, trailing: true }), [limit]); + }, 900, { leading: false, trailing: true }), [limit]); const handleChange: React.ChangeEventHandler = e => { refreshCancelToken(); diff --git a/app/soapbox/components/media-gallery.tsx b/app/soapbox/components/media-gallery.tsx index 722f5540a..cd7cd2605 100644 --- a/app/soapbox/components/media-gallery.tsx +++ b/app/soapbox/components/media-gallery.tsx @@ -294,7 +294,7 @@ const MediaGallery: React.FC = (props) => { const aspectRatio = media.getIn([0, 'meta', 'original', 'aspect']) as number | undefined; const getHeight = () => { - if (!aspectRatio) return w; + if (!aspectRatio) return w * 9 / 16; if (isPanoramic(aspectRatio)) return Math.floor(w / maximumAspectRatio); if (isPortrait(aspectRatio)) return Math.floor(w / minimumAspectRatio); return Math.floor(w / aspectRatio); diff --git a/app/soapbox/components/sidebar-menu.tsx b/app/soapbox/components/sidebar-menu.tsx index 80a292ec9..34fd62260 100644 --- a/app/soapbox/components/sidebar-menu.tsx +++ b/app/soapbox/components/sidebar-menu.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/interactive-supports-focus */ import classNames from 'clsx'; import React from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; @@ -136,218 +137,234 @@ const SidebarMenu: React.FC = (): JSX.Element | null => { return (
- -
- -
-
-
- - - - - - - + /> + +
+
+ + +
+
- + + + - - {(account.locked || followRequestsCount > 0) && ( - - )} - - {features.bookmarks && ( - - )} + + - {features.lists && ( - )} - {features.events && ( - - )} + {(account.locked || followRequestsCount > 0) && ( + + )} - {settings.get('isDeveloper') && ( - - )} + {features.bookmarks && ( + + )} - {features.publicTimeline && <> - + {features.lists && ( + + )} - : } - onClick={onClose} - /> + {features.events && ( + + )} - {features.federating && ( + {settings.get('isDeveloper') && ( } + to='/developers' + icon={require('@tabler/icons/code.svg')} + text={intl.formatMessage(messages.developers)} onClick={onClose} /> )} - } - + {features.publicTimeline && <> + - + : } + onClick={onClose} + /> - + {features.federating && ( + } + onClick={onClose} + /> + )} + } - + - {features.federating && ( - )} - {features.filters && ( - )} - {account.admin && ( - )} - {features.import && ( - - )} - - + {features.federating && ( + + )} - + {features.filters && ( + + )} - + {account.admin && ( + + )} - - - - {switcher && ( -
- {otherAccounts.map(account => renderAccount(account))} - - - - {intl.formatMessage(messages.addAccount)} - -
+ {features.import && ( + )} + + + + + + + + + + + {switcher && ( +
+ {otherAccounts.map(account => renderAccount(account))} + + + + {intl.formatMessage(messages.addAccount)} + +
+ )} +
-
+
+ + {/* Dummy element to keep Close Icon visible */} +
); diff --git a/app/soapbox/components/ui/select/select.tsx b/app/soapbox/components/ui/select/select.tsx index 8c2369ce5..e405fa240 100644 --- a/app/soapbox/components/ui/select/select.tsx +++ b/app/soapbox/components/ui/select/select.tsx @@ -11,7 +11,7 @@ const Select = React.forwardRef((props, ref) => { return (