You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
430 lines
11 KiB
430 lines
11 KiB
package ui |
|
|
|
import ( |
|
"fmt" |
|
|
|
"github.com/RasmusLindroth/go-mastodon" |
|
"github.com/gdamore/tcell/v2" |
|
"github.com/rivo/tview" |
|
) |
|
|
|
var visibilitiesPrefStr = []string{ |
|
mastodon.VisibilityPublic, |
|
mastodon.VisibilityUnlisted, |
|
mastodon.VisibilityFollowersOnly, |
|
} |
|
|
|
type preferences struct { |
|
displayname string |
|
bio string |
|
fields []mastodon.Field |
|
visibility string |
|
} |
|
|
|
type PreferenceView struct { |
|
tutView *TutView |
|
shared *Shared |
|
View *tview.Flex |
|
displayName *tview.TextView |
|
bio *tview.TextView |
|
fields *tview.List |
|
visibility *tview.DropDown |
|
controls *tview.Flex |
|
preferences *preferences |
|
fieldFocus bool |
|
} |
|
|
|
func NewPreferenceView(tv *TutView) *PreferenceView { |
|
p := &PreferenceView{ |
|
tutView: tv, |
|
shared: tv.Shared, |
|
displayName: NewTextView(tv.tut.Config), |
|
bio: NewTextView(tv.tut.Config), |
|
fields: NewList(tv.tut.Config), |
|
visibility: NewDropDown(tv.tut.Config), |
|
controls: NewControlView(tv.tut.Config), |
|
preferences: &preferences{}, |
|
} |
|
p.View = preferenceViewUI(p) |
|
p.MainFocus() |
|
p.Update() |
|
|
|
return p |
|
} |
|
|
|
func preferenceViewUI(p *PreferenceView) *tview.Flex { |
|
p.visibility.SetLabel("Default toot visibility: ") |
|
p.visibility.SetOptions(visibilitiesPrefStr, p.visibilitySelected) |
|
|
|
r := tview.NewFlex().SetDirection(tview.FlexRow) |
|
if p.tutView.tut.Config.General.TerminalTitle < 2 { |
|
r.AddItem(p.shared.Top.View, 1, 0, false) |
|
} |
|
r.AddItem(tview.NewFlex().SetDirection(tview.FlexColumn). |
|
AddItem(tview.NewFlex().SetDirection(tview.FlexRow). |
|
AddItem(p.displayName, 1, 0, false). |
|
AddItem(p.visibility, 2, 0, false). |
|
AddItem(p.fields, 0, 1, false), 0, 1, false). |
|
AddItem(tview.NewFlex().SetDirection(tview.FlexRow). |
|
AddItem(p.bio, 0, 1, false), 0, 1, false), 0, 1, false). |
|
AddItem(p.controls, 1, 0, false). |
|
AddItem(p.shared.Bottom.View, 2, 0, false) |
|
return r |
|
} |
|
|
|
func (p *PreferenceView) Update() { |
|
pf := &preferences{} |
|
me := p.tutView.tut.Client.Me |
|
pf.displayname = me.DisplayName |
|
if me.Source != nil { |
|
if me.Source.Note != nil { |
|
pf.bio = *me.Source.Note |
|
} |
|
if me.Source.Fields != nil { |
|
for _, f := range *me.Source.Fields { |
|
pf.fields = append(pf.fields, mastodon.Field{ |
|
Name: f.Name, |
|
Value: f.Value, |
|
}) |
|
} |
|
} |
|
if me.Source.Privacy != nil { |
|
pf.visibility = *me.Source.Privacy |
|
} |
|
} |
|
p.preferences = pf |
|
p.update() |
|
} |
|
|
|
func (p *PreferenceView) update() { |
|
pf := p.preferences |
|
p.displayName.SetText(fmt.Sprintf("Display name: %s", tview.Escape(pf.displayname))) |
|
p.bio.SetText(fmt.Sprintf("Bio:\n%s", tview.Escape(pf.bio))) |
|
|
|
p.fields.Clear() |
|
for _, f := range pf.fields { |
|
p.fields.AddItem(fmt.Sprintf("%s: %s\n", tview.Escape(f.Name), tview.Escape(f.Value)), "", 0, nil) |
|
} |
|
|
|
index := 0 |
|
for i, v := range visibilitiesPrefStr { |
|
if pf.visibility == v { |
|
index = i |
|
break |
|
} |
|
} |
|
p.visibility.SetCurrentOption(index) |
|
} |
|
|
|
func (p *PreferenceView) HasFieldFocus() bool { |
|
return p.fieldFocus |
|
} |
|
|
|
func (p *PreferenceView) FieldFocus() { |
|
p.fieldFocus = true |
|
|
|
var items []Control |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceFieldsAdd, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceFieldsEdit, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceFieldsDelete, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.GlobalBack, true)) |
|
p.controls.Clear() |
|
for i, item := range items { |
|
if i < len(items)-1 { |
|
p.controls.AddItem(NewControlButton(p.tutView, item), item.Len+1, 0, false) |
|
} else { |
|
p.controls.AddItem(NewControlButton(p.tutView, item), item.Len, 0, false) |
|
} |
|
} |
|
cnf := p.tutView.tut.Config |
|
p.fields.SetSelectedBackgroundColor(cnf.Style.ListSelectedBackground) |
|
p.fields.SetSelectedTextColor(cnf.Style.ListSelectedText) |
|
} |
|
|
|
func (p *PreferenceView) MainFocus() { |
|
p.fieldFocus = false |
|
|
|
var items []Control |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceName, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceVisibility, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceBio, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceFields, true)) |
|
items = append(items, NewControl(p.tutView.tut.Config, p.tutView.tut.Config.Input.PreferenceSave, true)) |
|
p.controls.Clear() |
|
for i, item := range items { |
|
if i < len(items)-1 { |
|
p.controls.AddItem(NewControlButton(p.tutView, item), item.Len+1, 0, false) |
|
} else { |
|
p.controls.AddItem(NewControlButton(p.tutView, item), item.Len, 0, false) |
|
} |
|
} |
|
|
|
cnf := p.tutView.tut.Config |
|
p.fields.SetSelectedBackgroundColor(cnf.Style.Background) |
|
p.fields.SetSelectedTextColor(cnf.Style.Text) |
|
} |
|
|
|
func (p *PreferenceView) PrevField() { |
|
index := p.fields.GetCurrentItem() |
|
if index-1 >= 0 { |
|
p.fields.SetCurrentItem(index - 1) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) NextField() { |
|
index := p.fields.GetCurrentItem() |
|
if index+1 < p.fields.GetItemCount() { |
|
p.fields.SetCurrentItem(index + 1) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) AddField() { |
|
if p.fields.GetItemCount() > 3 { |
|
p.tutView.ShowError("You can have a maximum of four fields.") |
|
return |
|
} |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init("name", 255, true, func(input string) { |
|
p.addFieldOne(input, nil) |
|
}) |
|
} else { |
|
name, err := OpenEditorLengthLimit(p.tutView, "name", 255) |
|
p.addFieldOne(name, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) addFieldOne(name string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't add name. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
if len(name) == 0 { |
|
p.tutView.ShowError("Name can't be empty.") |
|
return |
|
} |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init("value", 255, false, func(input string) { |
|
p.addFieldTwo(name, input, nil) |
|
}) |
|
} else { |
|
value, err := OpenEditorLengthLimit(p.tutView, "value", 255) |
|
p.addFieldTwo(name, value, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) addFieldTwo(name string, value string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't add value. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
if len(value) == 0 { |
|
p.tutView.ShowError("Value can't be empty.") |
|
return |
|
} |
|
field := mastodon.Field{ |
|
Name: name, |
|
Value: value, |
|
} |
|
p.preferences.fields = append(p.preferences.fields, field) |
|
p.update() |
|
p.fields.SetCurrentItem(p.fields.GetItemCount() - 1) |
|
} |
|
|
|
func (p *PreferenceView) EditField() { |
|
if p.fields.GetItemCount() == 0 { |
|
return |
|
} |
|
index := p.fields.GetCurrentItem() |
|
if index < 0 || index >= len(p.preferences.fields) { |
|
return |
|
} |
|
curr := p.preferences.fields[index] |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init(curr.Name, 255, true, func(input string) { |
|
p.editFieldOne(index, input, curr.Value, nil) |
|
}) |
|
} else { |
|
name, err := OpenEditorLengthLimit(p.tutView, curr.Name, 255) |
|
p.editFieldOne(index, name, curr.Value, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) editFieldOne(index int, name string, value string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't edit name. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
if len(name) == 0 { |
|
p.tutView.ShowError("Name can't be empty.") |
|
return |
|
} |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init(value, 255, false, func(input string) { |
|
p.editFieldTwo(index, name, input, nil) |
|
}) |
|
} else { |
|
value, err := OpenEditorLengthLimit(p.tutView, value, 255) |
|
p.editFieldTwo(index, name, value, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) editFieldTwo(index int, name string, value string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't edit value. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
if len(value) == 0 { |
|
p.tutView.ShowError("Value can't be empty.") |
|
return |
|
} |
|
field := mastodon.Field{ |
|
Name: name, |
|
Value: value, |
|
} |
|
p.preferences.fields[index] = field |
|
p.update() |
|
} |
|
|
|
func (p *PreferenceView) DeleteField() { |
|
if p.fields.GetItemCount() == 0 { |
|
return |
|
} |
|
index := p.fields.GetCurrentItem() |
|
if index < 0 || index >= len(p.preferences.fields) { |
|
return |
|
} |
|
p.fields.RemoveItem(index) |
|
p.preferences.fields = append(p.preferences.fields[:index], p.preferences.fields[index+1:]...) |
|
p.update() |
|
} |
|
|
|
func (p *PreferenceView) EditBio() { |
|
bio := p.preferences.bio |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init(bio, 500, true, func(input string) { |
|
p.editBio(input, nil) |
|
}) |
|
} else { |
|
text, err := OpenEditorLengthLimit(p.tutView, bio, 500) |
|
p.editBio(text, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) editBio(text string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't edit bio. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
p.preferences.bio = text |
|
p.update() |
|
} |
|
|
|
func (p *PreferenceView) EditDisplayname() { |
|
dn := p.preferences.displayname |
|
if p.tutView.tut.Config.General.UseInternalEditor { |
|
p.tutView.EditorView.Init(dn, 30, true, func(input string) { |
|
p.editDisplayname(input, nil) |
|
}) |
|
} else { |
|
text, err := OpenEditorLengthLimit(p.tutView, dn, 30) |
|
p.editDisplayname(text, err) |
|
} |
|
} |
|
|
|
func (p *PreferenceView) editDisplayname(text string, err error) { |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't edit display name. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
p.preferences.displayname = text |
|
p.update() |
|
} |
|
|
|
func (p *PreferenceView) visibilityInput(event *tcell.EventKey) *tcell.EventKey { |
|
if p.tutView.tut.Config.Input.GlobalDown.Match(event.Key(), event.Rune()) { |
|
return tcell.NewEventKey(tcell.KeyDown, 0, tcell.ModNone) |
|
} |
|
if p.tutView.tut.Config.Input.GlobalUp.Match(event.Key(), event.Rune()) { |
|
return tcell.NewEventKey(tcell.KeyUp, 0, tcell.ModNone) |
|
} |
|
if p.tutView.tut.Config.Input.GlobalExit.Match(event.Key(), event.Rune()) || |
|
p.tutView.tut.Config.Input.GlobalBack.Match(event.Key(), event.Rune()) { |
|
p.exitVisibility() |
|
return nil |
|
} |
|
return event |
|
} |
|
|
|
func (p *PreferenceView) exitVisibility() { |
|
p.tutView.tut.App.SetInputCapture(p.tutView.Input) |
|
p.tutView.tut.App.SetFocus(p.tutView.View) |
|
} |
|
|
|
func (p *PreferenceView) visibilitySelected(s string, index int) { |
|
_, p.preferences.visibility = p.visibility.GetCurrentOption() |
|
p.exitVisibility() |
|
} |
|
|
|
func (p *PreferenceView) FocusVisibility() { |
|
p.tutView.tut.App.SetInputCapture(p.visibilityInput) |
|
p.tutView.tut.App.SetFocus(p.visibility) |
|
ev := tcell.NewEventKey(tcell.KeyDown, 0, tcell.ModNone) |
|
p.tutView.tut.App.QueueEvent(ev) |
|
} |
|
|
|
func (p *PreferenceView) Save() { |
|
og := &preferences{} |
|
me := p.tutView.tut.Client.Me |
|
og.displayname = me.DisplayName |
|
if me.Source != nil { |
|
if me.Source.Note != nil { |
|
og.bio = *me.Source.Note |
|
} |
|
if me.Source.Fields != nil { |
|
for _, f := range *me.Source.Fields { |
|
og.fields = append(og.fields, mastodon.Field{ |
|
Name: f.Name, |
|
Value: f.Value, |
|
}) |
|
} |
|
} |
|
if me.Source.Privacy != nil { |
|
og.visibility = *me.Source.Privacy |
|
} |
|
} |
|
|
|
profile := mastodon.Profile{ |
|
Source: &mastodon.AccountSource{}, |
|
} |
|
if og.displayname != p.preferences.displayname { |
|
profile.DisplayName = &p.preferences.displayname |
|
} |
|
if og.bio != p.preferences.bio { |
|
profile.Note = &p.preferences.bio |
|
} |
|
if og.visibility != p.preferences.visibility { |
|
profile.Source.Privacy = &p.preferences.visibility |
|
} |
|
profile.Fields = &p.preferences.fields |
|
|
|
err := p.tutView.tut.Client.SavePreferences(&profile) |
|
if err != nil { |
|
p.tutView.ShowError( |
|
fmt.Sprintf("Couldn't update preferences. Error: %v\n", err), |
|
) |
|
return |
|
} |
|
p.tutView.SetPage(MainFocus) |
|
}
|
|
|