mirror of
https://gitlab.gnome.org/World/tootle
synced 2025-02-02 00:46:48 +01:00
InstanceAccount: Register places (#328)
This commit is contained in:
parent
d635226a17
commit
02f918d637
@ -36,6 +36,7 @@ sources = files(
|
||||
'src/Utils/DateTime.vala',
|
||||
'src/Services/Accounts/InstanceAccount.vala',
|
||||
'src/Services/Accounts/AccountStore.vala',
|
||||
'src/Services/Accounts/Places.vala',
|
||||
'src/Services/Accounts/SecretAccountStore.vala',
|
||||
'src/Services/Accounts/AccountHolder.vala',
|
||||
'src/Services/Accounts/Mastodon/Account.vala',
|
||||
|
@ -14,6 +14,10 @@ public class Tootle.InstanceAccount : API.Account, Streamable {
|
||||
public string? access_token { get; set; }
|
||||
public Error? error { get; set; } //TODO: use this field when server invalidates the auth token
|
||||
|
||||
public GLib.ListStore known_places = new GLib.ListStore (typeof (Place));
|
||||
|
||||
public HashMap<Type,Type> type_overrides = new HashMap<Type,Type> ();
|
||||
|
||||
public new string handle {
|
||||
owned get { return @"@$username@$domain"; }
|
||||
}
|
||||
@ -26,8 +30,6 @@ public class Tootle.InstanceAccount : API.Account, Streamable {
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Type,Type> type_overrides = new HashMap<Type,Type> ();
|
||||
|
||||
public virtual signal void activated () {}
|
||||
public virtual signal void deactivated () {}
|
||||
public virtual signal void added () {
|
||||
@ -41,8 +43,9 @@ public class Tootle.InstanceAccount : API.Account, Streamable {
|
||||
|
||||
|
||||
construct {
|
||||
construct_streamable ();
|
||||
stream_event[EVENT_NOTIFICATION].connect (on_notification_event);
|
||||
this.construct_streamable ();
|
||||
this.stream_event[EVENT_NOTIFICATION].connect (on_notification_event);
|
||||
this.register_known_places (this.known_places);
|
||||
}
|
||||
~InstanceAccount () {
|
||||
destruct_streamable ();
|
||||
@ -110,13 +113,13 @@ public class Tootle.InstanceAccount : API.Account, Streamable {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public virtual void populate_user_menu (GLib.ListStore model) {}
|
||||
|
||||
public virtual void describe_kind (string kind, out string? icon, out string? descr, API.Account account) {
|
||||
icon = null;
|
||||
descr = null;
|
||||
}
|
||||
|
||||
public virtual void register_known_places (GLib.ListStore places) {}
|
||||
|
||||
|
||||
|
||||
// Notifications
|
||||
|
@ -2,13 +2,13 @@ public class Tootle.Mastodon.Account : InstanceAccount {
|
||||
|
||||
public const string BACKEND = "Mastodon";
|
||||
|
||||
public const string KIND_MENTION = "mention";
|
||||
public const string KIND_REBLOG = "reblog";
|
||||
public const string KIND_FAVOURITE = "favourite";
|
||||
public const string KIND_FOLLOW = "follow";
|
||||
public const string KIND_POLL = "poll";
|
||||
public const string KIND_FOLLOW_REQUEST = "__follow-request";
|
||||
public const string KIND_REMOTE_REBLOG = "__remote-reblog";
|
||||
public const string KIND_MENTION = "mention";
|
||||
public const string KIND_REBLOG = "reblog";
|
||||
public const string KIND_FAVOURITE = "favourite";
|
||||
public const string KIND_FOLLOW = "follow";
|
||||
public const string KIND_POLL = "poll";
|
||||
public const string KIND_FOLLOW_REQUEST = "__follow-request";
|
||||
public const string KIND_REMOTE_REBLOG = "__remote-reblog";
|
||||
|
||||
class Test : AccountStore.BackendTest {
|
||||
public override string? get_backend (Json.Object obj) {
|
||||
@ -25,19 +25,65 @@ public class Tootle.Mastodon.Account : InstanceAccount {
|
||||
});
|
||||
}
|
||||
|
||||
public static Place PLACE_NOTIFICATIONS = new Place () {
|
||||
title = _("Notifications"),
|
||||
icon = "bell-symbolic",
|
||||
open_func = win => {
|
||||
win.open_view (new Views.Notifications ());
|
||||
}
|
||||
};
|
||||
|
||||
public static Place PLACE_MESSAGES = new Place () {
|
||||
title = _("Direct Messages"),
|
||||
icon = "mail-unread-symbolic",
|
||||
open_func = (win) => {
|
||||
win.open_view (new Views.Conversations ());
|
||||
}
|
||||
};
|
||||
|
||||
public Views.Sidebar.Item notifications_item;
|
||||
public static Place PLACE_BOOKMARKS = new Place () {
|
||||
title = _("Bookmarks"),
|
||||
icon = "user-bookmarks-symbolic",
|
||||
open_func = (win) => {
|
||||
win.open_view (new Views.Bookmarks ());
|
||||
}
|
||||
};
|
||||
|
||||
construct {
|
||||
notifications_item = new Views.Sidebar.Item () {
|
||||
label = "Notifications",
|
||||
icon = "bell-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Notifications ());
|
||||
}
|
||||
};
|
||||
bind_property ("unread_count", notifications_item, "badge", BindingFlags.SYNC_CREATE);
|
||||
public static Place PLACE_FAVORITES = new Place () {
|
||||
title = _("Favorites"),
|
||||
icon = "non-starred-symbolic",
|
||||
open_func = (win) => {
|
||||
win.open_view (new Views.Favorites ());
|
||||
}
|
||||
};
|
||||
|
||||
public static Place PLACE_LISTS = new Place () {
|
||||
title = _("Lists"),
|
||||
icon = "view-list-symbolic",
|
||||
open_func = (win) => {
|
||||
win.open_view (new Views.Lists ());
|
||||
}
|
||||
};
|
||||
|
||||
public static Place PLACE_SEARCH = new Place () {
|
||||
title = _("Search"),
|
||||
icon = "system-search-symbolic",
|
||||
open_func = (win) => {
|
||||
win.open_view (new Views.Search ());
|
||||
}
|
||||
};
|
||||
|
||||
public override void register_known_places (GLib.ListStore places) {
|
||||
places.append (PLACE_NOTIFICATIONS);
|
||||
places.append (PLACE_MESSAGES);
|
||||
places.append (PLACE_BOOKMARKS);
|
||||
places.append (PLACE_FAVORITES);
|
||||
places.append (PLACE_LISTS);
|
||||
places.append (PLACE_SEARCH);
|
||||
}
|
||||
|
||||
construct {
|
||||
// bind_property ("unread_count", notifications_item, "badge", BindingFlags.SYNC_CREATE);
|
||||
|
||||
// Populate possible visibility variants
|
||||
set_visibility (new Visibility () {
|
||||
@ -64,86 +110,43 @@ public class Tootle.Mastodon.Account : InstanceAccount {
|
||||
icon_name = "mail-unread-symbolic",
|
||||
description = _("Post to mentioned users only")
|
||||
});
|
||||
}
|
||||
|
||||
public override void populate_user_menu (GLib.ListStore model) {
|
||||
// model.append (new Views.Sidebar.Item () {
|
||||
// label = "Timelines",
|
||||
// icon = "user-home-symbolic"
|
||||
// });
|
||||
model.append (notifications_item);
|
||||
model.append (new Views.Sidebar.Item () {
|
||||
label = "Direct Messages",
|
||||
icon = "mail-unread-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Conversations ());
|
||||
}
|
||||
});
|
||||
model.append (new Views.Sidebar.Item () {
|
||||
label = "Bookmarks",
|
||||
icon = "user-bookmarks-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Bookmarks ());
|
||||
}
|
||||
});
|
||||
model.append (new Views.Sidebar.Item () {
|
||||
label = "Favorites",
|
||||
icon = "non-starred-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Favorites ());
|
||||
}
|
||||
});
|
||||
model.append (new Views.Sidebar.Item () {
|
||||
label = "Lists",
|
||||
icon = "view-list-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Lists ());
|
||||
}
|
||||
});
|
||||
model.append (new Views.Sidebar.Item () {
|
||||
label = "Search",
|
||||
icon = "system-search-symbolic",
|
||||
on_activated = () => {
|
||||
app.main_window.open_view (new Views.Search ());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void describe_kind (string kind, out string? icon, out string? descr, API.Account account) {
|
||||
switch (kind) {
|
||||
case KIND_MENTION:
|
||||
icon = "user-available-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> mentioned you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_REBLOG:
|
||||
icon = "media-playlist-repeat-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted your status</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_REMOTE_REBLOG:
|
||||
icon = "media-playlist-repeat-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FAVOURITE:
|
||||
icon = "starred-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> favorited your status</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FOLLOW:
|
||||
icon = "contact-new-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> now follows you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FOLLOW_REQUEST:
|
||||
icon = "contact-new-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> wants to follow you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_POLL:
|
||||
icon = "emblem-default-symbolic";
|
||||
descr = _("Poll results");
|
||||
break;
|
||||
default:
|
||||
icon = null;
|
||||
descr = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public override void describe_kind (string kind, out string? icon, out string? descr, API.Account account) {
|
||||
switch (kind) {
|
||||
case KIND_MENTION:
|
||||
icon = "user-available-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> mentioned you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_REBLOG:
|
||||
icon = "media-playlist-repeat-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted your status</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_REMOTE_REBLOG:
|
||||
icon = "media-playlist-repeat-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FAVOURITE:
|
||||
icon = "starred-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> favorited your status</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FOLLOW:
|
||||
icon = "contact-new-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> now follows you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_FOLLOW_REQUEST:
|
||||
icon = "contact-new-symbolic";
|
||||
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> wants to follow you</span>").printf (account.url, account.display_name);
|
||||
break;
|
||||
case KIND_POLL:
|
||||
icon = "emblem-default-symbolic";
|
||||
descr = _("Poll results");
|
||||
break;
|
||||
default:
|
||||
icon = null;
|
||||
descr = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
13
src/Services/Accounts/Places.vala
Normal file
13
src/Services/Accounts/Places.vala
Normal file
@ -0,0 +1,13 @@
|
||||
public class Tootle.Place : Object {
|
||||
|
||||
public string title { get; set; }
|
||||
public string icon { get; set; }
|
||||
public int badge { get; set; default = 0; }
|
||||
public bool separated { get; set; default = false; }
|
||||
|
||||
[CCode (has_target = false)]
|
||||
public delegate void OpenFunc (Dialogs.MainWindow window);
|
||||
|
||||
public OpenFunc open_func { get; set; }
|
||||
|
||||
}
|
@ -4,6 +4,7 @@ public class Tootle.Views.Main : Views.TabbedBase {
|
||||
|
||||
public Main () {
|
||||
add_tab (new Views.Home ());
|
||||
add_tab (new Views.Notifications ());
|
||||
add_tab (new Views.Local ());
|
||||
add_tab (new Views.Federated ());
|
||||
}
|
||||
|
@ -13,31 +13,46 @@ public class Tootle.Views.Sidebar : Box, AccountHolder {
|
||||
[GtkChild] unowned Label subtitle;
|
||||
|
||||
protected InstanceAccount? account { get; set; default = null; }
|
||||
GLib.ListStore item_model = new GLib.ListStore (typeof (Object));
|
||||
|
||||
Item item_preferences = new Item () {
|
||||
label = _("Preferences"),
|
||||
protected GLib.ListStore app_items;
|
||||
protected SliceListModel account_items;
|
||||
protected FlattenListModel item_model;
|
||||
|
||||
public static Place PREFERENCES = new Place () {
|
||||
title = _("Preferences"),
|
||||
icon = "emblem-system-symbolic",
|
||||
selectable = false,
|
||||
//selectable = false,
|
||||
separated = true,
|
||||
on_activated = () => {
|
||||
open_func = () => {
|
||||
Dialogs.Preferences.open ();
|
||||
}
|
||||
};
|
||||
Item item_about = new Item () {
|
||||
label = _("About"),
|
||||
public static Place ABOUT = new Place () {
|
||||
title = _("About"),
|
||||
icon = "help-about-symbolic",
|
||||
selectable = false,
|
||||
on_activated = () => {
|
||||
//selectable = false,
|
||||
open_func = () => {
|
||||
app.lookup_action ("about").activate (null);
|
||||
}
|
||||
};
|
||||
|
||||
construct {
|
||||
construct_account_holder ();
|
||||
app_items = new GLib.ListStore (typeof (Place));
|
||||
app_items.append (PREFERENCES);
|
||||
app_items.append (ABOUT);
|
||||
|
||||
account_items = new SliceListModel (null, 0, 15);
|
||||
|
||||
var models = new GLib.ListStore (typeof (Object));
|
||||
models.append (account_items);
|
||||
models.append (app_items);
|
||||
item_model = new FlattenListModel (models);
|
||||
|
||||
items.bind_model (item_model, on_item_create);
|
||||
items.set_header_func (on_item_header_update);
|
||||
saved_accounts.set_header_func (on_account_header_update);
|
||||
|
||||
construct_account_holder ();
|
||||
}
|
||||
|
||||
protected virtual void on_accounts_changed (Gee.ArrayList<InstanceAccount> accounts) {
|
||||
@ -56,17 +71,13 @@ public class Tootle.Views.Sidebar : Box, AccountHolder {
|
||||
|
||||
protected virtual void on_account_changed (InstanceAccount? account) {
|
||||
this.account = account;
|
||||
|
||||
warning (account.handle);
|
||||
accounts_button.active = false;
|
||||
item_model.remove_all ();
|
||||
|
||||
if (account != null) {
|
||||
title.label = account.display_name;
|
||||
subtitle.label = account.handle;
|
||||
avatar.account = account;
|
||||
|
||||
account.populate_user_menu (item_model);
|
||||
account_items.model = account.known_places;
|
||||
}
|
||||
else {
|
||||
saved_accounts.unselect_all ();
|
||||
@ -74,18 +85,8 @@ public class Tootle.Views.Sidebar : Box, AccountHolder {
|
||||
title.label = _("Anonymous");
|
||||
subtitle.label = _("No account selected");
|
||||
avatar.account = null;
|
||||
account_items.model = null;
|
||||
}
|
||||
|
||||
item_model.append (item_preferences);
|
||||
item_model.append (item_about);
|
||||
|
||||
// item_model.append (new Item () {
|
||||
// label = "(Debug) Empty View",
|
||||
// separated = true,
|
||||
// on_activated = () => {
|
||||
// app.main_window.open_view (new Views.ContentBase ());
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
[GtkCallback] void on_mode_changed () {
|
||||
@ -100,44 +101,35 @@ public class Tootle.Views.Sidebar : Box, AccountHolder {
|
||||
|
||||
// Item
|
||||
|
||||
public class Item : Object {
|
||||
public VoidFunc? on_activated;
|
||||
public string label { get; set; default = ""; }
|
||||
public string icon { get; set; default = ""; }
|
||||
public int badge { get; set; default = 0; }
|
||||
public bool selectable { get; set; default = false; }
|
||||
public bool separated { get; set; default = false; }
|
||||
}
|
||||
|
||||
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/views/sidebar/item.ui")]
|
||||
protected class ItemRow : ListBoxRow {
|
||||
public Item item;
|
||||
public Place place;
|
||||
|
||||
[GtkChild] unowned Image icon;
|
||||
[GtkChild] unowned Label label;
|
||||
[GtkChild] unowned Label badge;
|
||||
|
||||
public ItemRow (Item _item) {
|
||||
item = _item;
|
||||
item.bind_property ("label", label, "label", BindingFlags.SYNC_CREATE);
|
||||
item.bind_property ("icon", icon, "icon-name", BindingFlags.SYNC_CREATE);
|
||||
item.bind_property ("badge", badge, "label", BindingFlags.SYNC_CREATE);
|
||||
item.bind_property ("badge", badge, "visible", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
|
||||
public ItemRow (Place place) {
|
||||
this.place = place;
|
||||
place.bind_property ("title", label, "label", BindingFlags.SYNC_CREATE);
|
||||
place.bind_property ("icon", icon, "icon-name", BindingFlags.SYNC_CREATE);
|
||||
place.bind_property ("badge", badge, "label", BindingFlags.SYNC_CREATE);
|
||||
place.bind_property ("badge", badge, "visible", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
|
||||
target.set_boolean (src.get_int () > 0);
|
||||
return true;
|
||||
});
|
||||
bind_property ("selectable", item, "selectable", BindingFlags.SYNC_CREATE);
|
||||
// bind_property ("selectable", item, "selectable", BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
Widget on_item_create (Object obj) {
|
||||
return new ItemRow (obj as Item);
|
||||
return new ItemRow (obj as Place);
|
||||
}
|
||||
|
||||
[GtkCallback] void on_item_activated (ListBoxRow _row) {
|
||||
var row = _row as ItemRow;
|
||||
if (row.item.on_activated != null)
|
||||
row.item.on_activated ();
|
||||
if (row.place.open_func != null)
|
||||
row.place.open_func (app.main_window);
|
||||
|
||||
var flap = app.main_window.flap;
|
||||
if (flap.folded)
|
||||
@ -150,7 +142,7 @@ public class Tootle.Views.Sidebar : Box, AccountHolder {
|
||||
|
||||
row.set_header (null);
|
||||
|
||||
if (row.item.separated && before != null && !before.item.separated) {
|
||||
if (row.place.separated && before != null && !before.place.separated) {
|
||||
row.set_header (new Separator (Orientation.HORIZONTAL));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user