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.
 
 

437 lines
13 KiB

package ui
import (
. "gotoot/toot"
"log"
"time"
"strconv"
"github.com/gotk3/gotk3/gtk"
)
var NewTootWin *NewTootWindow
type NewTootWindow struct {
Window *gtk.Window
App *gtk.Application
TootCW *gtk.Entry `reset:""`
TootText *gtk.TextView `reset:""`
TootLength *gtk.Label `reset:0`
TootSendBtn *gtk.Button
MediaBtn *gtk.Button `reset:false`
PollBtn *gtk.Button `reset:false`
AutoSplit *gtk.CheckButton `reset:false`
Vis struct {
Image *gtk.Image
Menu *gtk.PopoverMenu
Public *gtk.Button
Unlisted *gtk.Button
Direct *gtk.Button
FollowersOnly *gtk.Button
State string
}
Media struct {
Box *gtk.Box
FlowBox *gtk.FlowBox
Flow1 *gtk.FlowBoxChild
Flow2 *gtk.FlowBoxChild
Flow3 *gtk.FlowBoxChild
Flow4 *gtk.FlowBoxChild
Img1 *gtk.Image `reset:""`
Img2 *gtk.Image `reset:""`
Img3 *gtk.Image `reset:""`
Img4 *gtk.Image `reset:""`
Attachment1 string
Attachment2 string
Attachment3 string
Attachment4 string
}
Poll struct {
Box *gtk.Box
Entry1 *gtk.Entry `reset:""`
Entry2 *gtk.Entry `reset:""`
Entry3 *gtk.Entry `reset:""`
Entry4 *gtk.Entry `reset:""`
HasTotal *gtk.CheckButton `reset:false`
Multiple *gtk.CheckButton `reset:false`
DurationNumber *gtk.SpinButton `reset:"1"`
DurationUnit *gtk.ComboBoxText `reset:"days"`
}
Plan struct {
Label *gtk.Label
Popover *gtk.Popover
NowBtn *gtk.Button
HourBtn *gtk.Button
TomorrowBtn *gtk.Button
ApplyBtn *gtk.Button
CancelBtn *gtk.Button
Hour *gtk.SpinButton
Minute *gtk.SpinButton
Calendar *gtk.Calendar
SelectedDate time.Time
}
IsPlanned bool `reset:false`
MediaVisible bool `reset:false`
PollVisible bool `reset:false`
ReplyTo *TootStatus
}
func (nt *NewTootWindow) UpdateBoxes () {
if nt.MediaVisible {
nt.Media.Box.Show()
} else {
nt.Media.Box.Hide()
}
if nt.PollVisible {
nt.Poll.Box.Show()
} else {
nt.Poll.Box.Hide()
}
}
func UpdateVis ( newVal string ) {
NewTootWin.Vis.State = newVal
NewTootWin.Vis.Menu.Hide()
switch NewTootWin.Vis.State {
case "public":
NewTootWin.Vis.Image.SetFromIconName ( "network-workgroup", gtk.ICON_SIZE_BUTTON)
NewTootWin.Vis.Image.SetTooltipText ( "Public" )
case "unlisted":
NewTootWin.Vis.Image.SetFromIconName ( "go-home", gtk.ICON_SIZE_BUTTON)
NewTootWin.Vis.Image.SetTooltipText ( "Unlisted" )
case "private":
NewTootWin.Vis.Image.SetFromIconName ( "system-lock-screen", gtk.ICON_SIZE_BUTTON)
NewTootWin.Vis.Image.SetTooltipText ( "Followers-Only" )
case "direct":
NewTootWin.Vis.Image.SetFromIconName ( "mail-send", gtk.ICON_SIZE_BUTTON)
NewTootWin.Vis.Image.SetTooltipText ( "Direct (Only Mentioned)" )
}
}
func TryAddAttachment ( num int ) {
fchoose, err := gtk.FileChooserNativeDialogNew (
"Choose Attachment",
NewTootWin.Window,
gtk.FILE_CHOOSER_ACTION_OPEN,
"Open",
"Cancel",
);
if err != nil {
log.Println ( "Cannot create file chooser: " + err.Error() );
return
}
filter, _ := gtk.FileFilterNew()
filter.AddPixbufFormats()
fchoose.AddFilter ( filter )
fchoose.SetSelectMultiple ( false );
ret := fchoose.Run ();
if ret == int(gtk.RESPONSE_ACCEPT) {
path := fchoose.GetFilename()
w,_ := NewTootWin.Media.Flow1.GetSizeRequest()
px, err := SimpleScale ( path, w, -1 )
if err != nil {
return
}
switch num {
case 1:
NewTootWin.Media.Attachment1 = path
NewTootWin.Media.Img1.SetFromPixbuf ( px )
NewTootWin.Media.Flow2.ShowAll()
case 2:
NewTootWin.Media.Attachment2 = path
NewTootWin.Media.Img2.SetFromPixbuf ( px )
NewTootWin.Media.Flow3.ShowAll()
case 3:
NewTootWin.Media.Attachment3 = path
NewTootWin.Media.Img3.SetFromPixbuf ( px )
NewTootWin.Media.Flow4.ShowAll()
case 4:
NewTootWin.Media.Attachment4 = path
NewTootWin.Media.Img4.SetFromPixbuf ( px )
}
}
}
func MentionUser ( acc TootAccount, visibility string ) {
if NewTootWin.ReplyTo != nil {
// TODO Notify the user; will just assume, that she gave her okay for now
}
Reset ( NewTootWin )
if visibility != "" {
UpdateVis ( visibility )
}
b, _ := NewTootWin.TootText.GetBuffer()
b.InsertAtCursor ( "@" + acc.Acct + " " )
NewTootWin.Window.Show()
}
func ReplyTootWindow ( status TootStatus ) {
if NewTootWin.ReplyTo != nil {
// TODO Notify the user; will just assume, that she gave her okay for now
}
Reset ( NewTootWin )
NewTootWin.ReplyTo = &status
if status.SpoilerText != "" {
NewTootWin.TootCW.SetText ( "Re: " + status.SpoilerText )
}
b, _ := NewTootWin.TootText.GetBuffer()
b.InsertAtCursor ( "@" + status.Account.Acct + " " )
UpdateVis ( status.Visibility )
NewTootWin.Window.Show()
}
func (nt *NewTootWindow) ResetCalendar () {
nt.Plan.SelectedDate = time.Time{}
nt.IsPlanned = false
nt.Plan.Label.SetText ( "Plan" )
t := time.Now()
nt.SetPlanDate ( t )
}
func (nt *NewTootWindow) SetPlanDate ( t time.Time ) {
nt.Plan.Hour.SetValue ( float64(t.Hour()) )
nt.Plan.Minute.SetValue ( float64(t.Minute()+1) )
nt.Plan.Calendar.SelectMonth ( uint ( t.Month()-1 ), uint ( t.Year() ) )
nt.Plan.Calendar.SelectDay ( uint ( t.Day() ) )
}
func NewTootForm ( GtkBuilder *gtk.Builder ) (*NewTootWindow) {
if NewTootWin != nil {
return NewTootWin
}
NewTootWin = &NewTootWindow{ MediaVisible: false, PollVisible: false }
err := DiscoverWidgets ( GtkBuilder, NewTootWin, "New" )
if err != nil {
log.Println ("Discover Widgets threw an error: ", err.Error())
}
NewTootWin.ResetCalendar ()
NewTootWin.Plan.ApplyBtn.Connect ( "clicked", func () {
t := time.Now()
t = t.Add ( -24*time.Hour )
hrs := int ( NewTootWin.Plan.Hour.GetValue() )
min := int ( NewTootWin.Plan.Minute.GetValue() )
y,m,d := NewTootWin.Plan.Calendar.GetDate()
year := int ( y )
month := int ( m ) + 1
day := int ( d )
if month > 12 || day > 31 {
return
}
selected := time.Date ( year, time.Month(month), day, hrs, min, 0,0, time.Local )
if selected.After (time.Now()) {
NewTootWin.IsPlanned = true
NewTootWin.Plan.SelectedDate = selected
NewTootWin.Plan.Label.SetText ( NewTootWin.Plan.SelectedDate.Format ( "2.1.2006 15:04" ))
} else {
NewTootWin.IsPlanned = false
NewTootWin.Plan.SelectedDate = time.Time{}
NewTootWin.Plan.Label.SetText ( "Plan" )
}
NewTootWin.Plan.Popover.Hide()
})
NewTootWin.Plan.TomorrowBtn.Connect ( "clicked", func () {
NewTootWin.IsPlanned = true
t := time.Now()
NewTootWin.Plan.SelectedDate = t.Add ( time.Hour*24 )
NewTootWin.Plan.Label.SetText ( NewTootWin.Plan.SelectedDate.Format ( "2.1.2006 15:04" ))
NewTootWin.SetPlanDate ( NewTootWin.Plan.SelectedDate )
NewTootWin.Plan.Popover.Hide()
})
NewTootWin.Plan.HourBtn.Connect ( "clicked", func () {
NewTootWin.IsPlanned = true
t := time.Now()
NewTootWin.Plan.SelectedDate = t.Add ( time.Hour )
NewTootWin.Plan.Label.SetText ( NewTootWin.Plan.SelectedDate.Format ( "2.1.2006 15:04" ))
NewTootWin.SetPlanDate ( NewTootWin.Plan.SelectedDate )
NewTootWin.Plan.Popover.Hide()
})
NewTootWin.Plan.CancelBtn.Connect ( "clicked", func () {
NewTootWin.ResetCalendar ()
NewTootWin.Plan.Popover.Hide()
})
NewTootWin.Plan.NowBtn.Connect ( "clicked", func () {
NewTootWin.ResetCalendar ()
NewTootWin.Plan.Popover.Hide()
})
NewTootWin.Window.Connect ("realize", func () {
NewTootWin.UpdateBoxes()
})
NewTootWin.MediaBtn.Connect ("clicked", func () {
NewTootWin.MediaVisible = !NewTootWin.MediaVisible
NewTootWin.UpdateBoxes()
})
NewTootWin.PollBtn.Connect ("clicked", func () {
NewTootWin.PollVisible = !NewTootWin.PollVisible
NewTootWin.UpdateBoxes()
})
NewTootWin.Media.Flow1.Connect ( "activate", func () {
TryAddAttachment ( 1 )
})
NewTootWin.Media.Flow2.Connect ( "activate", func () {
TryAddAttachment ( 2 )
})
NewTootWin.Media.Flow3.Connect ( "activate", func () {
TryAddAttachment ( 3 )
})
NewTootWin.Media.Flow4.Connect ( "activate", func () {
TryAddAttachment ( 4 )
})
NewTootWin.Vis.State = "public"
NewTootWin.Vis.Public.Connect ( "clicked", func () {
UpdateVis ( "public" )
})
NewTootWin.Vis.Unlisted.Connect ( "clicked", func () {
UpdateVis ( "unlisted" )
})
NewTootWin.Vis.FollowersOnly.Connect ( "clicked", func () {
UpdateVis ( "private" )
})
NewTootWin.Vis.Direct.Connect ( "clicked", func () {
UpdateVis ( "direct" )
})
NewTootWin.Window.Connect ("delete-event", func() bool {
log.Println ("NewTootWindow destroyed")
NewTootWin.Window.Hide()
return true
})
b, err := NewTootWin.TootText.GetBuffer()
if err != nil {
log.Println ("Cannot get the buffer")
} else {
b.Connect("changed", func () {
l := b.GetCharCount ()
NewTootWin.TootLength.SetText(strconv.Itoa(l) + " / 500")
})
}
NewTootWin.TootSendBtn.Connect ("clicked", func () {
var status TootStatus;
b, _ := NewTootWin.TootText.GetBuffer()
s,e := b.GetBounds();
status.Content, _ = b.GetText(s,e,false);
status.Visibility = NewTootWin.Vis.State
status.SpoilerText, _ = NewTootWin.TootCW.GetText()
if NewTootWin.ReplyTo != nil {
status.InReplyToId = NewTootWin.ReplyTo.Id
}
var scheduled *time.Time = nil
if NewTootWin.IsPlanned {
scheduled = &NewTootWin.Plan.SelectedDate
}
if NewTootWin.PollVisible == true {
txt1, _ := NewTootWin.Poll.Entry1.GetText()
txt2, _ := NewTootWin.Poll.Entry2.GetText()
txt3, _ := NewTootWin.Poll.Entry3.GetText()
txt4, _ := NewTootWin.Poll.Entry4.GetText()
var starttime time.Time
if scheduled == nil {
starttime = time.Now()
} else {
starttime = *scheduled
}
var duration time.Duration
val := NewTootWin.Poll.DurationNumber.GetValueAsInt()
unit := NewTootWin.Poll.DurationUnit.GetActiveText()
if val <= 0 {
duration = 24*time.Hour
} else {
dval := time.Duration(val)
switch unit {
case "hours":
duration = dval*time.Hour
case "days":
duration = dval*time.Hour*24
case "weeks":
duration = dval*time.Hour*24*7
case "months":
duration = dval*time.Hour*24*7*30
}
}
status.AddPoll (
[]string{ txt1, txt2, txt3, txt4 },
starttime.Add ( duration ),
NewTootWin.Poll.Multiple.GetActive(),
!NewTootWin.Poll.HasTotal.GetActive(),
)
}
if NewTootWin.MediaVisible == true {
err := status.AddAttachments (
[]Media{
Media{NewTootWin.Media.Attachment1,"",0,0},
Media{NewTootWin.Media.Attachment2,"",0,0},
Media{NewTootWin.Media.Attachment3,"",0,0},
Media{NewTootWin.Media.Attachment4,"",0,0},
},
)
if err != nil {
// Error Message
log.Println("Cannot add Attachments! ", err )
return
}
}
st, err := status.PostStatus ( scheduled );
if err != nil {
log.Println("Error: ", err)
} else {
log.Println("Worked! ", st)
//InputReset ( NewTootWin )
}
NewTootWin.ReplyTo = nil
NewTootWin.ResetCalendar()
NewTootWin.Window.Hide()
})
return NewTootWin
}