add listener online indicator

peertube
Namekuji 2023-01-25 15:58:15 -05:00
rodzic 906170c110
commit 5b7c6735ed
9 zmienionych plików z 87 dodań i 74 usunięć

Wyświetl plik

@ -64,7 +64,7 @@ startListening: "Start Listening"
browserMuted: "To protect your ears, sound is muted by the browser. Press @:startListening to continue." browserMuted: "To protect your ears, sound is muted by the browser. Press @:startListening to continue."
onlineIndicator: onlineIndicator:
message: "Do you want to add the online indicator to your account's avatar like this?" 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." warning: "Your instance may take a while to reflect the indicator."
sure: "Yes" sure: "Yes"
nope: "No" nope: "No"

Wyświetl plik

@ -63,8 +63,8 @@ errors:
startListening: "視聴を始める" startListening: "視聴を始める"
browserMuted: "大きな音であなたが驚かないよう、無音になっています。続行するには @:startListening ボタンを押してください。" browserMuted: "大きな音であなたが驚かないよう、無音になっています。続行するには @:startListening ボタンを押してください。"
onlineIndicator: onlineIndicator:
message: "あなたが部屋をホスト中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。" message: "あなたが部屋に参加中であることを表示しますか?「表示する」を選ぶとアカウントのアバターがこのようになります。"
hint: "部屋を閉じた後、アバターは自動で元に戻ります。" hint: "部屋から退出後、アバターは自動で元に戻ります。"
warning: "サーバーが変更を反映するまで時間がかかることがあります。" warning: "サーバーが変更を反映するまで時間がかかることがあります。"
sure: "表示する" sure: "表示する"
nope: "表示しない" nope: "表示しない"

Wyświetl plik

@ -48,7 +48,8 @@ export const useMastodonStore = defineStore("mastodon", {
}, },
async revertAvatar() { async revertAvatar() {
const token = await axios.get("/api/token"); 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) { if (this.avatar) {
await this.updateAvatar(this.avatar, token.data.audon.avatar); await this.updateAvatar(this.avatar, token.data.audon.avatar);
} }

Wyświetl plik

@ -22,7 +22,7 @@ import (
"gopkg.in/gographics/imagick.v2/imagick" "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 { if u == nil {
return nil, errors.New("nil user") return nil, errors.New("nil user")
} }
@ -73,17 +73,21 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte) ([]byte, erro
if err != nil { if err != nil {
return nil, err 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)) avatarPNG := image.NewRGBA(image.Rect(0, 0, 150, 150))
draw.BiLinear.Scale(avatarPNG, avatarPNG.Rect, avatar, avatar.Bounds(), draw.Src, nil) draw.BiLinear.Scale(avatarPNG, avatarPNG.Rect, avatar, avatar.Bounds(), draw.Src, nil)
baseFrame := image.NewRGBA(avatarPNG.Bounds()) baseFrame := image.NewRGBA(avatarPNG.Bounds())
draw.Draw(baseFrame, baseFrame.Bounds(), image.Black, image.Point{}, draw.Src) draw.Draw(baseFrame, baseFrame.Bounds(), image.Black, image.Point{}, draw.Src)
draw.Copy(baseFrame, image.Point{}, avatarPNG, avatarPNG.Bounds(), draw.Over, nil) 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) anim := webpanimation.NewWebpAnimation(150, 150, 0)
defer anim.ReleaseMemory() defer anim.ReleaseMemory()

Wyświetl plik

