Porównaj commity

...

19 Commity
v0.3.0 ... main

Autor SHA1 Wiadomość Data
Namekuji 7adba191e6
Add link to Hamabē 2024-02-15 21:57:46 -05:00
Namekuji 3cc4ee4f84
use native 2023-07-02 12:04:34 -04:00
Namekuji a606f7f4fb
remove png 2023-07-02 11:51:52 -04:00
Namekuji 1bb384a10c
fix bot url 2023-07-02 02:43:02 -04:00
Namekuji 0fc4e5fbec
update introduction 2023-05-28 08:59:39 -04:00
Namekuji 30cc7930fc
disable avatar conversion 2023-05-28 08:36:24 -04:00
Namekuji 6c4ef49085
reduce sound effect volumes 2023-05-28 08:08:20 -04:00
Namekuji 85979a7ebf
remove avatar restore 2023-05-26 10:32:52 -04:00
Namekuji 6f7b58f2e2 fix mic status label 2023-04-28 21:16:23 -04:00
Namekuji 03e5cb4f02 bump version 2023-04-28 14:16:52 -04:00
Namekuji 87300ea112 remove docker 2023-04-28 14:15:43 -04:00
Namekuji 7b837651dd add aria-label to buttons missing content 2023-04-28 14:15:24 -04:00
Namekuji c40fb71147 use rootless 2023-04-28 13:32:50 -04:00
Namekuji d52ae18c44 disable avatar update 2023-04-28 09:31:40 -04:00
Namekuji 3138e2a596 fix returning string 2023-03-22 10:45:00 -04:00
Namekuji 80963c96e6 fix oauth redirect_uri 2023-03-22 10:14:00 -04:00
Namekuji 32dbfbc205 use png twemoji 2023-02-20 17:39:27 -05:00
Namekuji e2a5fb6fd6 fix import error 2023-02-20 15:12:47 -05:00
Namekuji f11d4f016a use twemoji 2023-02-20 15:08:35 -05:00
23 zmienionych plików z 2496 dodań i 3869 usunięć

Wyświetl plik

@ -16,7 +16,7 @@ audon.localhost {
} }
} }
livekit.audon.localhost { livekit.localhost {
tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem
encode zstd gzip encode zstd gzip
reverse_proxy livekit:7880 reverse_proxy livekit:7880

Wyświetl plik

@ -6,7 +6,7 @@
// "image": "mcr.microsoft.com/devcontainers/universal:2-linux" // "image": "mcr.microsoft.com/devcontainers/universal:2-linux"
"dockerComposeFile": "docker-compose.dev.yaml", "dockerComposeFile": "docker-compose.dev.yaml",
"service": "devcontainer", "service": "devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceFolder": "/audon-go",
// Features to add to the dev container. More info: https://containers.dev/features. // Features to add to the dev container. More info: https://containers.dev/features.
"features": { "features": {
@ -33,8 +33,8 @@
"EditorConfig.EditorConfig" "EditorConfig.EditorConfig"
] ]
} }
} },
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root" "remoteUser": "root"
} }

Wyświetl plik

@ -2,10 +2,12 @@ version: '3.1'
services: services:
devcontainer: devcontainer:
image: "mcr.microsoft.com/devcontainers/base:jammy" image: "mcr.microsoft.com/devcontainers/base:debian"
volumes: volumes:
- ../..:/workspaces:cached - ..:/audon-go:cached
command: sleep infinity command: sleep infinity
environment:
- "DOCKER_HOST=unix:///run/user/1000/docker.sock"
db: db:
image: mongo:6 image: mongo:6

1
.gitignore vendored
Wyświetl plik

@ -66,6 +66,7 @@ build/Release
# Dependency directories # Dependency directories
node_modules/ node_modules/
jspm_packages/ jspm_packages/
.pnpm-store/
# Snowpack dependency directory (https://snowpack.dev/) # Snowpack dependency directory (https://snowpack.dev/)
web_modules/ web_modules/

Wyświetl plik

@ -4,8 +4,9 @@ WORKDIR /workspace
COPY audon-fe/ /workspace/ COPY audon-fe/ /workspace/
RUN npm install && \ RUN npm install -g pnpm && \
npm run build pnpm install && \
pnpm run build
FROM golang:1.19-bullseye FROM golang:1.19-bullseye

Wyświetl plik

