Stream all timelines (close #45)
This commit is contained in:
parent
08084ecdae
commit
8ef015be91
|
@ -28,8 +28,13 @@
|
|||
</key>
|
||||
<key name="live-updates" type="b">
|
||||
<default>true</default>
|
||||
<summary>Update timelines in real-time</summary>
|
||||
<description></description>
|
||||
<summary>Real-time timelines</summary>
|
||||
<description>Update timelines in real-time</description>
|
||||
</key>
|
||||
<key name="live-updates-public" type="b">
|
||||
<default>false</default>
|
||||
<summary>Real-time public timelines</summary>
|
||||
<description>Update local and federated timelines in real-time. May clog up memory on busy instances.</description>
|
||||
</key>
|
||||
<key name="dark-theme" type="b">
|
||||
<default>false</default>
|
||||
|
@ -39,7 +44,7 @@
|
|||
<key name="char-limit" type="i">
|
||||
<default>500</default>
|
||||
<summary>Default character limit</summary>
|
||||
<description>Change this if your instance supports more than 500 characters in post</description>
|
||||
<description>Change this if your instance supports more than 500 characters in posts</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
|
|
@ -51,6 +51,7 @@ executable(
|
|||
'src/Dialogs/SettingsDialog.vala',
|
||||
'src/Views/AbstractView.vala',
|
||||
'src/Views/TimelineView.vala',
|
||||
'src/Views/HomeView.vala',
|
||||
'src/Views/LocalView.vala',
|
||||
'src/Views/FederatedView.vala',
|
||||
'src/Views/NotificationsView.vala',
|
||||
|
|
|
@ -7,27 +7,42 @@ public class Tootle.SettingsDialog : Gtk.Dialog {
|
|||
|
||||
private SettingsSwitch switch_notifications;
|
||||
private SettingsSwitch switch_watcher;
|
||||
private SettingsSwitch switch_stream;
|
||||
private SettingsSwitch switch_stream_public;
|
||||
private Gtk.Grid grid;
|
||||
|
||||
public SettingsDialog () {
|
||||
Object (
|
||||
border_width: 6,
|
||||
deletable: false,
|
||||
resizable: false,
|
||||
title: _("Settings"),
|
||||
transient_for: Tootle.window
|
||||
);
|
||||
border_width = 6;
|
||||
deletable = false;
|
||||
resizable = false;
|
||||
title = _("Settings");
|
||||
transient_for = Tootle.window;
|
||||
|
||||
int i = 0;
|
||||
grid = new Gtk.Grid ();
|
||||
|
||||
switch_watcher = new SettingsSwitch ("always-online");
|
||||
switch_notifications = new SettingsSwitch ("notifications");
|
||||
switch_notifications.state_set.connect (state => {
|
||||
switch_watcher.sensitive = state;
|
||||
return false;
|
||||
});
|
||||
switch_stream = new SettingsSwitch ("live-updates");
|
||||
switch_stream_public = new SettingsSwitch ("live-updates-public");
|
||||
switch_stream.state_set.connect (state => {
|
||||
switch_stream_public.sensitive = state;
|
||||
return false;
|
||||
});
|
||||
|
||||
grid.attach (new Granite.HeaderLabel (_("Appearance")), 0, i++, 2, 1);
|
||||
grid.attach (new SettingsLabel (_("Dark theme:")), 0, i);
|
||||
grid.attach (new SettingsSwitch ("dark-theme"), 1, i++);
|
||||
|
||||
grid.attach (new Granite.HeaderLabel (_("Timelines")), 0, i++, 2, 1);
|
||||
grid.attach (new SettingsLabel (_("Real-time updates:")), 0, i);
|
||||
grid.attach (new SettingsSwitch ("live-updates"), 1, i++);
|
||||
grid.attach (switch_stream, 1, i++);
|
||||
grid.attach (new SettingsLabel (_("Update public timelines:")), 0, i);
|
||||
grid.attach (switch_stream_public, 1, i++);
|
||||
|
||||
// grid.attach (new Granite.HeaderLabel (_("Caching")), 0, i++, 2, 1);
|
||||
// grid.attach (new SettingsLabel (_("Use cache:")), 0, i);
|
||||
|
@ -37,13 +52,6 @@ public class Tootle.SettingsDialog : Gtk.Dialog {
|
|||
// settings.schema.bind ("cache-size", cache_size, "value", SettingsBindFlags.DEFAULT);
|
||||
// grid.attach (cache_size, 1, i++);
|
||||
|
||||
switch_watcher = new SettingsSwitch ("always-online");
|
||||
switch_notifications = new SettingsSwitch ("notifications");
|
||||
switch_notifications.state_set.connect (state => {
|
||||
switch_watcher.sensitive = state;
|
||||
return false;
|
||||
});
|
||||
|
||||
grid.attach (new Granite.HeaderLabel (_("Notifications")), 0, i++, 2, 1);
|
||||
grid.attach (new SettingsLabel (_("Display notifications:")), 0, i);
|
||||
grid.attach (switch_notifications, 1, i++);
|
||||
|
|
|
@ -23,16 +23,14 @@ public class Tootle.InstanceAccount : GLib.Object {
|
|||
notificator.close ();
|
||||
|
||||
notificator = new Notificator (get_stream ());
|
||||
notificator.status_added.connect (status_added);
|
||||
notificator.status_removed.connect (status_removed);
|
||||
notificator.notification.connect (notification);
|
||||
notificator.start ();
|
||||
}
|
||||
|
||||
private Soup.Message get_stream () {
|
||||
public Soup.Message get_stream () {
|
||||
var url = "%s/api/v1/streaming/?stream=user&access_token=%s".printf (instance, token);
|
||||
var msg = new Soup.Message("GET", url);
|
||||
return msg;
|
||||
return new Soup.Message ("GET", url);
|
||||
}
|
||||
|
||||
public void close_notificator () {
|
||||
|
@ -87,21 +85,8 @@ public class Tootle.InstanceAccount : GLib.Object {
|
|||
network.notification (ref obj);
|
||||
}
|
||||
|
||||
private void status_added (ref Status status) {
|
||||
if (accounts.formal.token != this.token)
|
||||
return;
|
||||
|
||||
if (settings.live_updates)
|
||||
network.status_added (ref status, "home");
|
||||
else
|
||||
app.toast (_("New toot available"));
|
||||
}
|
||||
|
||||
private void status_removed (int64 id) {
|
||||
if (accounts.formal.token != this.token)
|
||||
return;
|
||||
|
||||
if (settings.live_updates)
|
||||
if (accounts.formal.token == this.token)
|
||||
network.status_removed (id);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,23 @@ using Gtk;
|
|||
|
||||
public class Tootle.MainWindow: Gtk.Window {
|
||||
|
||||
private Gtk.Overlay overlay;
|
||||
private Overlay overlay;
|
||||
private Granite.Widgets.Toast toast;
|
||||
private Gtk.Grid grid;
|
||||
private Grid grid;
|
||||
private Stack primary_stack;
|
||||
private Stack secondary_stack;
|
||||
|
||||
public Gtk.HeaderBar header;
|
||||
public HeaderBar header;
|
||||
private Granite.Widgets.ModeButton button_mode;
|
||||
private AccountsButton button_accounts;
|
||||
private Spinner spinner;
|
||||
private Button button_toot;
|
||||
private Button button_back;
|
||||
|
||||
public HomeView home = new HomeView ();
|
||||
public NotificationsView notifications = new NotificationsView ();
|
||||
public LocalView local = new LocalView ();
|
||||
public FederatedView federated = new FederatedView ();
|
||||
|
||||
construct {
|
||||
var provider = new Gtk.CssProvider ();
|
||||
|
@ -67,10 +72,10 @@ public class Tootle.MainWindow: Gtk.Window {
|
|||
grid = new Gtk.Grid ();
|
||||
grid.attach (primary_stack, 0, 0, 1, 1);
|
||||
|
||||
add_header_view (new TimelineView ("home"));
|
||||
add_header_view (new NotificationsView ());
|
||||
add_header_view (new LocalView ());
|
||||
add_header_view (new FederatedView ());
|
||||
add_header_view (home);
|
||||
add_header_view (notifications);
|
||||
add_header_view (local);
|
||||
add_header_view (federated);
|
||||
button_mode.set_active (0);
|
||||
|
||||
toast = new Granite.Widgets.Toast ("");
|
||||
|
|
|
@ -9,7 +9,6 @@ public class Tootle.NetManager : GLib.Object {
|
|||
public abstract signal void finished ();
|
||||
|
||||
public abstract signal void notification (ref Notification notification);
|
||||
public abstract signal void status_added (ref Status status, string timeline);
|
||||
public abstract signal void status_removed (int64 id);
|
||||
|
||||
private int requests_processing = 0;
|
||||
|
|
|
@ -67,10 +67,16 @@ public class Tootle.Notificator : GLib.Object {
|
|||
var type = root.get_string_member ("event");
|
||||
switch (type) {
|
||||
case "update":
|
||||
if (!settings.live_updates)
|
||||
return;
|
||||
|
||||
var status = Status.parse (sanitize (root));
|
||||
status_added (ref status);
|
||||
break;
|
||||
case "delete":
|
||||
if (!settings.live_updates)
|
||||
return;
|
||||
|
||||
var id = int64.parse (root.get_string_member("payload"));
|
||||
status_removed (id);
|
||||
break;
|
||||
|
|
|
@ -7,6 +7,7 @@ public class Tootle.SettingsManager : Granite.Services.Settings {
|
|||
public int cache_size { get; set; }
|
||||
public int char_limit { get; set; }
|
||||
public bool live_updates { get; set; }
|
||||
public bool live_updates_public { get; set; }
|
||||
public bool dark_theme { get; set; }
|
||||
|
||||
public SettingsManager () {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using Gtk;
|
||||
|
||||
public class Tootle.FavoritesView : TimelineView {
|
||||
|
||||
public FavoritesView () {
|
||||
|
@ -10,7 +8,7 @@ public class Tootle.FavoritesView : TimelineView {
|
|||
if (page_next != null)
|
||||
return page_next;
|
||||
|
||||
var url = "%s/api/v1/favourites/?limit=%i".printf (Tootle.accounts.formal.instance, this.limit);
|
||||
var url = "%s/api/v1/favourites/?limit=%i".printf (accounts.formal.instance, this.limit);
|
||||
return url;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using Gtk;
|
||||
|
||||
public class Tootle.FederatedView : TimelineView {
|
||||
|
||||
public FederatedView () {
|
||||
base ("public");
|
||||
notificator = new Notificator (get_stream ());
|
||||
notificator.status_added.connect ((ref status) => {
|
||||
if (settings.live_updates_public)
|
||||
on_status_added (ref status);
|
||||
});
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
|
@ -13,5 +16,10 @@ public class Tootle.FederatedView : TimelineView {
|
|||
public override string get_name () {
|
||||
return _("Federated Timeline");
|
||||
}
|
||||
|
||||
protected Soup.Message get_stream () {
|
||||
var url = "%s/api/v1/streaming/?stream=public&access_token=%s".printf (accounts.formal.instance, accounts.formal.token);
|
||||
return new Soup.Message("GET", url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class Tootle.FollowersView : TimelineView {
|
|||
if (page_next != null)
|
||||
return page_next;
|
||||
|
||||
var url = "%s/api/v1/accounts/%s/followers".printf (Tootle.accounts.formal.instance, this.timeline);
|
||||
var url = "%s/api/v1/accounts/%s/followers".printf (accounts.formal.instance, this.timeline);
|
||||
return url;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using Gtk;
|
||||
|
||||
public class Tootle.FollowingView : FollowersView {
|
||||
|
||||
public FollowingView (ref Account account) {
|
||||
|
@ -11,7 +9,7 @@ public class Tootle.FollowingView : FollowersView {
|
|||
if (page_next != null)
|
||||
return page_next;
|
||||
|
||||
var url = "%s/api/v1/accounts/%s/following".printf (Tootle.accounts.formal.instance, this.timeline);
|
||||
var url = "%s/api/v1/accounts/%s/following".printf (accounts.formal.instance, this.timeline);
|
||||
return url;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
public class Tootle.HomeView : TimelineView {
|
||||
|
||||
public HomeView () {
|
||||
base ("home");
|
||||
notificator = new Notificator (accounts.formal.get_stream ());
|
||||
notificator.status_added.connect ((ref status) => {
|
||||
if (settings.live_updates)
|
||||
on_status_added (ref status);
|
||||
});
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
return "user-home-symbolic";
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Home");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
using Gtk;
|
||||
|
||||
public class Tootle.LocalView : TimelineView {
|
||||
|
||||
public LocalView () {
|
||||
base ("public");
|
||||
notificator = new Notificator (get_stream ());
|
||||
notificator.status_added.connect ((ref status) => {
|
||||
if (settings.live_updates_public)
|
||||
on_status_added (ref status);
|
||||
});
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
|
@ -15,9 +18,14 @@ public class Tootle.LocalView : TimelineView {
|
|||
}
|
||||
|
||||
public override string get_url (){
|
||||
string url = base.get_url ();
|
||||
var url = base.get_url ();
|
||||
url += "&local=true";
|
||||
return url;
|
||||
}
|
||||
|
||||
protected Soup.Message get_stream () {
|
||||
var url = "%s/api/v1/streaming/?stream=public:local&access_token=%s".printf (accounts.formal.instance, accounts.formal.token);
|
||||
return new Soup.Message("GET", url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,20 +5,39 @@ public class Tootle.TimelineView : AbstractView {
|
|||
|
||||
protected string timeline;
|
||||
protected string pars;
|
||||
|
||||
protected int limit = 25;
|
||||
protected bool is_last_page = false;
|
||||
protected string? page_next;
|
||||
protected string? page_prev;
|
||||
|
||||
private Notificator? _notificator;
|
||||
public Notificator? notificator {
|
||||
get {
|
||||
return _notificator;
|
||||
}
|
||||
|
||||
set {
|
||||
if (_notificator != null)
|
||||
_notificator.close ();
|
||||
|
||||
_notificator = value;
|
||||
|
||||
if (_notificator != null)
|
||||
_notificator.start ();
|
||||
}
|
||||
}
|
||||
|
||||
public TimelineView (string timeline, string pars = "") {
|
||||
base ();
|
||||
this.timeline = timeline;
|
||||
this.pars = pars;
|
||||
|
||||
Tootle.accounts.switched.connect(on_account_changed);
|
||||
Tootle.app.refresh.connect(on_refresh);
|
||||
Tootle.network.status_added.connect (on_status_added);
|
||||
accounts.switched.connect (on_account_changed);
|
||||
app.refresh.connect (on_refresh);
|
||||
destroy.connect (() => {
|
||||
if (notificator != null)
|
||||
notificator.close ();
|
||||
});
|
||||
|
||||
request ();
|
||||
}
|
||||
|
@ -31,10 +50,7 @@ public class Tootle.TimelineView : AbstractView {
|
|||
return _("Home");
|
||||
}
|
||||
|
||||
private void on_status_added (ref Status status, string timeline) {
|
||||
if (timeline != this.timeline)
|
||||
return;
|
||||
|
||||
public virtual void on_status_added (ref Status status) {
|
||||
prepend (ref status);
|
||||
}
|
||||
|
||||
|
@ -138,6 +154,12 @@ public class Tootle.TimelineView : AbstractView {
|
|||
public virtual void on_account_changed (Account? account){
|
||||
if(account == null)
|
||||
return;
|
||||
|
||||
if (notificator != null) {
|
||||
notificator.close ();
|
||||
notificator.start ();
|
||||
}
|
||||
|
||||
on_refresh ();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,19 @@ public class Tootle.RichLabel : Gtk.Label {
|
|||
if ("/tags/" in url){
|
||||
var encoded = url.split("/tags/")[1];
|
||||
var hashtag = Soup.URI.decode (encoded);
|
||||
var feed = new TimelineView ("tag/" + hashtag);
|
||||
Tootle.window.open_view (feed);
|
||||
|
||||
var msg_url = "%s/api/v1/streaming/?stream=hashtag&access_token=%s&tag=%s"
|
||||
.printf (accounts.formal.instance, accounts.formal.token, encoded);
|
||||
var msg = new Soup.Message("GET", msg_url);
|
||||
|
||||
var timeline = new TimelineView ("tag/" + hashtag);
|
||||
timeline.notificator = new Notificator (msg);
|
||||
timeline.notificator.status_added.connect ((ref status) => {
|
||||
if (settings.live_updates)
|
||||
timeline.on_status_added (ref status);
|
||||
});
|
||||
window.open_view (timeline);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue