Compare commits

..

No commits in common. "70f6b85a21510f1d141cf1c1348e51b9aaf9bea0" and "31287c88995feb4cc6130ad8b0ee2f9534e224c0" have entirely different histories.

48 changed files with 1094 additions and 1100 deletions

View file

@ -57,7 +57,7 @@ steps:
- pull_request - pull_request
- name: web-setup - name: web-setup
image: node:20-alpine image: node:18-alpine
volumes: volumes:
- name: yarn_cache - name: yarn_cache
path: /tmp/cache path: /tmp/cache
@ -72,7 +72,7 @@ steps:
- pull_request - pull_request
- name: web-lint - name: web-lint
image: node:20-alpine image: node:18-alpine
commands: commands:
- yarn --cwd ./web/source lint - yarn --cwd ./web/source lint
depends_on: depends_on:
@ -83,7 +83,7 @@ steps:
- pull_request - pull_request
- name: web-build - name: web-build
image: node:20-alpine image: node:18-alpine
commands: commands:
- yarn --cwd ./web/source build - yarn --cwd ./web/source build
depends_on: depends_on:
@ -224,3 +224,5 @@ steps:
--- ---
kind: signature kind: signature
hmac: 1b89e3a538fbca72eb9a0b398cd82f09a774ba3649013e19d36012eda327e83f hmac: 1b89e3a538fbca72eb9a0b398cd82f09a774ba3649013e19d36012eda327e83f
...

View file

@ -3,9 +3,6 @@
"go.lintFlags": [ "go.lintFlags": [
"--fast" "--fast"
], ],
"go.testEnvVars": {
"WAZERO_COMPILATION_CACHE": "~/.cache/wazero"
},
"gopls": { "gopls": {
"analyses": { "analyses": {
"composites": false "composites": false
@ -22,9 +19,5 @@
], ],
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit" "source.fixAll.eslint": "explicit"
}, }
"html.format.wrapLineLength": 0,
"html.format.wrapAttributes": "preserve",
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
} }

View file

@ -19,7 +19,7 @@ WORKDIR /go/src/github.com/superseriousbusiness/gotosocial
RUN /go/bin/swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models RUN /go/bin/swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models
# stage 2: generate the web/assets/dist bundles # stage 2: generate the web/assets/dist bundles
FROM --platform=${BUILDPLATFORM} node:20-alpine AS bundler FROM --platform=${BUILDPLATFORM} node:18-alpine AS bundler
COPY web web COPY web web
RUN yarn --cwd ./web/source install && \ RUN yarn --cwd ./web/source install && \

View file

@ -1780,7 +1780,7 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIStatusPendingApproval()
"muted": false, "muted": false,
"bookmarked": false, "bookmarked": false,
"pinned": false, "pinned": false,
"content": "<p>Hi <span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span>, can I reply?</p><hr><p><i lang=\"en\"> Note from localhost:8080: This reply is pending your approval. You can quickly accept it by liking, boosting or replying to it. You can also accept or reject it at the following link: <a href=\"http://localhost:8080/settings/user/interaction-requests/01J5QVXCCEATJYSXM9H6MZT4JR\" rel=\"noreferrer noopener nofollow\" target=\"_blank\">http://localhost:8080/settings/user/interaction-requests/01J5QVXCCEATJYSXM9H6MZT4JR</a>.</i></p>", "content": "<p>Hi <span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span>, can I reply?</p><hr><p><i lang=\"en\"> Note from localhost:8080: This reply is pending your approval. You can quickly accept it by liking, boosting or replying to it. You can also accept or reject it at the following link: <a href=\"http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR\" rel=\"noreferrer noopener nofollow\" target=\"_blank\">http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR</a>.</i></p>",
"reblog": null, "reblog": null,
"application": { "application": {
"name": "superseriousbusiness", "name": "superseriousbusiness",

View file

@ -214,8 +214,8 @@ func (c *Converter) pendingReplyNote(
// Build the settings panel URL at which the user // Build the settings panel URL at which the user
// can view + approve/reject the interaction request. // can view + approve/reject the interaction request.
// //
// Eg., https://example.org/settings/user/interaction-requests/01J5QVXCCEATJYSXM9H6MZT4JR // Eg., https://example.org/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR
settingsURL = proto + "://" + host + "/settings/user/interaction-requests/" + intReq.ID settingsURL = proto + "://" + host + "/settings/user/interaction_requests/" + intReq.ID
) )
var note strings.Builder var note strings.Builder

View file

@ -29,8 +29,7 @@ module.exports = [
} }
}, },
plugins: { plugins: {
"license-header": require("eslint-plugin-license-header"), "license-header": require("eslint-plugin-license-header")
"only-warn": require("eslint-plugin-only-warn")
}, },
rules: { rules: {
"license-header/header": ["error", __dirname + "/.license-header.js"] "license-header/header": ["error", __dirname + "/.license-header.js"]

View file

@ -47,7 +47,7 @@
"@babel/preset-typescript": "^7.24.1", "@babel/preset-typescript": "^7.24.1",
"@browserify/envify": "^6.0.0", "@browserify/envify": "^6.0.0",
"@browserify/uglifyify": "^6.0.0", "@browserify/uglifyify": "^6.0.0",
"@f0x52/eslint-config": "^2.0.11", "@f0x52/eslint-config": "^2.0.9",
"@types/html-to-text": "^9.0.4", "@types/html-to-text": "^9.0.4",
"@types/is-valid-domain": "^0.0.2", "@types/is-valid-domain": "^0.0.2",
"@types/papaparse": "^5.3.9", "@types/papaparse": "^5.3.9",
@ -62,7 +62,6 @@
"css-extract": "^2.0.0", "css-extract": "^2.0.0",
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-plugin-license-header": "^0.6.0", "eslint-plugin-license-header": "^0.6.0",
"eslint-plugin-only-warn": "^1.1.0",
"factor-bundle": "^2.5.0", "factor-bundle": "^2.5.0",
"icssify": "^2.0.0", "icssify": "^2.0.0",
"postcss": "^8.4.18", "postcss": "^8.4.18",

View file

@ -39,9 +39,9 @@ export default function UserLogoutCard() {
return ( return (
<div className="account-card"> <div className="account-card">
<img className="avatar" src={profile.avatar} alt="" /> <img className="avatar" src={profile.avatar} alt="" />
<b className="text-cutoff">{profile.display_name.length > 0 ? profile.display_name : profile.acct}</b> <h3 className="text-cutoff">{profile.display_name?.length > 0 ? profile.display_name : profile.acct}</h3>
<span className="text-cutoff">@{profile.username}@{instance?.account_domain}</span> <span className="text-cutoff">@{profile.username}@{instance?.account_domain}</span>
<a onClick={() => void logoutQuery()} href="#" aria-label="Log out" title="Log out" className="logout"> <a onClick={logoutQuery} href="#" aria-label="Log out" title="Log out" className="logout">
<i className="fa fa-fw fa-sign-out" aria-hidden="true" /> <i className="fa fa-fw fa-sign-out" aria-hidden="true" />
</a> </a>
</div> </div>

View file

@ -188,7 +188,7 @@ const extended = gtsApi.injectEndpoints({
return { data: null }; return { data: null };
}, },
}), }),
logout: build.mutation<null, void>({ logout: build.mutation({
queryFn: (_arg, api) => { queryFn: (_arg, api) => {
api.dispatch(oauthRemove()); api.dispatch(oauthRemove());
return { data: null }; return { data: null };

View file

@ -18,13 +18,9 @@
*/ */
import React from "react"; import React from "react";
import { Redirect, Route, Router, Switch } from "wouter";
import { BaseUrlContext, useBaseUrl } from "../../../lib/navigation/util";
import InteractionRequestDetail from "./detail";
import InteractionRequestsSearchForm from "./search"; import InteractionRequestsSearchForm from "./search";
function InteractionRequests() { export default function InteractionRequests() {
return ( return (
<div className="interaction-requests-view"> <div className="interaction-requests-view">
<div className="form-section-docs"> <div className="form-section-docs">
@ -38,25 +34,3 @@ function InteractionRequests() {
</div> </div>
); );
} }
/**
* - /settings/users/interaction-requests/search
* - /settings/users/interaction-requests/{reqId}
*/
export default function InteractionRequestsRouter() {
const parentUrl = useBaseUrl();
const thisBase = "/interaction-requests";
const absBase = parentUrl + thisBase;
return (
<BaseUrlContext.Provider value={absBase}>
<Router base={thisBase}>
<Switch>
<Route path="/search" component={InteractionRequests} />
<Route path="/:reqId" component={InteractionRequestDetail} />
<Redirect to="/search" />
</Switch>
</Router>
</BaseUrlContext.Provider>
);
}

View file

@ -45,7 +45,7 @@ export default function UserMenu() {
/> />
<MenuItem <MenuItem
name="Interaction Requests" name="Interaction Requests"
itemUrl="interaction-requests" itemUrl="interaction_requests"
icon="fa-commenting-o" icon="fa-commenting-o"
/> />
<MenuItem <MenuItem

View file

@ -26,7 +26,8 @@ import UserMigration from "./migration";
import PostSettings from "./posts"; import PostSettings from "./posts";
import EmailPassword from "./emailpassword"; import EmailPassword from "./emailpassword";
import ExportImport from "./export-import"; import ExportImport from "./export-import";
import InteractionRequestsRouter from "./interactions"; import InteractionRequests from "./interactions";
import InteractionRequestDetail from "./interactions/detail";
/** /**
* - /settings/user/profile * - /settings/user/profile
@ -34,7 +35,7 @@ import InteractionRequestsRouter from "./interactions";
* - /settings/user/emailpassword * - /settings/user/emailpassword
* - /settings/user/migration * - /settings/user/migration
* - /settings/user/export-import * - /settings/user/export-import
* - /settings/users/interaction-requests * - /settings/users/interaction_requests
*/ */
export default function UserRouter() { export default function UserRouter() {
const baseUrl = useBaseUrl(); const baseUrl = useBaseUrl();
@ -51,11 +52,33 @@ export default function UserRouter() {
<Route path="/emailpassword" component={EmailPassword} /> <Route path="/emailpassword" component={EmailPassword} />
<Route path="/migration" component={UserMigration} /> <Route path="/migration" component={UserMigration} />
<Route path="/export-import" component={ExportImport} /> <Route path="/export-import" component={ExportImport} />
<Route path="/interaction-requests/*?" component={InteractionRequestsRouter} /> <InteractionRequestsRouter />
<Redirect to="/profile" /> <Route><Redirect to="/profile" /></Route>
</Switch> </Switch>
</ErrorBoundary> </ErrorBoundary>
</Router> </Router>
</BaseUrlContext.Provider> </BaseUrlContext.Provider>
); );
} }
/**
* - /settings/users/interaction_requests/search
* - /settings/users/interaction_requests/{reqId}
*/
function InteractionRequestsRouter() {
const parentUrl = useBaseUrl();
const thisBase = "/interaction_requests";
const absBase = parentUrl + thisBase;
return (
<BaseUrlContext.Provider value={absBase}>
<Router base={thisBase}>
<Switch>
<Route path="/search" component={InteractionRequests} />
<Route path="/:reqId" component={InteractionRequestDetail} />
<Route><Redirect to="/search"/></Route>
</Switch>
</Router>
</BaseUrlContext.Provider>
);
}

View file

@ -1345,10 +1345,10 @@
dependencies: dependencies:
levn "^0.4.1" levn "^0.4.1"
"@f0x52/eslint-config@^2.0.11": "@f0x52/eslint-config@^2.0.9":
version "2.0.11" version "2.0.9"
resolved "https://registry.yarnpkg.com/@f0x52/eslint-config/-/eslint-config-2.0.11.tgz#a8f1cdc057344b6fa61794b7bea437f0b6e269c5" resolved "https://registry.yarnpkg.com/@f0x52/eslint-config/-/eslint-config-2.0.9.tgz#96320799d6c1ecaabd663091a796a765ca075869"
integrity sha512-QsNeb3uQ/CR5XNKbI98ThchD2vj4IjMh8oEMoFQiB7ae51NCUruSQiE91hq4IvvXGZy4li61loavO4avbm6DJA== integrity sha512-4XiXUe6wMm5btpMBXpkB90W6aSl4EtuUSmswc9LtsByTvmYQ4+dn0zXoRh2WkWzvZx/VHFIxqu73BMeHHzBDxg==
dependencies: dependencies:
"@eslint/js" "^9.11.0" "@eslint/js" "^9.11.0"
"@stylistic/eslint-plugin" "^2.8.0" "@stylistic/eslint-plugin" "^2.8.0"
@ -3541,11 +3541,6 @@ eslint-plugin-license-header@^0.6.0:
dependencies: dependencies:
requireindex "^1.2.0" requireindex "^1.2.0"
eslint-plugin-only-warn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-only-warn/-/eslint-plugin-only-warn-1.1.0.tgz#c6ddc37ddc4e72c121f07be565fcb7b6671fe78a"
integrity sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==
eslint-scope@^8.2.0: eslint-scope@^8.2.0:
version "8.2.0" version "8.2.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442"

View file

@ -23,13 +23,10 @@ Someone has submitted a new account sign-up to your instance.
They provided the following details: They provided the following details:
Email address: Email address: {{ .SignupEmail }}
{{ .SignupEmail }} Username: {{ .SignupUsername }}
Username:
{{ .SignupUsername }}
{{- if .SignupReason }} {{- if .SignupReason }}
Reason: Reason: {{ .SignupReason }}
{{ .SignupReason }}
{{- end }} {{- end }}
To view the sign-up, paste the following link into your browser: {{ .SignupURL }} To view the sign-up, paste the following link into your browser: {{ .SignupURL }}

View file

@ -26,7 +26,8 @@
href="{{ .URL }}" href="{{ .URL }}"
class="nounderline" class="nounderline"
rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener"
target="_blank"> target="_blank"
>
@{{ .Username }} @{{ .Username }}
</a> </a>
</b> </b>
@ -41,47 +42,48 @@
{{- define "avatarWidth" -}} {{- define "avatarWidth" -}}
{{- with .account }} {{- with .account }}
{{- if isNil .AvatarAttachment -}} {{- if isNil .AvatarAttachment -}}
{{- template "defaultAvatarDimension" . -}} {{- template "defaultAvatarDimension" . -}}
{{- else -}} {{- else -}}
{{- /* Use the avatar's proper dimensions. */ -}} {{- /* Use the avatar's proper dimensions. */ -}}
{{- .AvatarAttachment.Meta.Original.Width -}} {{- .AvatarAttachment.Meta.Original.Width -}}
{{- end -}} {{- end -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "avatarHeight" -}} {{- define "avatarHeight" -}}
{{- with .account }} {{- with .account }}
{{- if isNil .AvatarAttachment -}} {{- if isNil .AvatarAttachment -}}
{{- template "defaultAvatarDimension" . -}} {{- template "defaultAvatarDimension" . -}}
{{- else -}} {{- else -}}
{{- /* Use the avatar's proper dimensions. */ -}} {{- /* Use the avatar's proper dimensions. */ -}}
{{- .AvatarAttachment.Meta.Original.Height -}} {{- .AvatarAttachment.Meta.Original.Height -}}
{{- end -}} {{- end -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "avatarAlt" -}} {{- define "avatarAlt" -}}
Avatar for {{ .account.Username -}} Avatar for {{ .account.Username -}}
{{- if .account.AvatarDescription }} {{- if .account.AvatarDescription }}
{{- /* Add the avatar's image description. */ -}} {{- /* Add the avatar's image description. */ -}}
: {{ .account.AvatarDescription -}} : {{ .account.AvatarDescription -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "headerAlt" -}} {{- define "headerAlt" -}}
Header for {{ .account.Username -}} Header for {{ .account.Username -}}
{{- if .account.HeaderDescription }} {{- if .account.HeaderDescription }}
{{- /* Add the header's image description. */ -}} {{- /* Add the header's image description. */ -}}
: {{ .account.HeaderDescription -}} : {{ .account.HeaderDescription -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "avatar" -}} {{- define "avatar" -}}
{{- with . }} {{- with . }}
<div <div
class="media photoswipe-gallery odd single avatar-image-wrapper" class="media photoswipe-gallery odd single avatar-image-wrapper"
role="group"> role="group"
>
<a <a
class="photoswipe-slide" class="photoswipe-slide"
href="{{- .account.Avatar -}}" href="{{- .account.Avatar -}}"
@ -90,15 +92,18 @@ Header for {{ .account.Username -}}
data-pswp-height="{{- template "avatarHeight" . -}}px" data-pswp-height="{{- template "avatarHeight" . -}}px"
data-cropped="true" data-cropped="true"
alt="{{- template "avatarAlt" . -}}" alt="{{- template "avatarAlt" . -}}"
title="{{- template "avatarAlt" . -}}"> title="{{- template "avatarAlt" . -}}"
>
<picture <picture
aria-hidden="true"> aria-hidden="true"
>
{{- if .account.AvatarAttachment }} {{- if .account.AvatarAttachment }}
<source <source
class="avatar" class="avatar"
srcset="{{- .account.AvatarStatic -}}" srcset="{{- .account.AvatarStatic -}}"
type="{{- .account.AvatarAttachment.PreviewMIMEType -}}" type="{{- .account.AvatarAttachment.PreviewMIMEType -}}"
media="(prefers-reduced-motion: reduce)" /> media="(prefers-reduced-motion: reduce)"
/>
{{- end }} {{- end }}
<img <img
class="avatar" class="avatar"
@ -106,7 +111,8 @@ Header for {{ .account.Username -}}
alt="{{- template "avatarAlt" . -}}" alt="{{- template "avatarAlt" . -}}"
title="{{- template "avatarAlt" . -}}" title="{{- template "avatarAlt" . -}}"
width="{{- template "avatarWidth" . -}}" width="{{- template "avatarWidth" . -}}"
height="{{- template "avatarHeight" . -}}" /> height="{{- template "avatarHeight" . -}}"
/>
</picture> </picture>
</a> </a>
</div> </div>
@ -126,12 +132,14 @@ Header for {{ .account.Username -}}
<source <source
srcset="{{- .account.HeaderStatic -}}" srcset="{{- .account.HeaderStatic -}}"
type="{{- .account.HeaderAttachment.PreviewMIMEType -}}" type="{{- .account.HeaderAttachment.PreviewMIMEType -}}"
media="(prefers-reduced-motion: reduce)" /> media="(prefers-reduced-motion: reduce)"
/>
{{- end }} {{- end }}
<img <img
src="{{- .account.Header -}}" src="{{- .account.Header -}}"
alt="{{- template "headerAlt" . -}}" alt="{{- template "headerAlt" . -}}"
title="{{- template "headerAlt" . -}}" /> title="{{- template "headerAlt" . -}}"
/>
</picture> </picture>
</div> </div>
<div class="basic-info"> <div class="basic-info">
@ -155,7 +163,8 @@ Header for {{ .account.Username -}}
<div <div
class="bot-legend-wrapper" class="bot-legend-wrapper"
aria-hidden="true" aria-hidden="true"
title="This is a bot account."> title="This is a bot account."
>
<i class="bot-icon fa fa-microchip"></i> <i class="bot-icon fa fa-microchip"></i>
<span class="bot-legend">bot</span> <span class="bot-legend">bot</span>
</div> </div>
@ -212,7 +221,8 @@ Header for {{ .account.Username -}}
{{- range .pinned_statuses }} {{- range .pinned_statuses }}
<article <article
class="status expanded" class="status expanded"
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}> {{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
>
{{- include "status.tmpl" . | indent 6 }} {{- include "status.tmpl" . | indent 6 }}
</article> </article>
{{- end }} {{- end }}
@ -235,7 +245,8 @@ Header for {{ .account.Username -}}
{{- range .statuses }} {{- range .statuses }}
<article <article
class="status expanded" class="status expanded"
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}> {{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
>
{{- include "status.tmpl" . | indent 6 }} {{- include "status.tmpl" . | indent 6 }}
</article> </article>
{{- end }} {{- end }}

View file

@ -90,8 +90,9 @@ media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{
{{- if .Description }} {{- if .Description }}
alt="{{- $media.Description -}}" alt="{{- $media.Description -}}"
title="{{- $media.Description -}}" title="{{- $media.Description -}}"
{{- end }}> {{- end }}
<source type="{{- $media.MIMEType -}}" src="{{- $media.URL -}}" /> >
<source type="{{- $media.MIMEType -}}" src="{{- $media.URL -}}"/>
</video> </video>
{{- else if eq .Type "audio" }} {{- else if eq .Type "audio" }}
<video <video