Skip to content

Commit fc4164f

Browse files
committed
Added text overlay. Remove caption mode
1 parent 75bf509 commit fc4164f

5 files changed

Lines changed: 368 additions & 239 deletions

File tree

pkg/discord/bot.go

Lines changed: 78 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"log"
9+
"log/slog"
10+
"net/http"
11+
"regexp"
12+
"strconv"
13+
"strings"
14+
"sync"
15+
"time"
16+
817
"github.com/bwmarrin/discordgo"
918
"github.com/warmans/tvgif/pkg/discord/media"
1019
"github.com/warmans/tvgif/pkg/docs"
@@ -16,14 +25,6 @@ import (
1625
"github.com/warmans/tvgif/pkg/searchterms"
1726
"github.com/warmans/tvgif/pkg/store"
1827
"github.com/warmans/tvgif/pkg/util"
19-
"log"
20-
"log/slog"
21-
"net/http"
22-
"regexp"
23-
"strconv"
24-
"strings"
25-
"sync"
26-
"time"
2728
)
2829

2930
const SubSeparator = "---"
@@ -47,18 +48,18 @@ const (
4748

4849
const (
4950
ActionOpenCustomTextModal = Action("cstm")
50-
ActionOpenCaptionModal = Action("ctm")
5151
ActionOpenExtendTrimModal = Action("oem")
5252
ActionOpenMergeModal = Action("omm")
5353
ActionOpenAdvancedOverlayModal = Action("aom")
54+
ActionOpenTextOverlayModal = Action("tom")
5455
)
5556

5657
const (
5758
ModalSetSubs = Action("m_ss")
5859
ModalActionSetExtendValue = Action("m_sev")
5960
ModalActionMergeSubs = Action("m_ms")
60-
ModalSetCaption = Action("m_sc")
6161
ModalSetBoomerOverlayLayout = Action("m_bml")
62+
ModalSetTextOverlayLayout = Action("m_tol")
6263
)
6364

6465
var postedByUser = regexp.MustCompile(`.+ posted by \x60([^\x60]+)\x60`)
@@ -202,18 +203,18 @@ func NewBot(
202203
ActionNextResult: bot.btnNextResult,
203204
ActionPrevResult: bot.btnPreviewResult,
204205
ActionOpenCustomTextModal: bot.btnOpenCustomTextModal,
205-
ActionOpenCaptionModal: bot.btnOpenCaptionModal,
206206
ActionOpenExtendTrimModal: bot.btnOpenExtendModal,
207207
ActionOpenMergeModal: bot.btnOpenMergeModal,
208208
ActionOpenAdvancedOverlayModal: bot.btnOpenAdvancedOverlayModal,
209+
ActionOpenTextOverlayModal: bot.btnOpenTextOverlayModal,
209210
ActionUpdateState: bot.btnUpdateState,
210211
}
211212
bot.modalHandlers = map[Action]func(s *discordgo.Session, i *discordgo.InteractionCreate){
212213
ModalSetSubs: bot.handleModalSetSubs,
213-
ModalSetCaption: bot.handleModalSetCaption,
214214
ModalActionSetExtendValue: bot.handleModalSetExtendTrimValue,
215215
ModalActionMergeSubs: bot.handleModalMergeSubs,
216216
ModalSetBoomerOverlayLayout: bot.handleModalBoomerModeLayout,
217+
ModalSetTextOverlayLayout: bot.handleModalTextOverlayLayout,
217218
}
218219

219220
return bot, nil
@@ -704,45 +705,6 @@ func (b *Bot) btnOpenCustomTextModal(s *discordgo.Session, i *discordgo.Interact
704705
}
705706
}
706707

