tootle-linux-client/src/Dialogs/PostDialog.vala

204 lines
7.3 KiB
Vala
Raw Normal View History

2018-04-14 14:09:06 +02:00
using Gtk;
2018-04-15 13:29:55 +02:00
using Tootle;
2018-04-14 14:09:06 +02:00
2018-04-19 21:03:28 +02:00
public class Tootle.PostDialog : Gtk.Dialog {
2018-04-14 14:09:06 +02:00
2018-04-19 21:03:28 +02:00
private static PostDialog dialog;
2018-04-24 16:50:38 +02:00
protected Gtk.TextView text;
2018-05-04 16:23:26 +02:00
private Gtk.ScrolledWindow scroll;
2018-04-14 14:09:06 +02:00
private Gtk.Label counter;
private ImageToggleButton spoiler;
2018-04-15 13:29:55 +02:00
private Gtk.MenuButton visibility;
2018-05-09 16:20:40 +02:00
private Gtk.Button attach;
private Gtk.Button cancel;
2018-04-15 14:28:23 +02:00
private Gtk.Button publish;
2018-05-09 16:20:40 +02:00
private AttachmentBox attachments;
2018-04-15 13:29:55 +02:00
private Gtk.Revealer spoiler_revealer;
private Gtk.Entry spoiler_text;
protected Status? in_reply_to;
protected StatusVisibility visibility_opt = StatusVisibility.PUBLIC;
2018-04-14 14:09:06 +02:00
public PostDialog (Status? status = null) {
2018-04-14 14:09:06 +02:00
Object (
border_width: 6,
2018-04-14 14:09:06 +02:00
deletable: false,
resizable: false,
title: _("Toot"),
transient_for: Tootle.window
2018-04-14 14:09:06 +02:00
);
in_reply_to = status;
if (in_reply_to != null)
visibility_opt = in_reply_to.visibility;
2018-04-15 13:29:55 +02:00
var actions = get_action_area ().get_parent () as Gtk.Box;
var content = get_content_area ();
2018-05-09 16:20:40 +02:00
get_action_area ().hexpand = false;
2018-04-14 14:09:06 +02:00
2018-04-15 13:29:55 +02:00
visibility = get_visibility_btn ();
2018-05-09 16:20:40 +02:00
visibility.tooltip_text = _("Post Visibility");
visibility.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
visibility.get_style_context ().remove_class ("image-button");
2018-05-09 16:20:40 +02:00
visibility.can_default = false;
visibility.set_focus_on_click (false);
2018-05-09 16:20:40 +02:00
attach = new Gtk.Button.from_icon_name ("mail-attachment-symbolic");
attach.tooltip_text = _("Add Media");
attach.valign = Gtk.Align.CENTER;
attach.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
attach.get_style_context ().remove_class ("image-button");
attach.can_default = false;
attach.set_focus_on_click (false);
attach.clicked.connect (() => attachments.select ());
spoiler = new ImageToggleButton ("image-red-eye-symbolic");
spoiler.tooltip_text = _("Spoiler warning");
spoiler.set_action ();
spoiler.toggled.connect (() => {
spoiler_revealer.reveal_child = spoiler.active;
validate ();
});
2018-05-09 16:20:40 +02:00
cancel = add_button(_("Cancel"), 5) as Gtk.Button;
cancel.clicked.connect(() => this.destroy ());
2018-04-15 14:28:23 +02:00
publish = add_button(_("Toot!"), 5) as Gtk.Button;
2018-04-14 14:09:06 +02:00
publish.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
2018-04-15 13:29:55 +02:00
publish.clicked.connect (() => {
2018-04-15 14:28:23 +02:00
publish_post ();
2018-04-15 13:29:55 +02:00
});
2018-04-14 14:09:06 +02:00
spoiler_text = new Gtk.Entry ();
spoiler_text.margin_start = 6;
spoiler_text.margin_end = 6;
spoiler_text.placeholder_text = _("Write your warning here");
spoiler_revealer = new Gtk.Revealer ();
spoiler_revealer.add (spoiler_text);
2018-04-15 13:29:55 +02:00
text = new Gtk.TextView ();
2018-04-14 14:09:06 +02:00
text.get_style_context ().add_class ("toot-text");
text.wrap_mode = Gtk.WrapMode.WORD;
text.accepts_tab = false;
text.buffer.changed.connect (validate);
2018-04-14 14:09:06 +02:00
2018-05-04 16:23:26 +02:00
scroll = new Gtk.ScrolledWindow (null, null);
scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
scroll.min_content_height = 120;
2018-05-04 16:23:26 +02:00
scroll.margin_start = 6;
scroll.margin_end = 6;
scroll.add (text);
scroll.show_all ();
2018-05-09 16:20:40 +02:00
attachments = new AttachmentBox (true);
2018-04-14 14:09:06 +02:00
counter = new Gtk.Label ("500");
actions.pack_start (counter, false, false, 6);
actions.pack_end (spoiler, false, false, 6);
2018-05-09 16:20:40 +02:00
actions.pack_end (visibility, false, false, 0);
actions.pack_end (attach, false, false, 6);
content.pack_start (spoiler_revealer, false, false, 6);
2018-05-09 16:20:40 +02:00
content.pack_start (scroll, false, false, 6);
content.pack_start (attachments, false, false, 6);
content.set_size_request (350, 120);
if (in_reply_to != null) {
spoiler.active = in_reply_to.sensitive;
var status_spoiler_text = in_reply_to.spoiler_text != null ? in_reply_to.spoiler_text : "";
spoiler_text.set_text (status_spoiler_text);
}
2018-05-09 16:20:40 +02:00
show_all ();
attachments.hide ();
text.grab_focus ();
2018-04-14 14:09:06 +02:00
}
2018-05-09 16:20:40 +02:00
private Gtk.MenuButton get_visibility_btn () {
2018-04-15 13:29:55 +02:00
var button = new Gtk.MenuButton ();
var menu = new Gtk.Popover (null);
var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
box.margin = 6;
menu.add (box);
button.direction = Gtk.ArrowType.DOWN;
button.image = new Gtk.Image.from_icon_name (visibility_opt.get_icon (), Gtk.IconSize.BUTTON);
2018-04-15 13:29:55 +02:00
StatusVisibility[] opts = {StatusVisibility.PUBLIC, StatusVisibility.UNLISTED, StatusVisibility.PRIVATE, StatusVisibility.DIRECT};
Gtk.RadioButton* first = null;
foreach (StatusVisibility opt in opts){
var item = new Gtk.RadioButton.with_label_from_widget (first, opt.get_desc ());
if (first == null)
2018-04-15 13:29:55 +02:00
first = item;
item.toggled.connect (() => {
visibility_opt = opt;
(button.image as Gtk.Image).icon_name = visibility_opt.get_icon ();
2018-04-15 13:29:55 +02:00
});
item.active = visibility_opt == opt;
2018-04-15 13:29:55 +02:00
box.pack_start (item, false, false, 0);
}
box.show_all ();
button.use_popover = true;
button.popover = menu;
button.valign = Gtk.Align.CENTER;
button.show ();
return button;
}
private void validate () {
2018-04-14 14:09:06 +02:00
var len = text.buffer.text.length;
2018-04-15 14:28:23 +02:00
var remain = 500 - len;
2018-04-14 14:09:06 +02:00
2018-04-15 14:28:23 +02:00
counter.label = remain.to_string ();
publish.sensitive = remain >= 0;
2018-04-14 14:09:06 +02:00
}
public static void open (string? text = null, Status? reply_to = null) {
if (dialog == null){
dialog = new PostDialog (reply_to);
dialog.destroy.connect (() => dialog = null);
if (text != null)
dialog.text.buffer.text = text;
2018-04-14 14:09:06 +02:00
}
else if (text != null)
2018-05-04 15:57:59 +02:00
dialog.text.buffer.text += " " + text;
2018-04-14 14:09:06 +02:00
}
2018-04-15 14:28:23 +02:00
public static void open_reply (Status reply_to) {
if(dialog != null)
return;
open (null, reply_to);
dialog.text.buffer.text = "@%s ".printf (reply_to.account.acct);
2018-04-24 16:50:38 +02:00
}
2018-05-09 16:20:40 +02:00
public void publish_post () {
var pars = "?status=%s&visibility=%s".printf (Soup.URI.encode (text.buffer.text, null), visibility_opt.to_string ());
2018-05-09 16:20:40 +02:00
pars += attachments.get_uri_array ();
if (in_reply_to != null)
pars += "&in_reply_to_id=%s".printf (in_reply_to.id.to_string ());
2018-05-09 16:20:40 +02:00
if (spoiler.active) {
pars += "&sensitive=true";
pars += "&spoiler_text=" + Soup.URI.encode (spoiler_text.buffer.text, null);
}
2018-05-09 16:20:40 +02:00
var url = "%s/api/v1/statuses%s".printf (Tootle.settings.instance_url, pars);
var msg = new Soup.Message("POST", url);
2018-04-27 20:50:08 +02:00
Tootle.network.queue(msg, (sess, mess) => {
2018-05-09 16:20:40 +02:00
try {
2018-04-27 20:50:08 +02:00
var root = Tootle.network.parse (mess);
2018-04-15 14:28:23 +02:00
var status = Status.parse (root);
debug ("Posted: %s", status.id.to_string ()); //TODO: Live updates
2018-04-15 14:28:23 +02:00
this.destroy ();
}
catch (GLib.Error e) {
warning ("Can't publish post.");
warning (e.message);
}
});
}
2018-04-14 14:09:06 +02:00
}