Place time+encryption+read directly right of name

This commit is contained in:
fiaxh 2017-11-26 19:28:44 +01:00
parent 8cbc4e7f89
commit 119e7cce4f
7 changed files with 169 additions and 136 deletions

View file

@ -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;

View file

@ -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

View file

@ -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>

View 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

View file

@ -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 void set_main_widget(Widget w) {
attach(w, 1, 1, 2, 1);
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 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) {

View file

@ -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);

View file

@ -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;