kopia lustrzana https://codeberg.org/nmkj/audon
Porównaj commity
19 Commity
Autor | SHA1 | Data |
---|---|---|
Namekuji | 7adba191e6 | |
Namekuji | 3cc4ee4f84 | |
Namekuji | a606f7f4fb | |
Namekuji | 1bb384a10c | |
Namekuji | 0fc4e5fbec | |
Namekuji | 30cc7930fc | |
Namekuji | 6c4ef49085 | |
Namekuji | 85979a7ebf | |
Namekuji | 6f7b58f2e2 | |
Namekuji | 03e5cb4f02 | |
Namekuji | 87300ea112 | |
Namekuji | 7b837651dd | |
Namekuji | c40fb71147 | |
Namekuji | d52ae18c44 | |
Namekuji | 3138e2a596 | |
Namekuji | 80963c96e6 | |
Namekuji | 32dbfbc205 | |
Namekuji | e2a5fb6fd6 | |
Namekuji | f11d4f016a |
|
@ -16,7 +16,7 @@ audon.localhost {
|
|||
}
|
||||
}
|
||||
|
||||
livekit.audon.localhost {
|
||||
livekit.localhost {
|
||||
tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem
|
||||
encode zstd gzip
|
||||
reverse_proxy livekit:7880
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// "image": "mcr.microsoft.com/devcontainers/universal:2-linux"
|
||||
"dockerComposeFile": "docker-compose.dev.yaml",
|
||||
"service": "devcontainer",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
"workspaceFolder": "/audon-go",
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
"features": {
|
||||
|
@ -33,8 +33,8 @@
|
|||
"EditorConfig.EditorConfig"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
"remoteUser": "root"
|
||||
}
|
||||
|
|
|
@ -2,10 +2,12 @@ version: '3.1'
|
|||
|
||||
services:
|
||||
devcontainer:
|
||||
image: "mcr.microsoft.com/devcontainers/base:jammy"
|
||||
image: "mcr.microsoft.com/devcontainers/base:debian"
|
||||
volumes:
|
||||
- ../..:/workspaces:cached
|
||||
- ..:/audon-go:cached
|
||||
command: sleep infinity
|
||||
environment:
|
||||
- "DOCKER_HOST=unix:///run/user/1000/docker.sock"
|
||||
|
||||
db:
|
||||
image: mongo:6
|
||||
|
|
|
@ -66,6 +66,7 @@ build/Release
|
|||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
.pnpm-store/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
|
|
@ -4,8 +4,9 @@ WORKDIR /workspace
|
|||
|
||||
COPY audon-fe/ /workspace/
|
||||
|
||||
RUN npm install && \
|
||||
npm run build
|
||||
RUN npm install -g pnpm && \
|
||||
pnpm install && \
|
||||
pnpm run build
|
||||
|
||||
FROM golang:1.19-bullseye
|
||||
|
||||
|
|
|
@ -4,13 +4,19 @@
|
|||
|
||||
----
|
||||
|
||||
This repository is archived and will no longer be updated. Successor: [Hamabē](https://codeberg.org/hamabe/hamabe)
|
||||
|
||||
----
|
||||
|
||||
<div align="right">
|
||||
<img src="audon-fe/src/assets/img/mascot.webp" alt="Mascot" width="150" align="right" title="Mascot designed by Taiyo Fujii" />
|
||||
</div>
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
{% end %}
|
||||
</head>
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "audon-fe",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||
"@picmo/popup-picker": "^5.7.2",
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||
"@picmo/popup-picker": "^5.7.6",
|
||||
"@picmo/renderer-twemoji": "^5.7.6",
|
||||
"@uriopass/nosleep.js": "^0.12.2",
|
||||
"@vuelidate/core": "^2.0.0",
|
||||
"@vuelidate/validators": "^2.0.0",
|
||||
"@vueuse/core": "^9.6.0",
|
||||
"axios": "^1.2.0",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"axios": "^1.3.3",
|
||||
"howler": "^2.2.3",
|
||||
"livekit-client": "^1.6.0",
|
||||
"livekit-client": "^1.6.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"luxon": "^3.1.1",
|
||||
"masto": "^5.6.0",
|
||||
"picmo": "^5.7.2",
|
||||
"pinia": "^2.0.26",
|
||||
"vue": "^3.2.45",
|
||||
"luxon": "^3.2.1",
|
||||
"masto": "^5.10.0",
|
||||
"picmo": "^5.7.6",
|
||||
"pinia": "^2.0.31",
|
||||
"vue": "^3.2.47",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.1.6",
|
||||
"vuetify": "^3.0.3"
|
||||
"vuetify": "^3.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdi/js": "^7.0.96",
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@mdi/js": "^7.1.96",
|
||||
"@rushstack/eslint-patch": "^1.2.0",
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
"prettier": "^2.7.1",
|
||||
"vite": "^3.2.4",
|
||||
"vite-plugin-vuetify": "^1.0.0"
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-plugin-vue": "^9.9.0",
|
||||
"prettier": "^2.8.4",
|
||||
"vite": "^3.2.5",
|
||||
"vite-plugin-vuetify": "^1.0.2"
|
||||
}
|
||||
}
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -28,7 +28,8 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
uploadEnabled() {
|
||||
return this.roomToken?.original && this.roomToken?.indicator;
|
||||
// return this.roomToken?.original && this.roomToken?.indicator;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
|
|
|
@ -77,7 +77,9 @@ export default {
|
|||
scrim="#000000"
|
||||
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-img
|
||||
:class="{ cursorPointer: enableMenu }"
|
||||
|
@ -100,7 +102,9 @@ export default {
|
|||
scrim="#000000"
|
||||
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-img
|
||||
:class="{ cursorPointer: enableMenu }"
|
||||
|
@ -147,10 +151,8 @@ export default {
|
|||
outline: 3px solid cornflowerblue;
|
||||
}
|
||||
|
||||
.reaction span {
|
||||
font-size: 2rem;
|
||||
color: white;
|
||||
text-align: center;
|
||||
.reaction img {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.cursorPointer {
|
||||
|
|
|
@ -17,6 +17,21 @@ enterRoom: "Enter"
|
|||
leaveRoom: "Leave but keep this room open"
|
||||
closeRoom: "Close this room"
|
||||
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"
|
||||
server: "Your Mastodon instance"
|
||||
addressRequired: "Enter your instance address"
|
||||
|
@ -40,9 +55,9 @@ form:
|
|||
advertise: "Allow the bot ({bot}) to advertise your room"
|
||||
relationships:
|
||||
everyone: "Everyone"
|
||||
following: "Followed accounts only"
|
||||
follower: "Followers-only"
|
||||
knowing: "Followed accounts and/or followers"
|
||||
following: "Followees only (Accounts you're following)"
|
||||
follower: "Followers only (Accounts following you)"
|
||||
knowing: "Followees and/or followers"
|
||||
mutual: "Your mutuals"
|
||||
private: "CoHosts only"
|
||||
shareRoomMessage: "Join my Audon room!\n{link}\n\nTitle: {title}"
|
||||
|
|
|
@ -17,6 +17,18 @@ enterRoom: "入室"
|
|||
leaveRoom: "部屋を閉じずに退室"
|
||||
closeRoom: "部屋を閉じる"
|
||||
close: "閉じる"
|
||||
emojiReaction: "絵文字ピッカーを開く"
|
||||
micStatus:
|
||||
mute: "マイクをミュート"
|
||||
unmute: "マイクのミュートを解除"
|
||||
retry: "マイク有効化を再試行"
|
||||
request: "発言リクエストを送る"
|
||||
roomOperation:
|
||||
operation: "退室または閉室"
|
||||
leave: "部屋から退室する"
|
||||
close: "部屋を閉室する"
|
||||
openRequests: "発言リクエストの一覧を開く"
|
||||
edit: "部屋の情報を編集する"
|
||||
connecting: "接続中"
|
||||
server: "Mastodon サーバー"
|
||||
addressRequired: "アドレスを入力してください"
|
||||
|
|
|
@ -47,11 +47,14 @@ export const useMastodonStore = defineStore("mastodon", {
|
|||
this.authorized = true;
|
||||
},
|
||||
async updateAvatar(img, filename) {
|
||||
return;
|
||||
/*
|
||||
if (this.client === null) return;
|
||||
const avatarBlob = await (await fetch(img)).blob();
|
||||
this.userinfo = await this.client.v1.accounts.updateCredentials({
|
||||
avatar: new File([avatarBlob], `${Date.now()}_${filename}`),
|
||||
});
|
||||
*/
|
||||
},
|
||||
async revertAvatar() {
|
||||
const token = await axios.get("/api/token");
|
||||
|
|
|
@ -381,10 +381,8 @@ export default {
|
|||
<template v-slot:label>
|
||||
<i18n-t keypath="form.advertise" tag="div">
|
||||
<template v-slot:bot>
|
||||
<a
|
||||
href="https://akkoma.audon.space/users/now"
|
||||
target="_blank"
|
||||
>now@audon.space</a
|
||||
<a href="https://i.audon.space/@now" target="_blank"
|
||||
>now@i.audon.space</a
|
||||
>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
|
|
@ -3,7 +3,7 @@ import axios from "axios";
|
|||
import { pushNotFound, webfinger } from "../assets/utils";
|
||||
import { useMastodonStore } from "../stores/mastodon";
|
||||
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 { Howl } from "howler";
|
||||
import Participant from "../components/Participant.vue";
|
||||
|
@ -76,7 +76,7 @@ export default {
|
|||
sounds: {
|
||||
boop: new Howl({
|
||||
src: [boopSound],
|
||||
volume: 0.7,
|
||||
volume: 0.5,
|
||||
}),
|
||||
message: new Howl({
|
||||
src: [messageSound],
|
||||
|
@ -84,7 +84,7 @@ export default {
|
|||
}),
|
||||
request: new Howl({
|
||||
src: [requestSound],
|
||||
volume: 0.7,
|
||||
volume: 0.5,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
@ -256,6 +256,18 @@ export default {
|
|||
}
|
||||
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() {
|
||||
const errors = this.v$.editingRoomInfo.title.$errors;
|
||||
const messages = map(errors, (e) => e.$message);
|
||||
|
@ -544,6 +556,7 @@ export default {
|
|||
emojiSize: "1.8rem",
|
||||
autoFocus: "none",
|
||||
showPreview: false,
|
||||
renderer: new NativeRenderer(),
|
||||
},
|
||||
{
|
||||
referenceElement: btn,
|
||||
|
@ -553,8 +566,8 @@ export default {
|
|||
}
|
||||
);
|
||||
const self = this;
|
||||
picker.addEventListener("emoji:select", ({ emoji }) => {
|
||||
self.onEmojiSelected(emoji);
|
||||
picker.addEventListener("emoji:select", ({ url }) => {
|
||||
self.onEmojiSelected(url);
|
||||
});
|
||||
this.emojiPicker = picker;
|
||||
}
|
||||
|
@ -795,6 +808,7 @@ export default {
|
|||
:icon="mdiCheck"
|
||||
:disabled="isRequestLoading"
|
||||
@click.once="onModerate(id, 'speaker')"
|
||||
:aria-label="$t('requestOperation.accept')"
|
||||
></v-btn>
|
||||
<v-btn
|
||||
size="small"
|
||||
|
@ -802,6 +816,7 @@ export default {
|
|||
:icon="mdiClose"
|
||||
:disabled="isRequestLoading"
|
||||
@click="onDeclineRequest(id)"
|
||||
:aria-label="$t('requestOperation.decline')"
|
||||
></v-btn>
|
||||
</template>
|
||||
<v-list-item-subtitle>
|
||||
|
@ -837,6 +852,7 @@ export default {
|
|||
@click="showRequestedNotification = false"
|
||||
:icon="mdiClose"
|
||||
size="small"
|
||||
:aria-label="$t('close')"
|
||||
></v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
|
@ -861,6 +877,7 @@ export default {
|
|||
@click="showRequestNotification = false"
|
||||
:icon="mdiClose"
|
||||
size="small"
|
||||
:aria-label="$('close')"
|
||||
></v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
|
@ -877,6 +894,7 @@ export default {
|
|||
size="small"
|
||||
variant="text"
|
||||
color="white"
|
||||
:aria-label="$t('roomOperation.edit')"
|
||||
:icon="mdiPencil"
|
||||
@click="showEditDialog = true"
|
||||
></v-btn>
|
||||
|
@ -953,6 +971,7 @@ export default {
|
|||
<v-card-actions v-else class="justify-center" style="gap: 20px">
|
||||
<v-btn
|
||||
:icon="mdiEmoticon"
|
||||
:aria-label="$t('emojiReaction')"
|
||||
color="white"
|
||||
variant="flat"
|
||||
@click="onPickerPopup"
|
||||
|
@ -961,6 +980,7 @@ export default {
|
|||
</v-btn>
|
||||
<v-btn
|
||||
:icon="micStatusIcon"
|
||||
:aria-label="micStatusLabel"
|
||||
color="white"
|
||||
variant="flat"
|
||||
@click="onToggleMute"
|
||||
|
@ -970,6 +990,7 @@ export default {
|
|||
<v-btn
|
||||
:icon="mdiLogout"
|
||||
color="red"
|
||||
:aria-label="$t('roomOperation.operation')"
|
||||
:disabled="loading"
|
||||
variant="flat"
|
||||
v-bind="props"
|
||||
|
@ -978,6 +999,7 @@ export default {
|
|||
<v-list>
|
||||
<v-list-item
|
||||
:title="$t('closeRoom')"
|
||||
:aria-label="$t('roomOperation.close')"
|
||||
:prepend-icon="mdiCloseBoxOutline"
|
||||
@click="onRoomClose"
|
||||
class="text-red"
|
||||
|
@ -985,6 +1007,7 @@ export default {
|
|||
<v-list-item
|
||||
:disabled="isLastHost"
|
||||
:title="$t('leaveRoom')"
|
||||
:aria-label="$t('roomOperation.leave')"
|
||||
:prepend-icon="mdiExitRun"
|
||||
@click="onLeave"
|
||||
>
|
||||
|
@ -996,6 +1019,7 @@ export default {
|
|||
:icon="mdiLogout"
|
||||
color="red"
|
||||
:disabled="loading"
|
||||
:aria-label="$t('roomOperation.leave')"
|
||||
@click="onLeave"
|
||||
variant="flat"
|
||||
></v-btn>
|
||||
|
@ -1007,6 +1031,7 @@ export default {
|
|||
>
|
||||
<v-btn
|
||||
:icon="mdiAccountVoice"
|
||||
:aria-label="$t('roomOperation.openRequests')"
|
||||
variant="flat"
|
||||
color="white"
|
||||
@click="
|
||||
|
|
21
auth.go
21
auth.go
|
@ -66,7 +66,7 @@ func loginHandler(c echo.Context) (err error) {
|
|||
req.Redirect = "/"
|
||||
}
|
||||
|
||||
appConfig, err := getAppConfig(serverURL.String(), req.Redirect)
|
||||
appConfig, err := getAppConfig(serverURL.String())
|
||||
if err != nil {
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
|
@ -89,15 +89,24 @@ func loginHandler(c echo.Context) (err error) {
|
|||
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)
|
||||
}
|
||||
|
||||
type OAuthRequest struct {
|
||||
Code string `query:"code"`
|
||||
Redirect string `query:"redir"`
|
||||
Code string `query:"code"`
|
||||
State string `query:"state"`
|
||||
}
|
||||
|
||||
// handler for GET to /app/oauth?code=****
|
||||
|
@ -122,7 +131,7 @@ func oauthHandler(c echo.Context) (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appConf, err := getAppConfig(data.MastodonConfig.Server, req.Redirect)
|
||||
appConf, err := getAppConfig(data.MastodonConfig.Server)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
@ -178,7 +187,7 @@ func oauthHandler(c echo.Context) (err error) {
|
|||
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) {
|
||||
|
|
|
@ -93,10 +93,10 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) (
|
|||
return
|
||||
}
|
||||
|
||||
indicator, err = u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// indicator, err = u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u))
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
return indicator, origImg, isGIF, nil
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,10 +3,12 @@ module audon
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/gabriel-vasile/mimetype v1.4.1
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/go-redis/redis/v9 v9.0.0-rc.2
|
||||
github.com/gorilla/sessions v1.2.1
|
||||
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/labstack/echo-contrib v0.13.0
|
||||
github.com/labstack/echo/v4 v4.9.1
|
||||
|
@ -33,7 +35,6 @@ require (
|
|||
github.com/eapache/channels 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/gabriel-vasile/mimetype v1.4.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // 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/securecookie v1.1.1 // 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/klauspost/compress v1.13.6 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
|
|
5
room.go
5
room.go
|
@ -383,7 +383,8 @@ func joinRoomHandler(c echo.Context) (err error) {
|
|||
}
|
||||
|
||||
// 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"
|
||||
if isGIF {
|
||||
origMime = "image/gif"
|
||||
|
@ -393,7 +394,7 @@ func joinRoomHandler(c echo.Context) (err error) {
|
|||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
}
|
||||
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 {
|
||||
c.Logger().Error(err)
|
||||
}
|
||||
|
|
13
server.go
13
server.go
|
@ -225,25 +225,20 @@ func (cv *CustomValidator) Validate(i interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getAppConfig(server string, redirPath string) (*mastodon.AppConfig, error) {
|
||||
if redirPath == "" {
|
||||
redirPath = "/"
|
||||
}
|
||||
func getAppConfig(server string) (*mastodon.AppConfig, error) {
|
||||
redirectURI := "urn:ietf:wg:oauth:2.0:oob"
|
||||
u := &url.URL{
|
||||
Host: mainConfig.LocalDomain,
|
||||
Scheme: "https",
|
||||
Path: "/",
|
||||
}
|
||||
q := u.Query()
|
||||
q.Add("redir", redirPath)
|
||||
u.RawQuery = q.Encode()
|
||||
u = u.JoinPath("app", "oauth")
|
||||
redirectURI = u.String()
|
||||
|
||||
conf := &mastodon.AppConfig{
|
||||
ClientName: "Audon",
|
||||
Scopes: "read:accounts read:follows write:accounts",
|
||||
ClientName: "Audon",
|
||||
// Scopes: "read:accounts read:follows write:accounts",
|
||||
Scopes: "read:accounts read:follows",
|
||||
Website: "https://codeberg.org/nmkj/audon",
|
||||
RedirectURIs: redirectURI,
|
||||
}
|
||||
|
|
54
webhooks.go
54
webhooks.go
|
@ -1,19 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jellydator/ttlcache/v3"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/livekit/protocol/auth"
|
||||
"github.com/livekit/protocol/webhook"
|
||||
mastodon "github.com/mattn/go-mastodon"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func livekitWebhookHandler(c echo.Context) error {
|
||||
|
@ -38,7 +37,6 @@ func livekitWebhookHandler(c echo.Context) error {
|
|||
}
|
||||
}
|
||||
} else if event.GetEvent() == webhook.EventParticipantLeft {
|
||||
// Revert user's avatar
|
||||
audonID := event.GetParticipant().GetIdentity()
|
||||
user, err := findUserByID(c.Request().Context(), audonID)
|
||||
if user == nil || err != nil {
|
||||
|
@ -51,51 +49,13 @@ func livekitWebhookHandler(c echo.Context) error {
|
|||
if data == nil {
|
||||
return echo.NewHTTPError(http.StatusGone)
|
||||
}
|
||||
mastoClient := getMastodonClient(data.Value())
|
||||
if mastoClient == nil {
|
||||
c.Logger().Errorf("unable to get mastodon client: %v", data.Value().MastodonConfig)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
nextUser, err := findUserByID(ctx, audonID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
cached := webhookTimerCache.Get(audonID)
|
||||
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)
|
||||
}
|
||||
}()
|
||||
nextUser.ClearUserAvatar(ctx)
|
||||
}
|
||||
} else if event.GetEvent() == webhook.EventRoomStarted {
|
||||
// Have the bot advertise the room
|
||||
|
|
Ładowanie…
Reference in New Issue