Place time+encryption+read directly right of name
This commit is contained in:
parent
8cbc4e7f89
commit
119e7cce4f
|
@ -46,15 +46,14 @@ public class PresenceManager : StreamInteractionModule, Object {
|
|||
if (stream != null) {
|
||||
Xmpp.Presence.Flag flag = stream.get_flag(Presence.Flag.IDENTITY);
|
||||
if (flag == null) return null;
|
||||
Gee.List<string> resources = flag.get_resources(jid.bare_jid.to_string());
|
||||
Gee.List<string>? resources = flag.get_resources(jid.bare_jid.to_string());
|
||||
if (resources == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<Jid> ret = new ArrayList<Jid>(Jid.equals_func);
|
||||
resources.foreach((resource) => {
|
||||
foreach (string resource in resources) {
|
||||
ret.add(new Jid(resource));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -12,6 +12,7 @@ find_packages(MAIN_PACKAGES REQUIRED
|
|||
)
|
||||
|
||||
set(RESOURCE_LIST
|
||||
icons/dino-changes-prevent-symbolic.svg
|
||||
icons/dino-double-tick-symbolic.svg
|
||||
icons/dino-status-away.svg
|
||||
icons/dino-status-chat.svg
|
||||
|
@ -32,7 +33,6 @@ set(RESOURCE_LIST
|
|||
conversation_selector/chat_row_tooltip.ui
|
||||
conversation_selector/conversation_row.ui
|
||||
conversation_summary/image_toolbar.ui
|
||||
conversation_summary/message_item.ui
|
||||
conversation_summary/view.ui
|
||||
manage_accounts/account_row.ui
|
||||
manage_accounts/add_account_dialog.ui
|
||||
|
@ -159,6 +159,7 @@ install(FILES
|
|||
data/icons/dino-status-dnd.svg
|
||||
data/icons/dino-status-online.svg
|
||||
|
||||
data/icons/dino-changes-prevent-symbolic.svg
|
||||
data/icons/dino-double-tick-symbolic.svg
|
||||
data/icons/dino-tick-symbolic.svg
|
||||
DESTINATION
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DinoUiConversationSummaryConversationItemSkeleton">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="column-spacing">7</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="expand">False</property>
|
||||
<property name="height_request">30</property>
|
||||
<property name="margin_top">2</property>
|
||||
<property name="width_request">30</property>
|
||||
<property name="yalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="time_label">
|
||||
<property name="xalign">1</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="visible">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="received_image">
|
||||
<property name="visible">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="valign">start</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="encryption_image">
|
||||
<property name="visible">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="valign">start</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
67
main/data/icons/dino-changes-prevent-symbolic.svg
Normal file
67
main/data/icons/dino-changes-prevent-symbolic.svg
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="12">
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="layer9">
|
||||
<path
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.76307714;marker:none"
|
||||
id="rect4063"
|
||||
d="m 188.13566,241.5 c -1.44483,0 -2.63542,1.19893 -2.63542,2.65384 v 2.65385 h -0.87847 c -0.48668,0 -0.87847,0.39453 -0.87847,0.88462 V 248.16225 253 h 4.39236 1.75695 4.39235 v -4.83775 -0.46994 c 0,-0.49009 -0.39179,-0.88462 -0.87846,-0.88462 h -0.87848 v -2.65385 c 0,-1.45491 -1.19059,-2.65384 -2.63541,-2.65384 z m 0,1.76922 h 1.75695 c 0.50187,0 0.87848,0.37925 0.87848,0.88462 v 2.65385 h -3.5139 v -2.65385 c 0,-0.50537 0.3766,-0.88462 0.87847,-0.88462 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
transform="translate(-181.0002,-241)"
|
||||
style="display:inline"
|
||||
id="layer12" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -7,42 +7,51 @@ using Dino.Entities;
|
|||
|
||||
namespace Dino.Ui.ConversationSummary {
|
||||
|
||||
[GtkTemplate (ui = "/im/dino/Dino/conversation_summary/message_item.ui")]
|
||||
public class ConversationItemSkeleton : Grid {
|
||||
public class ConversationItemSkeleton : Box {
|
||||
|
||||
[GtkChild] private Image image;
|
||||
[GtkChild] private Label time_label;
|
||||
[GtkChild] private Image encryption_image;
|
||||
[GtkChild] private Image received_image;
|
||||
private Image image = new Image() { margin_top=2, valign=Align.START, visible=true };
|
||||
|
||||
public StreamInteractor stream_interactor;
|
||||
public Conversation conversation { get; set; }
|
||||
public ArrayList<Plugins.MetaConversationItem> items = new ArrayList<Plugins.MetaConversationItem>();
|
||||
|
||||
private Box box = new Box(Orientation.VERTICAL, 2) { visible=true };
|
||||
private Grid grid = new Grid() { visible=true };
|
||||
private HashMap<Plugins.MetaConversationItem, Widget> item_widgets = new HashMap<Plugins.MetaConversationItem, Widget>();
|
||||
private DefaultSkeletonHeader default_header;
|
||||
|
||||
public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation) {
|
||||
public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation, Plugins.MetaConversationItem item) {
|
||||
this.conversation = conversation;
|
||||
this.stream_interactor = stream_interactor;
|
||||
|
||||
set_main_widget(box);
|
||||
if (item.requires_avatar) {
|
||||
Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(32, 32, image.scale_factor)).set_greyscale(item.dim).draw_jid(stream_interactor, item.jid, conversation.account));
|
||||
}
|
||||
if (item.display_time != null) {
|
||||
default_header = new DefaultSkeletonHeader(stream_interactor, conversation, item) { visible=true };
|
||||
if (!item.requires_header) {
|
||||
default_header.name_label.visible = false;
|
||||
default_header.dot_label.visible = false;
|
||||
}
|
||||
grid.attach(default_header, 0, 0, 1, 1);
|
||||
}
|
||||
add_meta_item(item);
|
||||
|
||||
Box image_content_box = new Box(Orientation.HORIZONTAL, 8) { visible=true };
|
||||
image_content_box.add(image);
|
||||
image_content_box.add(grid);
|
||||
this.add(image_content_box);
|
||||
}
|
||||
|
||||
public void add_meta_item(Plugins.MetaConversationItem item) {
|
||||
items.add(item);
|
||||
if (items.size == 1) {
|
||||
setup(item);
|
||||
if (default_header != null) {
|
||||
default_header.add_item(item);
|
||||
}
|
||||
Widget widget = (Widget) item.get_widget(Plugins.WidgetType.GTK);
|
||||
if (item.requires_header) {
|
||||
box.add(widget);
|
||||
Widget? widget = item.get_widget(Plugins.WidgetType.GTK) as Widget;
|
||||
if (widget != null) {
|
||||
grid.attach(widget, 0, items.size, 1, 1);
|
||||
item_widgets[item] = widget;
|
||||
} else {
|
||||
set_title_widget(widget);
|
||||
}
|
||||
item.notify["mark"].connect_after(update_received_mark);
|
||||
update_received_mark();
|
||||
}
|
||||
|
||||
public void remove_meta_item(Plugins.MetaConversationItem item) {
|
||||
|
@ -51,45 +60,74 @@ public class ConversationItemSkeleton : Grid {
|
|||
items.remove(item);
|
||||
}
|
||||
|
||||
public void set_title_widget(Widget w) {
|
||||
attach(w, 1, 0, 1, 1);
|
||||
public void update_time() {
|
||||
if (default_header != null) {
|
||||
default_header.update_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultSkeletonHeader : Box {
|
||||
private Box box = new Box(Orientation.HORIZONTAL, 4) { visible=true };
|
||||
public Label name_label = new Label("") { use_markup=true, xalign=0, visible=true };
|
||||
public Label time_label = new Label("") { use_markup=true, xalign=0, visible=true };
|
||||
public Label dot_label = new Label("<span size='small'>·</span>") { use_markup=true, xalign=0, visible=true };
|
||||
public Image encryption_image = new Image();
|
||||
public Image received_image = new Image();
|
||||
|
||||
private StreamInteractor stream_interactor;
|
||||
private Conversation conversation;
|
||||
private Plugins.MetaConversationItem item;
|
||||
private ArrayList<Plugins.MetaConversationItem> items = new ArrayList<Plugins.MetaConversationItem>();
|
||||
|
||||
public static IconSize ICON_SIZE_HEADER = Gtk.icon_size_register("im.dino.Dino.HEADER_ICON", 17, 12);
|
||||
public virtual string TEXT_SIZE { get { return "small"; } }
|
||||
|
||||
construct {
|
||||
time_label.get_style_context().add_class("dim-label");
|
||||
dot_label.get_style_context().add_class("dim-label");
|
||||
encryption_image.opacity = 0.4;
|
||||
received_image.opacity = 0.4;
|
||||
}
|
||||
|
||||
public void set_main_widget(Widget w) {
|
||||
attach(w, 1, 1, 2, 1);
|
||||
public DefaultSkeletonHeader(StreamInteractor stream_interactor, Conversation conversation, Plugins.MetaConversationItem item) {
|
||||
this.stream_interactor = stream_interactor;
|
||||
this.conversation = conversation;
|
||||
this.item = item;
|
||||
|
||||
box.add(name_label);
|
||||
box.add(dot_label);
|
||||
box.add(time_label);
|
||||
box.add(received_image);
|
||||
box.add(encryption_image);
|
||||
this.add(box);
|
||||
|
||||
update_name_label();
|
||||
name_label.style_updated.connect(update_name_label);
|
||||
if (item.encryption != null && item.encryption != Encryption.NONE) {
|
||||
encryption_image.visible = true;
|
||||
encryption_image.set_from_icon_name("dino-changes-prevent-symbolic", ICON_SIZE_HEADER);
|
||||
}
|
||||
update_time();
|
||||
add_item(item);
|
||||
}
|
||||
|
||||
public void add_item(Plugins.MetaConversationItem item) {
|
||||
items.add(item);
|
||||
item.notify["mark"].connect_after(update_received_mark);
|
||||
update_received_mark();
|
||||
}
|
||||
|
||||
public void update_time() {
|
||||
if (items.size > 0 && items[0].display_time != null) {
|
||||
time_label.label = get_relative_time(items[0].display_time.to_local());
|
||||
if (item.display_time != null) {
|
||||
time_label.label = @"<span size='$TEXT_SIZE'>" + get_relative_time(item.display_time.to_local()) + "</span>";
|
||||
}
|
||||
}
|
||||
|
||||
private void setup(Plugins.MetaConversationItem item) {
|
||||
update_time();
|
||||
if (item.requires_avatar) {
|
||||
image.visible = true;
|
||||
Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).set_greyscale(item.dim).draw_jid(stream_interactor, item.jid, conversation.account));
|
||||
}
|
||||
if (item.requires_header) {
|
||||
set_default_title_widget(item.jid);
|
||||
}
|
||||
if (item.encryption != null && item.encryption != Encryption.NONE) {
|
||||
encryption_image.visible = true;
|
||||
encryption_image.set_from_icon_name("changes-prevent-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
}
|
||||
}
|
||||
|
||||
private void set_default_title_widget(Jid jid) {
|
||||
Label name_label = new Label("") { use_markup=true, xalign=0, hexpand=true, visible=true };
|
||||
string display_name = Util.get_display_name(stream_interactor, jid, conversation.account);
|
||||
string color = Util.get_name_hex_color(stream_interactor, conversation.account, jid, Util.is_dark_theme(name_label));
|
||||
name_label.label = @"<span foreground=\"#$color\">$display_name</span>";
|
||||
name_label.style_updated.connect(() => {
|
||||
string new_color = Util.get_name_hex_color(stream_interactor, conversation.account, jid, Util.is_dark_theme(name_label));
|
||||
name_label.set_markup(@"<span foreground=\"#$new_color\">$display_name</span>");
|
||||
});
|
||||
set_title_widget(name_label);
|
||||
private void update_name_label() {
|
||||
string display_name = Util.get_display_name(stream_interactor, item.jid, conversation.account);
|
||||
string color = Util.get_name_hex_color(stream_interactor, conversation.account, item.jid, Util.is_dark_theme(name_label));
|
||||
name_label.label = @"<span size='$TEXT_SIZE' foreground=\"#$color\">$display_name</span>";
|
||||
}
|
||||
|
||||
private void update_received_mark() {
|
||||
|
@ -99,7 +137,7 @@ public class ConversationItemSkeleton : Grid {
|
|||
foreach (Plugins.MetaConversationItem item in items) {
|
||||
if (item.mark == Message.Marked.WONTSEND) {
|
||||
received_image.visible = true;
|
||||
received_image.set_from_icon_name("dialog-warning-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
received_image.set_from_icon_name("dialog-warning-symbolic", ICON_SIZE_HEADER);
|
||||
Util.force_error_color(received_image);
|
||||
Util.force_error_color(encryption_image);
|
||||
Util.force_error_color(time_label);
|
||||
|
@ -116,19 +154,20 @@ public class ConversationItemSkeleton : Grid {
|
|||
}
|
||||
if (all_read) {
|
||||
received_image.visible = true;
|
||||
received_image.set_from_icon_name("dino-double-tick-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
received_image.set_from_icon_name("dino-double-tick-symbolic", ICON_SIZE_HEADER);
|
||||
} else if (all_received) {
|
||||
received_image.visible = true;
|
||||
received_image.set_from_icon_name("dino-tick-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
received_image.set_from_icon_name("dino-tick-symbolic", ICON_SIZE_HEADER);
|
||||
} else if (!all_sent) {
|
||||
received_image.visible = true;
|
||||
received_image.set_from_icon_name("image-loading-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
received_image.set_from_icon_name("image-loading-symbolic", ICON_SIZE_HEADER);
|
||||
} else if (received_image.visible) {
|
||||
received_image.set_from_icon_name("image-loading-symbolic", IconSize.SMALL_TOOLBAR);
|
||||
received_image.set_from_icon_name("image-loading-symbolic", ICON_SIZE_HEADER);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static string format_time(DateTime datetime, string format_24h, string format_12h) {
|
||||
public static string format_time(DateTime datetime, string format_24h, string format_12h) {
|
||||
string format = Util.is_24h_format() ? format_24h : format_12h;
|
||||
if (!get_charset(null)) {
|
||||
// No UTF-8 support, use simple colon for time instead
|
||||
|
@ -137,7 +176,7 @@ public class ConversationItemSkeleton : Grid {
|
|||
return datetime.format(format);
|
||||
}
|
||||
|
||||
private static string get_relative_time(DateTime datetime) {
|
||||
public virtual string get_relative_time(DateTime datetime) {
|
||||
DateTime now = new DateTime.now_local();
|
||||
TimeSpan timespan = now.difference(datetime);
|
||||
if (timespan > 365 * TimeSpan.DAY) {
|
||||
|
|
|
@ -161,8 +161,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
|
|||
}
|
||||
|
||||
// Fill datastructure
|
||||
ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation);
|
||||
item_skeleton.add_meta_item(item);
|
||||
ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation, item) { visible=true };
|
||||
item_item_skeletons[item] = item_skeleton;
|
||||
int index = lower_item != null ? item_skeletons.index_of(item_item_skeletons[lower_item]) + 1 : 0;
|
||||
item_skeletons.insert(index, item_skeleton);
|
||||
|
|
|
@ -59,8 +59,8 @@ public class MetaSlashmeItem : Plugins.MetaConversationItem {
|
|||
TextIter iter;
|
||||
text_view.buffer.get_start_iter(out iter);
|
||||
text_view.buffer.insert_with_tags(ref iter, display_name, display_name.length, nick_tag);
|
||||
|
||||
text_view.add_text(message.body.substring(3));
|
||||
|
||||
text_view.style_updated.connect(update_style);
|
||||
text_view.realize.connect(update_style);
|
||||
return text_view;
|
||||
|
|
Loading…
Reference in a new issue