@ -4,13 +4,19 @@
---- ----
This repository is archived and will no longer be updated. Successor: [Hamabē](https://codeberg.org/hamabe/hamabe)
----
<div align="right"> <div align="right">
<img src="audon-fe/src/assets/img/mascot.webp" alt="Mascot" width="150" align="right" title="Mascot designed by Taiyo Fujii" /> <img src="audon-fe/src/assets/img/mascot.webp" alt="Mascot" width="150" align="right" title="Mascot designed by Taiyo Fujii" />
</div> </div>
Audio + Mastodon = Audon Audio + Mastodon = Audon
Audon is a service of realtime audio streaming for Mastodon. Audon is a service of realtime audio chat for Mastodon, Akkoma, GoToSocial, and Calckey.
Other Fediverse platforms supporting Mastodon API may work, but not tested (yet).
## Tech Stack ## Tech Stack

Wyświetl plik

@ -29,7 +29,7 @@
{% end %} {% end %}
</head> </head>
<body> <body>
<div id="app" data-version='0.3.0'></div> <div id="app" data-version='0.3.2'></div>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>

3751
audon-fe/package-lock.json wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,6 +1,6 @@
{ {
"name": "audon-fe", "name": "audon-fe",
"version": "0.3.0", "version": "0.3.2",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "cp -v index.dev.html index.html && vite", "dev": "cp -v index.dev.html index.html && vite",
@ -9,34 +9,35 @@
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore" "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
}, },
"dependencies": { "dependencies": {
"@intlify/unplugin-vue-i18n": "^0.8.1", "@intlify/unplugin-vue-i18n": "^0.8.2",
"@picmo/popup-picker": "^5.7.2", "@picmo/popup-picker": "^5.7.6",
"@picmo/renderer-twemoji": "^5.7.6",
"@uriopass/nosleep.js": "^0.12.2", "@uriopass/nosleep.js": "^0.12.2",
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"@vueuse/core": "^9.6.0", "@vueuse/core": "^9.13.0",
"axios": "^1.2.0", "axios": "^1.3.3",
"howler": "^2.2.3", "howler": "^2.2.3",
"livekit-client": "^1.6.0", "livekit-client": "^1.6.5",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"luxon": "^3.1.1", "luxon": "^3.2.1",
"masto": "^5.6.0", "masto": "^5.10.0",
"picmo": "^5.7.2", "picmo": "^5.7.6",
"pinia": "^2.0.26", "pinia": "^2.0.31",
"vue": "^3.2.45", "vue": "^3.2.47",
"vue-i18n": "^9.2.2", "vue-i18n": "^9.2.2",
"vue-router": "^4.1.6", "vue-router": "^4.1.6",
"vuetify": "^3.0.3" "vuetify": "^3.1.5"
}, },
"devDependencies": { "devDependencies": {
"@mdi/js": "^7.0.96", "@mdi/js": "^7.1.96",
"@rushstack/eslint-patch": "^1.1.4", "@rushstack/eslint-patch": "^1.2.0",
"@vitejs/plugin-vue": "^3.2.0", "@vitejs/plugin-vue": "^3.2.0",
"@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-prettier": "^7.0.0",
"eslint": "^8.22.0", "eslint": "^8.34.0",
"eslint-plugin-vue": "^9.3.0", "eslint-plugin-vue": "^9.9.0",
"prettier": "^2.7.1", "prettier": "^2.8.4",
"vite": "^3.2.4", "vite": "^3.2.5",
"vite-plugin-vuetify": "^1.0.0" "vite-plugin-vuetify": "^1.0.2"
} }
} }

Plik diff jest za duży Load Diff

Wyświetl plik