707-
func (b *Bot) btnOpenCaptionModal(s *discordgo.Session, i *discordgo.InteractionCreate, rawMediaID string) {
708-
mediaID, err := media.ParseID(rawMediaID)
709-
if err != nil {
710-
b.respondError(s, i, fmt.Errorf("invalid mediaID"))
711-
return
712-
}
713-
714-
state, err := extractStateFromBody(i.Message.Content)
715-
if err != nil {
716-
b.respondError(s, i, fmt.Errorf("failed to get current state"))
717-
return
718-
}
719-
720-
fields := []discordgo.MessageComponent{discordgo.ActionsRow{
721-
Components: []discordgo.MessageComponent{
722-
discordgo.TextInput{
723-
CustomID: "caption",
724-
Label: "Caption",
725-
Style: discordgo.TextInputParagraph,
726-
Required: true,
727-
MaxLength: 128,
728-
Value: state.Settings.Caption,
729-
Placeholder: "Caption added to top of image",
730-
},
731-
},
732-
}}
733-
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
734-
Type: discordgo.InteractionResponseModal,
735-
Data: &discordgo.InteractionResponseData{
736-
CustomID: encodeAction(ModalSetCaption, mediaID),
737-
Title: "Set Caption",
738-
Components: fields,
739-
},
740-
})
741-
if err != nil {
742-
b.respondError(s, i, err)
743-
}
744-
}
745-
746708
func (b *Bot) btnOpenExtendModal(s *discordgo.Session, i *discordgo.InteractionCreate, rawMediaID string) {
747709
state, err := extractStateFromBody(i.Message.Content)
748710
if err != nil {
@@ -801,6 +763,28 @@ func (b *Bot) btnOpenAdvancedOverlayModal(s *discordgo.Session, i *discordgo.Int
801763
)
802764
}
803765

766+
func (b *Bot) btnOpenTextOverlayModal(s *discordgo.Session, i *discordgo.InteractionCreate, rawMediaID string) {
767+
state, err := extractStateFromBody(i.Message.Content)
768+
if err != nil {
769+
b.respondError(s, i, fmt.Errorf("failed to get current state"))
770+
return
771+
}
772+
773+
b.openGenericValueModal(
774+
s,
775+
i,
776+
rawMediaID,
777+
ModalSetTextOverlayLayout,
778+
"Text Layout",
779+
util.IfElse(
780+
state.Settings.TextOverlayLayout != "",
781+
state.Settings.TextOverlayLayout,
782+
b.getTextOverlayInitialLayout(),
783+
),
784+
discordgo.TextInputParagraph,
785+
)
786+
}
787+
804788
func (b *Bot) openGenericValueModal(
805789
s *discordgo.Session,
806790
i *discordgo.InteractionCreate,
@@ -969,17 +953,6 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
969953
}
970954
extendButtons := []discordgo.MessageComponent{}
971955

972-
if dialogDuration+(time.Second/2) <= limits.MaxGifDuration {
973-
extendButtons = append(extendButtons, discordgo.Button{
974-
Label: "0.5s",
975-
Emoji: &discordgo.ComponentEmoji{
976-
Name: "➕",
977-
},
978-
Style: discordgo.SecondaryButton,
979-
Disabled: false,
980-
CustomID: StateSetExtendOrTrim(state.Settings.ExtendOrTrim + (time.Second / 2)).CustomID(),
981-
})
982-
}
983956
if dialogDuration+time.Second <= limits.MaxGifDuration {
984957
extendButtons = append(extendButtons, discordgo.Button{
985958
Label: "1s",
@@ -1060,16 +1033,7 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
10601033
CustomID: StateSetMode(NormalMode).CustomID(),
10611034
},
10621035
discordgo.Button{
1063-
Label: "Caption",
1064-
Emoji: &discordgo.ComponentEmoji{
1065-
Name: "🎨",
1066-
},
1067-
Style: successBtnIfTrue(state.Settings.Mode == CaptionMode),
1068-
Disabled: false,
1069-
CustomID: StateSetMode(CaptionMode).CustomID(),
1070-
},
1071-
discordgo.Button{
1072-
Label: "Boomer",
1036+
Label: "Overlay",
10731037
Emoji: &discordgo.ComponentEmoji{
10741038
Name: "🎨",
10751039
},
@@ -1080,20 +1044,6 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
10801044
}
10811045

10821046
captionButtons := []discordgo.MessageComponent{}
1083-
if state.Settings.Mode == CaptionMode {
1084-
captionButtons = append(captionButtons, discordgo.Button{
1085-
Label: "Set Caption",
1086-
Style: discordgo.SecondaryButton,
1087-
Disabled: false,
1088-
CustomID: encodeAction(ActionOpenCaptionModal, state.ID),
1089-
})
1090-
captionButtons = append(captionButtons, discordgo.Button{
1091-
Label: "Toggle Subs",
1092-
Style: discordgo.SecondaryButton,
1093-
Disabled: false,
1094-
CustomID: StateSetSubsEnabled(!state.Settings.SubsEnabled).CustomID(),
1095-
})
1096-
}
10971047

10981048
boomerButtons := []discordgo.MessageComponent{}
10991049
if state.Settings.Mode == BoomerMode {
@@ -1115,6 +1065,15 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
11151065
Disabled: false,
11161066
URL: "http://tvgif.scrimpton.com:8080/overlays/index.html",
11171067
})
1068+
captionButtons = append(captionButtons, discordgo.Button{
1069+
Label: "Add Text",
1070+
Emoji: &discordgo.ComponentEmoji{
1071+
Name: "💬",
1072+
},
1073+
Style: successBtnIfTrue(state.Settings.TextOverlayLayout != ""),
1074+
Disabled: false,
1075+
CustomID: encodeAction(ActionOpenTextOverlayModal, state.ID),
1076+
})
11181077
}
11191078

11201079
postActions := []discordgo.MessageComponent{discordgo.Button{
@@ -1159,7 +1118,7 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
11591118
},
11601119
discordgo.Button{
11611120
Label: "Toggle Preview",
1162-
Style: successBtnIfTrue(state.Settings.Mode == CaptionMode),
1121+
Style: successBtnIfTrue(state.Settings.DisablePreviewImage),
11631122
Disabled: false,
11641123
CustomID: TogglePreview().CustomID(),
11651124
},
@@ -1169,10 +1128,10 @@ func (b *Bot) createButtons(dialog []model2.Dialog, state *PreviewState) ([]disc
11691128
if len(navigateButtons) > 0 && state.Settings.Mode == NormalMode {
11701129
actions = append(actions, discordgo.ActionsRow{Components: navigateButtons})
11711130
}
1172-
if len(shiftButtons) > 0 && state.Settings.Mode != CaptionMode {
1131+
if len(shiftButtons) > 0 {
11731132
actions = append(actions, discordgo.ActionsRow{Components: shiftButtons})
11741133
}
1175-
if len(extendButtons) > 0 && state.Settings.Mode != CaptionMode {
1134+
if len(extendButtons) > 0 {
11761135
actions = append(actions, discordgo.ActionsRow{Components: extendButtons})
11771136
}
11781137

@@ -1269,16 +1228,6 @@ func (b *Bot) btnUpdateState(s *discordgo.Session, i *discordgo.InteractionCreat
12691228
b.updatePreview(s, i, update)
12701229
}
12711230

1272-
func (b *Bot) handleModalSetCaption(s *discordgo.Session, i *discordgo.InteractionCreate) {
1273-
b.updatePreview(
1274-
s,
1275-
i,
1276-
StateSetCaption(
1277-
i.Interaction.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value,
1278-
),
1279-
)
1280-
}
1281-
12821231
func (b *Bot) handleModalSetSubs(s *discordgo.Session, i *discordgo.InteractionCreate) {
12831232
b.updatePreview(
12841233
s,
@@ -1361,6 +1310,16 @@ func (b *Bot) handleModalBoomerModeLayout(s *discordgo.Session, i *discordgo.Int
13611310
)
13621311
}
13631312

1313+
func (b *Bot) handleModalTextOverlayLayout(s *discordgo.Session, i *discordgo.InteractionCreate) {
1314+
b.updatePreview(
1315+
s,
1316+
i,
1317+
SetTextOverlayLayout(
1318+
i.Interaction.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value,
1319+
),
1320+
)
1321+
}
1322+
13641323
func (b *Bot) btnPostFromPreview(s *discordgo.Session, i *discordgo.InteractionCreate, payload string) {
13651324

13661325
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
@@ -1555,7 +1514,7 @@ func (b *Bot) respondError(s *discordgo.Session, i *discordgo.InteractionCreate,
15551514

15561515
func (b *Bot) renderFile(state *PreviewState, dialog []model2.Dialog, preview bool) (*discordgo.File, error) {
15571516

1558-
disableCaching := state.Settings.ExtendOrTrim != 0 || state.Settings.Shift != 0 || state.Settings.OverrideSubs != nil || (state.Settings.Mode != NormalMode)
1517+
disableCaching := state.Settings.ExtendOrTrim != 0 || state.Settings.Shift != 0 || state.Settings.OverrideSubs != nil || (state.Settings.Mode != NormalMode) || state.Settings.TextOverlayLayout != ""
15591518
startTimestamp := dialog[0].StartTimestamp
15601519
endTimestamp := dialog[len(dialog)-1].EndTimestamp
15611520

@@ -1589,20 +1548,14 @@ func (b *Bot) renderFile(state *PreviewState, dialog []model2.Dialog, preview bo
15891548
render.WithCustomText(state.Settings.OverrideSubs),
15901549
render.WithStartTimestamp(startTimestamp),
15911550
render.WithEndTimestamp(endTimestamp),
1551+
render.WithTextOverlayLayout(state.Settings.TextOverlayLayout),
15921552
}
15931553
if state.Settings.Mode == BoomerMode {
15941554
options = append(options,
15951555
render.WithOverlayLayout(util.IfElse(state.Settings.BoomerModeOpts.Layout != "", state.Settings.BoomerModeOpts.Layout, "")),
15961556
render.WithGrid(preview),
15971557
)
15981558
}
1599-
if state.Settings.Mode == CaptionMode {
1600-
options = append(options,
1601-
render.WithCaptionMode(true),
1602-
render.WithCaption(state.Settings.Caption),
1603-
render.WithDisableSubs(state.Settings.SubsEnabled),
1604-
)
1605-
}
16061559
if state.Settings.Mode == StickerMode {
16071560
var opts *render.StickerModeOpts
16081561

@@ -1817,6 +1770,24 @@ func (b *Bot) getBoomerModeInitialLayout() string {
18171770
return strings.Join(out, "\n")
18181771
}
18191772

1773+
func (b *Bot) getTextOverlayInitialLayout() string {
1774+
return `# Remove hash to enable a text overlay.
1775+
# Each line is one text element:
1776+
#
1777+
# [X cell]x[Y cell] [start seconds]-[end seconds] [scale] [text]
1778+
#
1779+
# Use * as the time range to show the text for the whole gif.
1780+
# Cell numbers are decimals and start at 0 (so you can do e.g. 3.5).
1781+
# The scale is optional e.g. 1 = 100%, 2 = 200%, 0.5 = 50%.
1782+
#
1783+
# Examples:
1784+
# 3x0.5 * hello world
1785+
# 0x4 0.5-2 shown from 0.5s to 2s
1786+
# 5x2 1-* shown from 1s to the end
1787+
# 2x2 * 2 double size text
1788+
`
1789+
}
1790+
18201791
func encodeAction(action Action, mediaID *media.ID) string {
18211792
return fmt.Sprintf("%s:%s", action, mediaID.String())
18221793
}

0 commit comments

Comments
 (0)