@ -21,11 +21,12 @@ type (
} }
AppConfigBase struct { AppConfigBase struct {
LocalDomain string `validate:"required,hostname|hostname_port"` LocalDomain string `validate:"required,hostname|hostname_port"`
Environment string `validate:"printascii"` Environment string `validate:"printascii"`
StorageDir string StorageDir string
LogoImageBack image.Image LogoImageBlueBack image.Image
LogoImageFront image.Image LogoImageWhiteBack image.Image
LogoImageFront image.Image
} }
LivekitConfig struct { LivekitConfig struct {
@ -92,12 +93,21 @@ func loadConfig(envname string) (*AppConfig, error) {
return nil, err return nil, err
} }
publicDir, _ := filepath.Abs("public") 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 { if err != nil {
return nil, err return nil, err
} }
defer logoBack.Close() defer logoBlueBack.Close()
logoBackPng, err := png.Decode(logoBack) 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 { if err != nil {
return nil, err return nil, err
} }
@ -112,11 +122,12 @@ func loadConfig(envname string) (*AppConfig, error) {
} }
basicConf := AppConfigBase{ basicConf := AppConfigBase{
LocalDomain: os.Getenv("LOCAL_DOMAIN"), LocalDomain: os.Getenv("LOCAL_DOMAIN"),
Environment: envname, Environment: envname,
StorageDir: storageDir, StorageDir: storageDir,
LogoImageBack: logoBackPng, LogoImageBlueBack: logoBlueBackPng,
LogoImageFront: logoFrontPng, LogoImageWhiteBack: logoWhiteBackPng,
LogoImageFront: logoFrontPng,
} }
if err := mainValidator.Struct(&basicConf); err != nil { if err := mainValidator.Struct(&basicConf); err != nil {
return nil, err return nil, err

Wyświetl plik

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
Wyświetl plik

@ -326,66 +326,63 @@ func joinRoomHandler(c echo.Context) (err error) {
roomMetadata.MastodonAccounts[user.AudonID] = mastoAccount roomMetadata.MastodonAccounts[user.AudonID] = mastoAccount
// Get ready to change avatar if user is host or cohost // Get user's stored avatar if exists
if room.IsHost(user) || room.IsCoHost(user) { if user.AvatarFile != "" {
// Get user's stored avatar if exists orig, err := os.ReadFile(user.getAvatarImagePath(user.AvatarFile))
if user.AvatarFile != "" { if err == nil && orig != nil {
orig, err := os.ReadFile(user.getAvatarImagePath(user.AvatarFile)) resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(orig), base64.StdEncoding.EncodeToString(orig))
if err == nil && orig != nil { } else if orig == nil {
resp.Original = fmt.Sprintf("data:%s;base64,%s", mimetype.Detect(orig), base64.StdEncoding.EncodeToString(orig)) user.AvatarFile = ""
} 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))
// }
} }
avatarLink := mastoAccount.Avatar // icon, err := os.ReadFile(user.GetGIFAvatarPath())
if err := mainValidator.Var(&avatarLink, "required"); err != nil { // if err == nil && icon != nil {
return wrapValidationError(err) // resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(icon))
} // }
avatarURL, err := url.Parse(avatarLink) }
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 { if err != nil {
c.Logger().Error(err) c.Logger().Error(err)
return ErrInvalidRequestFormat return ErrInvalidRequestFormat
} }
req.Header.Set("User-Agent", USER_AGENT)
// Retrieve user's current avatar if the old one doesn't exist in Audon. avatarResp, err := http.DefaultClient.Do(req)
// Skips if user is still in another room. if err != nil {
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 {
c.Logger().Error(err) 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 // Create room in LiveKit if it doesn't exist

Wyświetl plik

@ -170,7 +170,7 @@ func main() {
api := e.Group("/api", authMiddleware) api := e.Group("/api", authMiddleware)
api.GET("/token", getUserTokenHandler) api.GET("/token", getUserTokenHandler)
// api.GET("/room", getStatusHandler) api.GET("/room", getStatusHandler)
api.POST("/room", createRoomHandler) api.POST("/room", createRoomHandler)
api.DELETE("/room", leaveRoomHandler) api.DELETE("/room", leaveRoomHandler)
api.POST("/room/:id", joinRoomHandler) api.POST("/room/:id", joinRoomHandler)