@ -28,7 +28,8 @@ export default {
}, },
computed: { computed: {
uploadEnabled() { uploadEnabled() {
return this.roomToken?.original && this.roomToken?.indicator; // return this.roomToken?.original && this.roomToken?.indicator;
return false;
}, },
}, },
async mounted() { async mounted() {

Wyświetl plik

@ -77,7 +77,9 @@ export default {
scrim="#000000" scrim="#000000"
class="align-center justify-center reaction" class="align-center justify-center reaction"
> >
<span>{{ emoji }}</span> <div class="d-flex align-center justify-center">
<img class="emoji" :src="emoji" />
</div>
</v-overlay> </v-overlay>
<v-img <v-img
:class="{ cursorPointer: enableMenu }" :class="{ cursorPointer: enableMenu }"
@ -100,7 +102,9 @@ export default {
scrim="#000000" scrim="#000000"
class="align-center justify-center reaction" class="align-center justify-center reaction"
> >
<span>{{ emoji }}</span> <div class="d-flex align-center justify-center">
<img class="emoji" :src="emoji" />
</div>
</v-overlay> </v-overlay>
<v-img <v-img
:class="{ cursorPointer: enableMenu }" :class="{ cursorPointer: enableMenu }"
@ -147,10 +151,8 @@ export default {
outline: 3px solid cornflowerblue; outline: 3px solid cornflowerblue;
} }
.reaction span { .reaction img {
font-size: 2rem; height: 2rem;
color: white;
text-align: center;
} }
.cursorPointer { .cursorPointer {

Wyświetl plik

@ -17,6 +17,21 @@ enterRoom: "Enter"
leaveRoom: "Leave but keep this room open" leaveRoom: "Leave but keep this room open"
closeRoom: "Close this room" closeRoom: "Close this room"
close: "Close" close: "Close"
emojiReaction: "Open emoji reaction picker"
micStatus:
mute: "Mute microphone"
unmute: "Unmute microphone"
retry: "Retry enabling microphone"
request: "Send speaker request"
roomOperation:
operation: "Leave or close"
leave: "Leave this room"
close: "Close this room"
openRequests: "Open list of speaker requests"
edit: "Edit room information"
requestOperation:
decline: "Decline this speaker request"
accept: "Accept this speaker request"
connecting: "Connecting" connecting: "Connecting"
server: "Your Mastodon instance" server: "Your Mastodon instance"
addressRequired: "Enter your instance address" addressRequired: "Enter your instance address"
@ -40,9 +55,9 @@ form:
advertise: "Allow the bot ({bot}) to advertise your room" advertise: "Allow the bot ({bot}) to advertise your room"
relationships: relationships:
everyone: "Everyone" everyone: "Everyone"
following: "Followed accounts only" following: "Followees only (Accounts you're following)"
follower: "Followers-only" follower: "Followers only (Accounts following you)"
knowing: "Followed accounts and/or followers" knowing: "Followees and/or followers"
mutual: "Your mutuals" mutual: "Your mutuals"
private: "CoHosts only" private: "CoHosts only"
shareRoomMessage: "Join my Audon room!\n{link}\n\nTitle: {title}" shareRoomMessage: "Join my Audon room!\n{link}\n\nTitle: {title}"

Wyświetl plik

@ -17,6 +17,18 @@ enterRoom: "入室"
leaveRoom: "部屋を閉じずに退室" leaveRoom: "部屋を閉じずに退室"
closeRoom: "部屋を閉じる" closeRoom: "部屋を閉じる"
close: "閉じる" close: "閉じる"
emojiReaction: "絵文字ピッカーを開く"
micStatus:
mute: "マイクをミュート"
unmute: "マイクのミュートを解除"
retry: "マイク有効化を再試行"
request: "発言リクエストを送る"
roomOperation:
operation: "退室または閉室"
leave: "部屋から退室する"
close: "部屋を閉室する"
openRequests: "発言リクエストの一覧を開く"
edit: "部屋の情報を編集する"
connecting: "接続中" connecting: "接続中"
server: "Mastodon サーバー" server: "Mastodon サーバー"
addressRequired: "アドレスを入力してください" addressRequired: "アドレスを入力してください"

Wyświetl plik

@ -47,11 +47,14 @@ export const useMastodonStore = defineStore("mastodon", {
this.authorized = true; this.authorized = true;
}, },
async updateAvatar(img, filename) { async updateAvatar(img, filename) {
return;
/*
if (this.client === null) return; if (this.client === null) return;
const avatarBlob = await (await fetch(img)).blob(); const avatarBlob = await (await fetch(img)).blob();
this.userinfo = await this.client.v1.accounts.updateCredentials({ this.userinfo = await this.client.v1.accounts.updateCredentials({
avatar: new File([avatarBlob], `${Date.now()}_${filename}`), avatar: new File([avatarBlob], `${Date.now()}_${filename}`),
}); });
*/
}, },
async revertAvatar() { async revertAvatar() {
const token = await axios.get("/api/token"); const token = await axios.get("/api/token");

Wyświetl plik

@ -381,10 +381,8 @@ export default {
<template v-slot:label> <template v-slot:label>
<i18n-t keypath="form.advertise" tag="div"> <i18n-t keypath="form.advertise" tag="div">
<template v-slot:bot> <template v-slot:bot>
<a <a href="https://i.audon.space/@now" target="_blank"
href="https://akkoma.audon.space/users/now" >now@i.audon.space</a
target="_blank"
>now@audon.space</a
> >
</template> </template>
</i18n-t> </i18n-t>

Wyświetl plik

@ -3,7 +3,7 @@ import axios from "axios";
import { pushNotFound, webfinger } from "../assets/utils"; import { pushNotFound, webfinger } from "../assets/utils";
import { useMastodonStore } from "../stores/mastodon"; import { useMastodonStore } from "../stores/mastodon";
import { map, some, omit, filter, trim, clone, differenceBy } from "lodash-es"; import { map, some, omit, filter, trim, clone, differenceBy } from "lodash-es";
import { darkTheme } from "picmo"; import { darkTheme, NativeRenderer } from "picmo";
import { createPopup } from "@picmo/popup-picker"; import { createPopup } from "@picmo/popup-picker";
import { Howl } from "howler"; import { Howl } from "howler";
import Participant from "../components/Participant.vue"; import Participant from "../components/Participant.vue";
@ -76,7 +76,7 @@ export default {
sounds: { sounds: {
boop: new Howl({ boop: new Howl({
src: [boopSound], src: [boopSound],
volume: 0.7, volume: 0.5,
}), }),
message: new Howl({ message: new Howl({
src: [messageSound], src: [messageSound],
@ -84,7 +84,7 @@ export default {
}), }),
request: new Howl({ request: new Howl({
src: [requestSound], src: [requestSound],
volume: 0.7, volume: 0.5,
}), }),
}, },
}; };
@ -256,6 +256,18 @@ export default {
} }
return mdiMicrophone; return mdiMicrophone;
}, },
micStatusLabel() {
if (!(this.iamHost || this.iamCohost || this.iamSpeaker)) {
return this.$t("micStatus.request");
}
if (!this.micGranted) {
return this.$t("micStatus.retry");
}
if (this.iamMuted) {
return this.$t("micStatus.unmute");
}
return this.$t("micStatus.mute");
},
titleErrors() { titleErrors() {
const errors = this.v$.editingRoomInfo.title.$errors; const errors = this.v$.editingRoomInfo.title.$errors;
const messages = map(errors, (e) => e.$message); const messages = map(errors, (e) => e.$message);
@ -544,6 +556,7 @@ export default {
emojiSize: "1.8rem", emojiSize: "1.8rem",
autoFocus: "none", autoFocus: "none",
showPreview: false, showPreview: false,
renderer: new NativeRenderer(),
}, },
{ {
referenceElement: btn, referenceElement: btn,
@ -553,8 +566,8 @@ export default {
} }
); );
const self = this; const self = this;
picker.addEventListener("emoji:select", ({ emoji }) => { picker.addEventListener("emoji:select", ({ url }) => {
self.onEmojiSelected(emoji); self.onEmojiSelected(url);
}); });
this.emojiPicker = picker; this.emojiPicker = picker;
} }
@ -795,6 +808,7 @@ export default {
:icon="mdiCheck" :icon="mdiCheck"
:disabled="isRequestLoading" :disabled="isRequestLoading"
@click.once="onModerate(id, 'speaker')" @click.once="onModerate(id, 'speaker')"
:aria-label="$t('requestOperation.accept')"
></v-btn> ></v-btn>
<v-btn <v-btn
size="small" size="small"
@ -802,6 +816,7 @@ export default {
:icon="mdiClose" :icon="mdiClose"
:disabled="isRequestLoading" :disabled="isRequestLoading"
@click="onDeclineRequest(id)" @click="onDeclineRequest(id)"
:aria-label="$t('requestOperation.decline')"
></v-btn> ></v-btn>
</template> </template>
<v-list-item-subtitle> <v-list-item-subtitle>
@ -837,6 +852,7 @@ export default {
@click="showRequestedNotification = false" @click="showRequestedNotification = false"
:icon="mdiClose" :icon="mdiClose"
size="small" size="small"
:aria-label="$t('close')"
></v-btn> ></v-btn>
</template> </template>
</v-snackbar> </v-snackbar>
@ -861,6 +877,7 @@ export default {
@click="showRequestNotification = false" @click="showRequestNotification = false"
:icon="mdiClose" :icon="mdiClose"
size="small" size="small"
:aria-label="$('close')"
></v-btn> ></v-btn>
</template> </template>
</v-snackbar> </v-snackbar>
@ -877,6 +894,7 @@ export default {
size="small" size="small"
variant="text" variant="text"
color="white" color="white"
:aria-label="$t('roomOperation.edit')"
:icon="mdiPencil" :icon="mdiPencil"
@click="showEditDialog = true" @click="showEditDialog = true"
></v-btn> ></v-btn>
@ -953,6 +971,7 @@ export default {
<v-card-actions v-else class="justify-center" style="gap: 20px"> <v-card-actions v-else class="justify-center" style="gap: 20px">
<v-btn <v-btn
:icon="mdiEmoticon" :icon="mdiEmoticon"
:aria-label="$t('emojiReaction')"
color="white" color="white"
variant="flat" variant="flat"
@click="onPickerPopup" @click="onPickerPopup"
@ -961,6 +980,7 @@ export default {
</v-btn> </v-btn>
<v-btn <v-btn
:icon="micStatusIcon" :icon="micStatusIcon"
:aria-label="micStatusLabel"
color="white" color="white"
variant="flat" variant="flat"
@click="onToggleMute" @click="onToggleMute"
@ -970,6 +990,7 @@ export default {
<v-btn <v-btn
:icon="mdiLogout" :icon="mdiLogout"
color="red" color="red"
:aria-label="$t('roomOperation.operation')"
:disabled="loading" :disabled="loading"
variant="flat" variant="flat"
v-bind="props" v-bind="props"
@ -978,6 +999,7 @@ export default {
<v-list> <v-list>
<v-list-item <v-list-item
:title="$t('closeRoom')" :title="$t('closeRoom')"
:aria-label="$t('roomOperation.close')"
:prepend-icon="mdiCloseBoxOutline" :prepend-icon="mdiCloseBoxOutline"
@click="onRoomClose" @click="onRoomClose"
class="text-red" class="text-red"
@ -985,6 +1007,7 @@ export default {
<v-list-item <v-list-item
:disabled="isLastHost" :disabled="isLastHost"
:title="$t('leaveRoom')" :title="$t('leaveRoom')"
:aria-label="$t('roomOperation.leave')"
:prepend-icon="mdiExitRun" :prepend-icon="mdiExitRun"
@click="onLeave" @click="onLeave"
> >
@ -996,6 +1019,7 @@ export default {
:icon="mdiLogout" :icon="mdiLogout"
color="red" color="red"
:disabled="loading" :disabled="loading"
:aria-label="$t('roomOperation.leave')"
@click="onLeave" @click="onLeave"
variant="flat" variant="flat"
></v-btn> ></v-btn>
@ -1007,6 +1031,7 @@ export default {
> >
<v-btn <v-btn
:icon="mdiAccountVoice" :icon="mdiAccountVoice"
:aria-label="$t('roomOperation.openRequests')"
variant="flat" variant="flat"
color="white" color="white"
@click=" @click="

21
auth.go
Wyświetl plik

@ -66,7 +66,7 @@ func loginHandler(c echo.Context) (err error) {
req.Redirect = "/" req.Redirect = "/"
} }
appConfig, err := getAppConfig(serverURL.String(), req.Redirect) appConfig, err := getAppConfig(serverURL.String())
if err != nil { if err != nil {
return ErrInvalidRequestFormat return ErrInvalidRequestFormat
} }
@ -89,15 +89,24 @@ func loginHandler(c echo.Context) (err error) {
return echo.NewHTTPError(http.StatusInternalServerError) return echo.NewHTTPError(http.StatusInternalServerError)
} }
return c.String(http.StatusCreated, mastApp.AuthURI) redirURL, err := url.Parse(mastApp.AuthURI)
if err != nil {
c.Logger().Warn(err)
return echo.NewHTTPError(http.StatusInternalServerError, "invalid_auth_uri")
}
q := redirURL.Query()
q.Add("state", req.Redirect)
redirURL.RawQuery = q.Encode()
return c.String(http.StatusCreated, redirURL.String())
} }
return c.NoContent(http.StatusNoContent) return c.NoContent(http.StatusNoContent)
} }
type OAuthRequest struct { type OAuthRequest struct {
Code string `query:"code"` Code string `query:"code"`
Redirect string `query:"redir"` State string `query:"state"`
} }
// handler for GET to /app/oauth?code=**** // handler for GET to /app/oauth?code=****
@ -122,7 +131,7 @@ func oauthHandler(c echo.Context) (err error) {
if err != nil { if err != nil {
return err return err
} }
appConf, err := getAppConfig(data.MastodonConfig.Server, req.Redirect) appConf, err := getAppConfig(data.MastodonConfig.Server)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
@ -178,7 +187,7 @@ func oauthHandler(c echo.Context) (err error) {
return echo.NewHTTPError(http.StatusInternalServerError) return echo.NewHTTPError(http.StatusInternalServerError)
} }
return c.Redirect(http.StatusFound, req.Redirect) return c.Redirect(http.StatusFound, req.State)
} }
func getUserTokenHandler(c echo.Context) (err error) { func getUserTokenHandler(c echo.Context) (err error) {

Wyświetl plik

@ -93,10 +93,10 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) (
return return
} }
indicator, err = u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u)) // indicator, err = u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u))
if err != nil { // if err != nil {
return // return
} // }
return indicator, origImg, isGIF, nil return indicator, origImg, isGIF, nil
} }

4
go.mod
Wyświetl plik

@ -3,10 +3,12 @@ module audon
go 1.19 go 1.19
require ( require (
github.com/gabriel-vasile/mimetype v1.4.1
github.com/go-playground/validator/v10 v10.11.1 github.com/go-playground/validator/v10 v10.11.1
github.com/go-redis/redis/v9 v9.0.0-rc.2 github.com/go-redis/redis/v9 v9.0.0-rc.2
github.com/gorilla/sessions v1.2.1 github.com/gorilla/sessions v1.2.1
github.com/jaevor/go-nanoid v1.3.0 github.com/jaevor/go-nanoid v1.3.0
github.com/jellydator/ttlcache/v3 v3.0.1
github.com/joho/godotenv v1.4.0 github.com/joho/godotenv v1.4.0
github.com/labstack/echo-contrib v0.13.0 github.com/labstack/echo-contrib v0.13.0
github.com/labstack/echo/v4 v4.9.1 github.com/labstack/echo/v4 v4.9.1
@ -33,7 +35,6 @@ require (
github.com/eapache/channels v1.1.0 // indirect github.com/eapache/channels v1.1.0 // indirect
github.com/eapache/queue v1.1.0 // indirect github.com/eapache/queue v1.1.0 // indirect
github.com/frostbyte73/go-throttle v0.0.0-20210621200530-8018c891361d // indirect github.com/frostbyte73/go-throttle v0.0.0-20210621200530-8018c891361d // indirect
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.2.3 // indirect github.com/go-logr/zapr v1.2.3 // indirect
@ -47,7 +48,6 @@ require (
github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/jellydator/ttlcache/v3 v3.0.1 // indirect
github.com/jxskiss/base62 v1.1.0 // indirect github.com/jxskiss/base62 v1.1.0 // indirect
github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/compress v1.13.6 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect

Wyświetl plik

@ -383,7 +383,8 @@ func joinRoomHandler(c echo.Context) (err error) {
} }
// Generate indicator GIF // Generate indicator GIF
indicator, original, isGIF, err := user.GetIndicator(c.Request().Context(), fnew, room) // indicator, original, isGIF, err := user.GetIndicator(c.Request().Context(), fnew, room)
_, original, isGIF, err := user.GetIndicator(c.Request().Context(), fnew, room)
origMime := "image/png" origMime := "image/png"
if isGIF { if isGIF {
origMime = "image/gif" origMime = "image/gif"
@ -393,7 +394,7 @@ func joinRoomHandler(c echo.Context) (err error) {
return echo.NewHTTPError(http.StatusInternalServerError) return echo.NewHTTPError(http.StatusInternalServerError)
} }
resp.Original = fmt.Sprintf("data:%s;base64,%s", origMime, base64.StdEncoding.EncodeToString(original)) resp.Original = fmt.Sprintf("data:%s;base64,%s", origMime, base64.StdEncoding.EncodeToString(original))
resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(indicator)) // resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(indicator))
} else if err != nil { } else if err != nil {
c.Logger().Error(err) c.Logger().Error(err)
} }

Wyświetl plik

@ -225,25 +225,20 @@ func (cv *CustomValidator) Validate(i interface{}) error {
return nil return nil
} }
func getAppConfig(server string, redirPath string) (*mastodon.AppConfig, error) { func getAppConfig(server string) (*mastodon.AppConfig, error) {
if redirPath == "" {
redirPath = "/"
}
redirectURI := "urn:ietf:wg:oauth:2.0:oob" redirectURI := "urn:ietf:wg:oauth:2.0:oob"
u := &url.URL{ u := &url.URL{
Host: mainConfig.LocalDomain, Host: mainConfig.LocalDomain,
Scheme: "https", Scheme: "https",
Path: "/", Path: "/",
} }
q := u.Query()
q.Add("redir", redirPath)
u.RawQuery = q.Encode()
u = u.JoinPath("app", "oauth") u = u.JoinPath("app", "oauth")
redirectURI = u.String() redirectURI = u.String()
conf := &mastodon.AppConfig{ conf := &mastodon.AppConfig{
ClientName: "Audon", ClientName: "Audon",
Scopes: "read:accounts read:follows write:accounts", // Scopes: "read:accounts read:follows write:accounts",
Scopes: "read:accounts read:follows",
Website: "https://codeberg.org/nmkj/audon", Website: "https://codeberg.org/nmkj/audon",
RedirectURIs: redirectURI, RedirectURIs: redirectURI,
} }

Wyświetl plik

@ -1,19 +1,18 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
"github.com/jellydator/ttlcache/v3"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/livekit/protocol/auth" "github.com/livekit/protocol/auth"
"github.com/livekit/protocol/webhook" "github.com/livekit/protocol/webhook"
mastodon "github.com/mattn/go-mastodon" mastodon "github.com/mattn/go-mastodon"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/net/context"
) )
func livekitWebhookHandler(c echo.Context) error { func livekitWebhookHandler(c echo.Context) error {
@ -38,7 +37,6 @@ func livekitWebhookHandler(c echo.Context) error {
} }
} }
} else if event.GetEvent() == webhook.EventParticipantLeft { } else if event.GetEvent() == webhook.EventParticipantLeft {
// Revert user's avatar
audonID := event.GetParticipant().GetIdentity() audonID := event.GetParticipant().GetIdentity()
user, err := findUserByID(c.Request().Context(), audonID) user, err := findUserByID(c.Request().Context(), audonID)
if user == nil || err != nil { if user == nil || err != nil {
@ -51,51 +49,13 @@ func livekitWebhookHandler(c echo.Context) error {
if data == nil { if data == nil {
return echo.NewHTTPError(http.StatusGone) return echo.NewHTTPError(http.StatusGone)
} }
mastoClient := getMastodonClient(data.Value()) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
if mastoClient == nil { defer cancel()
c.Logger().Errorf("unable to get mastodon client: %v", data.Value().MastodonConfig) nextUser, err := findUserByID(ctx, audonID)
return echo.NewHTTPError(http.StatusInternalServerError) if err != nil {
log.Println(err)
} }
cached := webhookTimerCache.Get(audonID) nextUser.ClearUserAvatar(ctx)
if cached != nil {
oldTimer := cached.Value()
if !oldTimer.Stop() {
<-oldTimer.C
}
}
countdown := time.NewTimer(60 * time.Second)
webhookTimerCache.Set(audonID, countdown, ttlcache.DefaultTTL)
go func() {
<-countdown.C
webhookTimerCache.Delete(audonID)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
stillAgain, err := user.InLivekit(ctx)
if err != nil {
log.Println(err)
}
if stillAgain {
return
}
nextUser, err := findUserByID(ctx, audonID)
if err == nil && nextUser.AvatarFile != "" {
log.Printf("Recovering avatar: %s --> (%s) %s\n", nextUser.AvatarFile, audonID, nextUser.Webfinger)
if err != nil {
log.Println(err)
return
}
avatar := nextUser.getAvatarImagePath(nextUser.AvatarFile)
_, err = updateAvatar(ctx, mastoClient, avatar)
if err != nil {
log.Println(err)
}
nextUser.ClearUserAvatar(ctx)
} else if err != nil {
log.Println(err)
}
}()
} }
} else if event.GetEvent() == webhook.EventRoomStarted { } else if event.GetEvent() == webhook.EventRoomStarted {
// Have the bot advertise the room // Have the bot advertise the room