kopia lustrzana https://codeberg.org/nmkj/audon
add listener online indicator
rodzic
906170c110
commit
5b7c6735ed
|
@ -64,7 +64,7 @@ startListening: "Start Listening"
|
|||
browserMuted: "To protect your ears, sound is muted by the browser. Press @:startListening to continue."
|
||||
onlineIndicator:
|
||||
message: "Do you want to add the online indicator to your account's avatar like this?"
|
||||
hint: "Audon will remove the indicator after this room is closed."
|
||||
hint: "Audon will remove the indicator after you leave."
|
||||
warning: "Your instance may take a while to reflect the indicator."
|
||||
sure: "Yes"
|
||||
nope: "No"
|
||||
|
|
|
@ -63,8 +63,8 @@ errors:
|
|||
startListening: "視聴を始める"
|
||||
browserMuted: "大きな音であなたが驚かないよう、無音になっています。続行するには @:startListening ボタンを押してください。"
|
||||
onlineIndicator:
|
||||
message: "あなたが部屋をホスト中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。"
|
||||
hint: "部屋を閉じた後、アバターは自動で元に戻ります。"
|
||||
message: "あなたが部屋に参加中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。"
|
||||
hint: "部屋から退出後、アバターは自動で元に戻ります。"
|
||||
warning: "サーバーが変更を反映するまで時間がかかることがあります。"
|
||||
sure: "表示する"
|
||||
nope: "表示しない"
|
||||
|
|
|
@ -48,7 +48,8 @@ export const useMastodonStore = defineStore("mastodon", {
|
|||
},
|
||||
async revertAvatar() {
|
||||
const token = await axios.get("/api/token");
|
||||
if (token.data.audon.avatar) {
|
||||
const rooms = await axios.get("/api/room");
|
||||
if (token.data.audon.avatar && rooms.data.length < 1) {
|
||||
if (this.avatar) {
|
||||
await this.updateAvatar(this.avatar, token.data.audon.avatar);
|
||||
}
|
||||
|
|
12
avatar.go
12
avatar.go
|
@ -22,7 +22,7 @@ import (
|
|||
"gopkg.in/gographics/imagick.v2/imagick"
|
||||
)
|
||||
|
||||
func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte) ([]byte, error) {
|
||||
func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) ([]byte, error) {
|
||||
if u == nil {
|
||||
return nil, errors.New("nil user")
|
||||
}
|
||||
|
@ -73,17 +73,21 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte) ([]byte, erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return u.createGIF(newImg)
|
||||
return u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u))
|
||||
}
|
||||
|
||||
func (u *AudonUser) createGIF(avatar image.Image) ([]byte, error) {
|
||||
func (u *AudonUser) createGIF(avatar image.Image, blue bool) ([]byte, error) {
|
||||
avatarPNG := image.NewRGBA(image.Rect(0, 0, 150, 150))
|
||||
draw.BiLinear.Scale(avatarPNG, avatarPNG.Rect, avatar, avatar.Bounds(), draw.Src, nil)
|
||||
|
||||
baseFrame := image.NewRGBA(avatarPNG.Bounds())
|
||||
draw.Draw(baseFrame, baseFrame.Bounds(), image.Black, image.Point{}, draw.Src)
|
||||
draw.Copy(baseFrame, image.Point{}, avatarPNG, avatarPNG.Bounds(), draw.Over, nil)
|
||||
draw.Draw(baseFrame, baseFrame.Bounds(), mainConfig.LogoImageBack, image.Point{-55, -105}, draw.Over)
|
||||
logoImageBack := mainConfig.LogoImageWhiteBack
|
||||
if blue {
|
||||
logoImageBack = mainConfig.LogoImageBlueBack
|
||||
}
|
||||
draw.Draw(baseFrame, baseFrame.Bounds(), logoImageBack, image.Point{-55, -105}, draw.Over)
|
||||
|
||||
anim := webpanimation.NewWebpAnimation(150, 150, 0)
|
||||
defer anim.ReleaseMemory()
|
||||
|
|
37
config.go
37
config.go
|
@ -21,11 +21,12 @@ type (
|
|||
}
|
||||
|
||||
AppConfigBase struct {
|
||||
LocalDomain string `validate:"required,hostname|hostname_port"`
|
||||
Environment string `validate:"printascii"`
|
||||
StorageDir string
|
||||
LogoImageBack image.Image
|
||||
LogoImageFront image.Image
|
||||
LocalDomain string `validate:"required,hostname|hostname_port"`
|
||||
Environment string `validate:"printascii"`
|
||||
StorageDir string
|
||||
LogoImageBlueBack image.Image
|
||||
LogoImageWhiteBack image.Image
|
||||
LogoImageFront image.Image
|
||||
}
|
||||
|
||||
LivekitConfig struct {
|
||||
|
@ -92,12 +93,21 @@ func loadConfig(envname string) (*AppConfig, error) {
|
|||
return nil, err
|
||||
}
|
||||
publicDir, _ := filepath.Abs("public")
|
||||
logoBack, err := os.Open(filepath.Join(publicDir, "logo_back.png"))
|
||||
logoBlueBack, err := os.Open(filepath.Join(publicDir, "logo_back_blue.png"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer logoBack.Close()
|
||||
logoBackPng, err := png.Decode(logoBack)
|
||||
defer logoBlueBack.Close()
|
||||
logoBlueBackPng, err := png.Decode(logoBlueBack)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logoWhiteBack, err := os.Open(filepath.Join(publicDir, "logo_back_white.png"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer logoWhiteBack.Close()
|
||||
logoWhiteBackPng, err := png.Decode(logoWhiteBack)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -112,11 +122,12 @@ func loadConfig(envname string) (*AppConfig, error) {
|
|||
}
|
||||
|
||||
basicConf := AppConfigBase{
|
||||
LocalDomain: os.Getenv("LOCAL_DOMAIN"),
|
||||
Environment: envname,
|
||||
StorageDir: storageDir,
|
||||
LogoImageBack: logoBackPng,
|
||||
LogoImageFront: logoFrontPng,
|
||||
LocalDomain: os.Getenv("LOCAL_DOMAIN"),
|
||||
Environment: envname,
|
||||
StorageDir: storageDir,
|
||||
LogoImageBlueBack: logoBlueBackPng,
|
||||
LogoImageWhiteBack: logoWhiteBackPng,
|
||||
LogoImageFront: logoFrontPng,
|
||||
}
|
||||
if err := mainValidator.Struct(&basicConf); err != nil {
|
||||
return nil, err
|
||||
|
|
Przed Szerokość: | Wysokość: | Rozmiar: 5.6 KiB Po Szerokość: | Wysokość: | Rozmiar: 5.6 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 5.6 KiB |
101
room.go
101
room.go
|
@ -326,66 +326,63 @@ func joinRoomHandler(c echo.Context) (err error) {
|
|||
|
||||
roomMetadata.MastodonAccounts[user.AudonID] = mastoAccount
|
||||
|
||||
// Get ready to change avatar if user is host or cohost
|
||||
if room.IsHost(user) || room.IsCoHost(user) {
|
||||
// Get user's stored avatar if exists
|
||||
if user.AvatarFile != "" {
|
||||
orig, err := os.ReadFile(user.getAvatarImagePath(user.AvatarFile))
|
||||
if err == nil && orig != nil {
|
||||
resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(orig), base64.StdEncoding.EncodeToString(orig))
|
||||
} else if orig == nil {
|
||||
user.AvatarFile = ""
|
||||
}
|
||||
// icon, err := os.ReadFile(user.GetGIFAvatarPath())
|
||||
// if err == nil && icon != nil {
|
||||
// resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(icon))
|
||||
// }
|
||||
// Get user's stored avatar if exists
|
||||
if user.AvatarFile != "" {
|
||||
orig, err := os.ReadFile(user.getAvatarImagePath(user.AvatarFile))
|
||||
if err == nil && orig != nil {
|
||||
resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(orig), base64.StdEncoding.EncodeToString(orig))
|
||||
} else if orig == nil {
|
||||
user.AvatarFile = ""
|
||||
}
|
||||
avatarLink := mastoAccount.Avatar
|
||||
if err := mainValidator.Var(&avatarLink, "required"); err != nil {
|
||||
return wrapValidationError(err)
|
||||
}
|
||||
avatarURL, err := url.Parse(avatarLink)
|
||||
// icon, err := os.ReadFile(user.GetGIFAvatarPath())
|
||||
// if err == nil && icon != nil {
|
||||
// resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(icon))
|
||||
// }
|
||||
}
|
||||
avatarLink := mastoAccount.Avatar
|
||||
if err := mainValidator.Var(&avatarLink, "required"); err != nil {
|
||||
return wrapValidationError(err)
|
||||
}
|
||||
avatarURL, err := url.Parse(avatarLink)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
|
||||
// Retrieve user's current avatar if the old one doesn't exist in Audon.
|
||||
// Skips if user is still in another room.
|
||||
if already, err := user.InLivekit(c.Request().Context()); !already && err == nil && user.AvatarFile == "" {
|
||||
// Download user's avatar
|
||||
req, err := http.NewRequest(http.MethodGet, avatarURL.String(), nil)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
req.Header.Set("User-Agent", USER_AGENT)
|
||||
|
||||
// Retrieve user's current avatar if the old one doesn't exist in Audon.
|
||||
// Skips if user is still in another room.
|
||||
if already, err := user.InLivekit(c.Request().Context()); !already && err == nil && user.AvatarFile == "" {
|
||||
// Download user's avatar
|
||||
req, err := http.NewRequest(http.MethodGet, avatarURL.String(), nil)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
req.Header.Set("User-Agent", USER_AGENT)
|
||||
|
||||
avatarResp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
defer avatarResp.Body.Close()
|
||||
|
||||
fnew, err := io.ReadAll(avatarResp.Body)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Generate indicator GIF
|
||||
indicator, err := user.GetIndicator(c.Request().Context(), fnew)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
}
|
||||
resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(fnew), base64.StdEncoding.EncodeToString(fnew))
|
||||
resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(indicator))
|
||||
} else if err != nil {
|
||||
avatarResp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return ErrInvalidRequestFormat
|
||||
}
|
||||
defer avatarResp.Body.Close()
|
||||
|
||||
fnew, err := io.ReadAll(avatarResp.Body)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Generate indicator GIF
|
||||
indicator, err := user.GetIndicator(c.Request().Context(), fnew, room)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||
}
|
||||
resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(fnew), base64.StdEncoding.EncodeToString(fnew))
|
||||
resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(indicator))
|
||||
} else if err != nil {
|
||||
c.Logger().Error(err)
|
||||
}
|
||||
|
||||
// Create room in LiveKit if it doesn't exist
|
||||
|
|
|
@ -170,7 +170,7 @@ func main() {
|
|||
|
||||
api := e.Group("/api", authMiddleware)
|
||||
api.GET("/token", getUserTokenHandler)
|
||||
// api.GET("/room", getStatusHandler)
|
||||
api.GET("/room", getStatusHandler)
|
||||
api.POST("/room", createRoomHandler)
|
||||
api.DELETE("/room", leaveRoomHandler)
|
||||
api.POST("/room/:id", joinRoomHandler)
|
||||
|
|
Ładowanie…
Reference in New Issue