refactor: redesign format selection with unified list and independent audio/video picking
All checks were successful
CI / build (push) Successful in 52s
All checks were successful
CI / build (push) Successful in 52s
- Replace type/quality selection flow with unified format list (video+audio combined) - Add independent audio/video format picking: video-only formats prompt for audio track, audio-only formats offer optional video addition (skip when content is audio-only) - Fix formatKeyboard to use format IDs as callback data instead of display labels - Remove dead mediaTypeKeyboard function - Fix double-close panic in readProgress (caller is sole owner of updates channel) - Add FormatString field to DownloadJob for composite format specs (e.g. '137+140') - Change quota calculation from sum of all format sizes to max single format size - Fix 'Delete all data' button to use danger style with proper text - Clean up routePrefixedCallback: remove type_/quality_, add format_/secondary_ routes - Fix back navigation to rebuild format IDs list
This commit is contained in:
@@ -231,8 +231,7 @@ func (h *Handler) HandleCallback(ctx context.Context, cb *models.CallbackQuery)
|
||||
h.handleHelp(ctx, cb.Message.Message)
|
||||
h.answerCb(ctx, cb.ID)
|
||||
case data == "history":
|
||||
h.handleHistory(ctx, cb.Message.Message, userID)
|
||||
h.answerCb(ctx, cb.ID)
|
||||
h.historyCallback(ctx, chatID, msgID, cb.ID, userID)
|
||||
case data == "pending_cancel":
|
||||
h.backToMenu(ctx, chatID, msgID, cb.ID, userID)
|
||||
default:
|
||||
@@ -244,10 +243,10 @@ func (h *Handler) routePrefixedCallback(ctx context.Context, chatID int64, msgID
|
||||
defer h.answerCb(ctx, cbID)
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(data, "type_"):
|
||||
h.handleTypeSelection(ctx, chatID, msgID, userID, data[5:])
|
||||
case strings.HasPrefix(data, "quality_"):
|
||||
h.handleQualitySelection(ctx, chatID, msgID, userID, data[8:])
|
||||
case strings.HasPrefix(data, "format_"):
|
||||
h.handleFormatSelection(ctx, chatID, msgID, userID, data[7:])
|
||||
case strings.HasPrefix(data, "secondary_"):
|
||||
h.handleSecondarySelection(ctx, chatID, msgID, userID, data[10:])
|
||||
case strings.HasPrefix(data, "lang_"):
|
||||
h.handleLanguageSelection(ctx, chatID, msgID, userID, data[5:])
|
||||
case strings.HasPrefix(data, "container_"):
|
||||
@@ -262,14 +261,10 @@ func (h *Handler) routePrefixedCallback(ctx context.Context, chatID int64, msgID
|
||||
h.handlePlaylistConfirm(ctx, chatID, msgID, userID)
|
||||
case data == "back_settings":
|
||||
h.backToSettings(ctx, chatID, msgID, userID)
|
||||
case data == "delaccount_prompt":
|
||||
h.deleteAccountPrompt(ctx, chatID, msgID, userID)
|
||||
case strings.HasPrefix(data, "delaccount_"):
|
||||
h.deleteAccountConfirm(ctx, chatID, msgID, userID)
|
||||
case strings.HasPrefix(data, "settings_"):
|
||||
h.handleSettingsSelection(ctx, chatID, msgID, userID, data[9:])
|
||||
case strings.HasPrefix(data, "settings_set_"):
|
||||
h.handleSettingsSet(ctx, chatID, msgID, userID, data[13:])
|
||||
case strings.HasPrefix(data, "settings_"):
|
||||
h.handleSettingsSelection(ctx, chatID, msgID, userID, data[9:])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,8 +362,10 @@ func (h *Handler) answerCbWithText(ctx context.Context, callbackID, text string)
|
||||
func (h *Handler) backToMenu(ctx context.Context, chatID int64, msgID int, cbID string, userID int64) {
|
||||
defer h.answerCb(ctx, cbID)
|
||||
h.clearActiveJob(userID)
|
||||
h.editText(ctx, chatID, msgID, "Main Menu:", nil)
|
||||
h.sendWithKB(ctx, chatID, "Main Menu:", mainKeyboard())
|
||||
h.editText(ctx, chatID, msgID, "Main Menu:", &models.InlineKeyboardMarkup{
|
||||
InlineKeyboard: mainKeyboard().InlineKeyboard,
|
||||
})
|
||||
h.clearStepState(chatID)
|
||||
}
|
||||
|
||||
func (h *Handler) clearActiveJob(userID int64) {
|
||||
@@ -451,7 +448,7 @@ func (h *Handler) handleSettings(ctx context.Context, msg *models.Message, userI
|
||||
func (h *Handler) handleHistory(ctx context.Context, msg *models.Message, userID int64) {
|
||||
records, err := h.Repo.GetHistory(userID, 10, 0)
|
||||
if err != nil {
|
||||
h.sendText(ctx, msg.Chat.ID, "Error loading history")
|
||||
h.sendText(ctx, msg.Chat.ID, "Error loading history.")
|
||||
return
|
||||
}
|
||||
if len(records) == 0 {
|
||||
@@ -465,6 +462,37 @@ func (h *Handler) handleHistory(ctx context.Context, msg *models.Message, userID
|
||||
h.sendText(ctx, msg.Chat.ID, text)
|
||||
}
|
||||
|
||||
// historyCallback handles the history button from the main menu.
|
||||
func (h *Handler) historyCallback(ctx context.Context, chatID int64, msgID int, cbID string, userID int64) {
|
||||
defer h.answerCb(ctx, cbID)
|
||||
records, err := h.Repo.GetHistory(userID, 10, 0)
|
||||
if err != nil {
|
||||
h.editText(ctx, chatID, msgID, "Error loading history.", &models.InlineKeyboardMarkup{
|
||||
InlineKeyboard: [][]models.InlineKeyboardButton{
|
||||
{{Text: "Back to Menu", CallbackData: "back_menu"}},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
if len(records) == 0 {
|
||||
h.editText(ctx, chatID, msgID, "No download history yet.", &models.InlineKeyboardMarkup{
|
||||
InlineKeyboard: [][]models.InlineKeyboardButton{
|
||||
{{Text: "Back to Menu", CallbackData: "back_menu"}},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
text := "Recent downloads:\n"
|
||||
for i, r := range records {
|
||||
text += fmt.Sprintf("%d. %s (%s)\n", i+1, r.Title, formatBytes(r.FileSize))
|
||||
}
|
||||
h.editText(ctx, chatID, msgID, text, &models.InlineKeyboardMarkup{
|
||||
InlineKeyboard: [][]models.InlineKeyboardButton{
|
||||
{{Text: "Back to Menu", CallbackData: "back_menu"}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// applyQuota adds file size to the user's quota counters.
|
||||
func (h *Handler) applyQuota(userID int64, fileSize int64) {
|
||||
q, err := h.Repo.GetOrCreateQuotas(userID)
|
||||
|
||||
Reference in New Issue
Block a user