diff --git a/audon-fe/src/locales/en.yaml b/audon-fe/src/locales/en.yaml index 206cb88..825494b 100644 --- a/audon-fe/src/locales/en.yaml +++ b/audon-fe/src/locales/en.yaml @@ -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" diff --git a/audon-fe/src/locales/ja.yaml b/audon-fe/src/locales/ja.yaml index d7d1ee8..8f8cf65 100644 --- a/audon-fe/src/locales/ja.yaml +++ b/audon-fe/src/locales/ja.yaml @@ -63,8 +63,8 @@ errors: startListening: "視聴を始める" browserMuted: "大きな音であなたが驚かないよう、無音になっています。続行するには @:startListening ボタンを押してください。" onlineIndicator: - message: "あなたが部屋をホスト中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。" - hint: "部屋を閉じた後、アバターは自動で元に戻ります。" + message: "あなたが部屋に参加中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。" + hint: "部屋から退出後、アバターは自動で元に戻ります。" warning: "サーバーが変更を反映するまで時間がかかることがあります。" sure: "表示する" nope: "表示しない" diff --git a/audon-fe/src/stores/mastodon.js b/audon-fe/src/stores/mastodon.js index e4274af..f2df163 100644 --- a/audon-fe/src/stores/mastodon.js +++ b/audon-fe/src/stores/mastodon.js @@ -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); } diff --git a/avatar.go b/avatar.go index 6d35b9a..f3233ca 100644 --- a/avatar.go +++ b/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() diff --git a/config.go b/config.go index efb1c25..9959997 100644 --- a/config.go +++ b/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 diff --git a/public/logo_back.png b/public/logo_back_blue.png similarity index 100% rename from public/logo_back.png rename to public/logo_back_blue.png diff --git a/public/logo_back_white.png b/public/logo_back_white.png new file mode 100644 index 0000000..981c8ab Binary files /dev/null and b/public/logo_back_white.png differ diff --git a/room.go b/room.go index 05a9fea..5f5015c 100644 --- a/room.go +++ b/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 diff --git a/server.go b/server.go index a434fa5..1b236aa 100644 --- a/server.go +++ b/server.go @@ -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)