refactor: rename Format to Quality, add container Audio/Video sub-pickers

- Rename 'Format' button to 'Quality' in settings (audio_quality/video_quality)
- Add DefaultAudioContainer and DefaultVideoContainer to UserPreferences
- Container settings now has Audio/Video sub-pickers (mp3/m4a/opus vs mp4/mkv/webm)
- Add migration 003 for new container columns
- Update repo layer and playlist flow for new fields
- Update back routing: back_quality, back_container
This commit is contained in:
2026-06-25 16:03:03 +03:30
parent e08ed77884
commit 785e20bf94
7 changed files with 112 additions and 53 deletions

View File

@@ -20,9 +20,13 @@ func (h *Handler) buildSettingsKeyboard(userID int64, prefs *domain.UserPreferen
if videoFmt == "" {
videoFmt = "best"
}
containerLabel := prefs.DefaultContainer
if containerLabel == "" {
containerLabel = "mp4"
audioCont := prefs.DefaultAudioContainer
if audioCont == "" {
audioCont = "mp3"
}
videoCont := prefs.DefaultVideoContainer
if videoCont == "" {
videoCont = "mp4"
}
langLabel := prefs.DefaultLanguage
if langLabel == "" {
@@ -31,10 +35,10 @@ func (h *Handler) buildSettingsKeyboard(userID int64, prefs *domain.UserPreferen
rows := [][]models.InlineKeyboardButton{
{
{Text: fmt.Sprintf("Format: %s/%s", audioFmt, videoFmt), CallbackData: "settings_format"},
{Text: fmt.Sprintf("Quality: %s/%s", audioFmt, videoFmt), CallbackData: "settings_quality"},
},
{
{Text: fmt.Sprintf("Container: %s", containerLabel), CallbackData: "settings_container"},
{Text: fmt.Sprintf("Container: %s/%s", audioCont, videoCont), CallbackData: "settings_container"},
{Text: fmt.Sprintf("Language: %s", langLabel), CallbackData: "settings_language"},
},
{{Text: "Delete all data", CallbackData: "deleteaccount", Style: "danger"}},
@@ -69,17 +73,23 @@ func (h *Handler) handleSettingsSelection(ctx context.Context, chatID int64, msg
}
switch setting {
case "format":
text, kb := h.buildFormatPicker(prefs)
case "quality":
text, kb := h.buildQualityAudioVideoPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "format_audio":
text, kb := h.buildAudioFormatPicker(prefs)
case "quality_audio":
text, kb := h.buildAudioQualityPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "format_video":
text, kb := h.buildVideoFormatPicker(prefs)
case "quality_video":
text, kb := h.buildVideoQualityPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "container":
text, kb := h.buildContainerPicker(prefs)
text, kb := h.buildContainerAudioVideoPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "container_audio":
text, kb := h.buildAudioContainerPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "container_video":
text, kb := h.buildVideoContainerPicker(prefs)
h.editText(ctx, chatID, msgID, text, &kb)
case "language":
text, kb := h.buildLanguagePicker(prefs)
@@ -87,16 +97,16 @@ func (h *Handler) handleSettingsSelection(ctx context.Context, chatID int64, msg
}
}
func (h *Handler) buildFormatPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
func (h *Handler) buildQualityAudioVideoPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
rows := [][]models.InlineKeyboardButton{
{{Text: "Audio", CallbackData: "settings_format_audio"}},
{{Text: "Video", CallbackData: "settings_format_video"}},
{{Text: "Audio", CallbackData: "settings_quality_audio"}},
{{Text: "Video", CallbackData: "settings_quality_video"}},
{{Text: "Back to Settings", CallbackData: "back_settings"}},
}
return "Choose format type to set default:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
return "Choose quality type to set default:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildAudioFormatPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
func (h *Handler) buildAudioQualityPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
bitrates := []string{"best", "128k", "192k", "256k", "320k"}
rows := [][]models.InlineKeyboardButton{}
for _, b := range bitrates {
@@ -105,16 +115,16 @@ func (h *Handler) buildAudioFormatPicker(prefs *domain.UserPreferences) (string,
label = "> " + label
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: label, CallbackData: "settings_set_audioformat_" + b},
{Text: label, CallbackData: "settings_set_audioquality_" + b},
})
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: "Back", CallbackData: "back_format"},
{Text: "Back", CallbackData: "back_quality"},
})
return "Select default audio format:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
return "Select default audio quality:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildVideoFormatPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
func (h *Handler) buildVideoQualityPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
resolutions := []string{"best", "2160p", "1440p", "1080p", "720p", "480p", "360p"}
rows := [][]models.InlineKeyboardButton{}
row := []models.InlineKeyboardButton{}
@@ -124,7 +134,7 @@ func (h *Handler) buildVideoFormatPicker(prefs *domain.UserPreferences) (string,
label = "> " + label
}
row = append(row, models.InlineKeyboardButton{
Text: label, CallbackData: "settings_set_videoformat_" + r,
Text: label, CallbackData: "settings_set_videoquality_" + r,
})
if len(row) == 3 || i == len(resolutions)-1 {
rows = append(rows, row)
@@ -132,22 +142,49 @@ func (h *Handler) buildVideoFormatPicker(prefs *domain.UserPreferences) (string,
}
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: "Back", CallbackData: "back_format"},
{Text: "Back", CallbackData: "back_quality"},
})
return "Select default video format:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
return "Select default video quality:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildContainerPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
containers := []string{"mp4", "mkv", "webm", "mp3", "m4a", "opus"}
func (h *Handler) buildContainerAudioVideoPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
rows := [][]models.InlineKeyboardButton{
{{Text: "Audio", CallbackData: "settings_container_audio"}},
{{Text: "Video", CallbackData: "settings_container_video"}},
{{Text: "Back to Settings", CallbackData: "back_settings"}},
}
return "Choose container type to set default:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildAudioContainerPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
containers := []string{"mp3", "m4a", "opus"}
rows := [][]models.InlineKeyboardButton{}
for _, c := range containers {
label := c
if c == prefs.DefaultAudioContainer {
label = "> " + label
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: label, CallbackData: "settings_set_audiocontainer_" + c},
})
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: "Back", CallbackData: "back_container"},
})
return "Select default audio container:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildVideoContainerPicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
containers := []string{"mp4", "mkv", "webm"}
rows := [][]models.InlineKeyboardButton{}
row := []models.InlineKeyboardButton{}
for i, c := range containers {
label := c
if c == prefs.DefaultContainer {
if c == prefs.DefaultVideoContainer {
label = "> " + label
}
row = append(row, models.InlineKeyboardButton{
Text: label, CallbackData: "settings_set_container_" + c,
Text: label, CallbackData: "settings_set_videocontainer_" + c,
})
if len(row) == 3 || i == len(containers)-1 {
rows = append(rows, row)
@@ -155,9 +192,9 @@ func (h *Handler) buildContainerPicker(prefs *domain.UserPreferences) (string, m
}
}
rows = append(rows, []models.InlineKeyboardButton{
{Text: "Back to Settings", CallbackData: "back_settings"},
{Text: "Back", CallbackData: "back_container"},
})
return "Select default container:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
return "Select default video container:", models.InlineKeyboardMarkup{InlineKeyboard: rows}
}
func (h *Handler) buildLanguagePicker(prefs *domain.UserPreferences) (string, models.InlineKeyboardMarkup) {
@@ -203,14 +240,17 @@ func (h *Handler) handleSettingsSet(ctx context.Context, chatID int64, msgID int
changed := false
switch action {
case "audioformat":
case "audioquality":
prefs.DefaultAudioFormat = value
changed = true
case "videoformat":
case "videoquality":
prefs.DefaultVideoFormat = value
changed = true
case "container":
prefs.DefaultContainer = value
case "audiocontainer":
prefs.DefaultAudioContainer = value
changed = true
case "videocontainer":
prefs.DefaultVideoContainer = value
changed = true
case "language":
prefs.DefaultLanguage = value