Compare commits

...

7 Commits

Author SHA1 Message Date
Xavier Del Campo Romero 1355ba0aaf
SoupVersion.cmake: Force version required by Nice
Otherwise, Dino would crash due to conflicting Soup 2 and 3 symbols.
2023-10-04 22:36:16 +02:00
Xavier Del Campo Romero 3b3f9ee85d
file_widget.vala: Only show image when sent 2023-10-04 22:36:16 +02:00
Xavier Del Campo Romero 47433ef5ab
connection_manager.vala: Use yield on disconnect() 2023-10-04 22:36:15 +02:00
Xavier Del Campo Romero e8fd7054ff
file_sender.vala: Split very long line 2023-10-04 22:36:15 +02:00
Xavier Del Campo Romero a8df3f4cf1
Check XmppStream against null
Most of the calls to stream_interactor.get_stream(account) were already
doing null checks, but there were still some missing.
2023-10-04 22:35:36 +02:00
Xavier Del Campo Romero f93c0ef8c7
file_manager.vala: Disable automatic download 2023-10-04 22:35:36 +02:00
Xavier Del Campo Romero fe34ae1ca7
WIP chunk signals 2023-10-04 22:35:36 +02:00
14 changed files with 110 additions and 28 deletions

View File

@ -1,5 +1,5 @@
find_package(Nice QUIET)
if (Nice_FOUND AND NOT SOUP_VERSION AND NOT USE_SOUP3)
if (Nice_FOUND)
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR Nice_DEPENDENCIES
UNRESOLVED_DEPENDENCIES_VAR Nice_UNRESOLVED_DEPENDENCIES
@ -9,11 +9,21 @@ if (Nice_FOUND AND NOT SOUP_VERSION AND NOT USE_SOUP3)
)
foreach (lib ${Nice_DEPENDENCIES})
if (lib MATCHES ".*/libsoup-3.*")
if(SOUP_VERSION AND NOT SOUP_VERSION EQUAL 3)
message(FATAL_ERROR "libnice-${Nice_VERSION} depends on "
"libsoup-3, but SOUP_VERSION=${SOUP_VERSION} was given.")
endif()
set(SOUP_VERSION 3)
endif ()
endforeach ()
foreach (lib ${Nice_DEPENDENCIES})
if (lib MATCHES ".*/libsoup-2.*")
if(SOUP_VERSION AND NOT SOUP_VERSION EQUAL 2)
message(FATAL_ERROR "libnice-${Nice_VERSION} depends on "
"libsoup-2, but SOUP_VERSION=${SOUP_VERSION} was given.")
endif()
set(SOUP_VERSION 2)
endif ()
endforeach ()

View File

@ -3,7 +3,7 @@ using Xmpp;
namespace Dino.Entities {
public class FileTransfer : Object {
public signal void progress_updated(int progress);
public const bool DIRECTION_SENT = true;
public const bool DIRECTION_RECEIVED = false;
@ -70,6 +70,14 @@ public class FileTransfer : Object {
public State state { get; set; default=State.NOT_STARTED; }
public int provider { get; set; }
public string info { get; set; }
public int progress_ { get; set; }
public int progress {
get {return progress_;}
set {
progress_ = value;
progress_updated(progress_);
}
}
public Cancellable cancellable { get; default=new Cancellable(); }
private Database? db;

View File

@ -144,7 +144,7 @@ public class AvatarManager : StreamInteractionModule, Object {
}
uint8[] buffer;
pixbuf.save_to_buffer(out buffer, "png");
XmppStream stream = stream_interactor.get_stream(account);
XmppStream? stream = stream_interactor.get_stream(account);
if (stream != null) {
Xmpp.Xep.UserAvatars.publish_png(stream, buffer, pixbuf.width, pixbuf.height);
}

View File

@ -21,22 +21,26 @@ public class BlockingManager : StreamInteractionModule, Object {
}
public bool is_blocked(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
XmppStream? stream = stream_interactor.get_stream(account);
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_blocked(stream, jid.to_string());
}
public void block(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).block(stream, { jid.to_string() });
XmppStream? stream = stream_interactor.get_stream(account);
if (stream != null) {
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).block(stream, { jid.to_string() });
}
}
public void unblock(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).unblock(stream, { jid.to_string() });
XmppStream? stream = stream_interactor.get_stream(account);
if (stream != null) {
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).unblock(stream, { jid.to_string() });
}
}
public bool is_supported(Account account) {
XmppStream stream = stream_interactor.get_stream(account);
XmppStream? stream = stream_interactor.get_stream(account);
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_supported(stream);
}
}

View File

@ -59,12 +59,12 @@ public class ConnectionManager : Object {
reset();
}
public void reset() {
public async void reset() {
acked = false;
if (stream != null) {
stream.detach_modules();
stream.disconnect.begin();
yield stream.disconnect();
}
stream = null;
uuid = Xmpp.random_uuid();

View File

@ -120,6 +120,7 @@ public class FileManager : StreamInteractionModule, Object {
}
yield file_sender.send_file(conversation, file_transfer, file_send_data, file_meta);
file_transfer.state = FileTransfer.State.COMPLETE;
} catch (Error e) {
warning("Send file error: %s", e.message);
@ -292,6 +293,7 @@ public class FileManager : StreamInteractionModule, Object {
file_transfer.file_name = file_meta.file_name;
file_transfer.size = (int)file_meta.size;
file_transfer.info = info;
file_transfer.progress = 0;
var encryption = file_provider.get_encryption(file_transfer, receive_data, file_meta);
if (encryption != Encryption.NONE) file_transfer.encryption = encryption;
@ -311,11 +313,6 @@ public class FileManager : StreamInteractionModule, Object {
warning("Error downloading file: %s", e.message);
file_transfer.state = FileTransfer.State.FAILED;
}
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
download_file_internal.begin(file_provider, file_transfer, conversation, (_, res) => {
download_file_internal.end(res);
});
}
}
conversation.last_active = file_transfer.time;
@ -328,7 +325,7 @@ public class FileManager : StreamInteractionModule, Object {
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION);
yield os.splice_async(file_transfer.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE|OutputStreamSpliceFlags.CLOSE_TARGET);
file_transfer.state = FileTransfer.State.COMPLETE;
file_transfer.state = FileTransfer.State.IN_PROGRESS;
file_transfer.path = filename;
file_transfer.input_stream = yield file.read_async();
} catch (Error e) {

View File

@ -366,7 +366,10 @@ public class Dino.HistorySync {
* prev_page_result: null if this is the first page request
**/
private async PageRequestResult get_mam_page(Account account, Xmpp.MessageArchiveManagement.V2.MamQueryParams query_params, PageRequestResult? prev_page_result, Cancellable? cancellable = null) {
XmppStream stream = stream_interactor.get_stream(account);
XmppStream? stream = stream_interactor.get_stream(account);
if (stream == null) {
return new PageRequestResult.with_result(PageResult.Error);
}
Xmpp.MessageArchiveManagement.QueryResult query_result = null;
if (prev_page_result == null) {
query_result = yield Xmpp.MessageArchiveManagement.V2.query_archive(stream, query_params, cancellable);
@ -592,5 +595,9 @@ public class Dino.HistorySync {
this.query_result = query_result;
this.stanzas = stanzas;
}
public PageRequestResult.with_result(PageResult page_result) {
this.page_result = page_result;
}
}
}

View File

@ -31,7 +31,8 @@ public class FileDefaultWidget : EventBox {
cancel_button = new ModelButton() { text=_("Cancel"), visible=true };
}
public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
public void update_file_info(string? mime_type, int progress,
bool direction, FileTransfer.State state, long size) {
this.state = state;
spinner.active = false; // A hidden spinning spinner still uses CPU. Deactivate asap
@ -58,7 +59,12 @@ public class FileDefaultWidget : EventBox {
popover_menu.closed.connect(on_pointer_left);
break;
case FileTransfer.State.IN_PROGRESS:
mime_label.label = _("Downloading %s…").printf(get_size_string(size));
if (direction == FileTransfer.DIRECTION_SENT) {
mime_label.label = _("Uploading %s (%d%%)…").printf(get_size_string(size), progress);
}
else {
mime_label.label = _("Downloading %s (%d%%)…").printf(get_size_string(size), progress);
}
spinner.active = true;
image_stack.set_visible_child_name("spinner");

View File

@ -65,7 +65,8 @@ public class FileWidget : SizeRequestBox {
}
private async void update_widget() {
if (show_image() && state != State.IMAGE) {
if (show_image() && state != State.IMAGE
&& file_transfer.state == FileTransfer.State.COMPLETE) {
var content_bak = content;
FileImageWidget file_image_widget = null;
@ -148,6 +149,7 @@ public class FileDefaultWidgetController : Object {
this.notify["file-transfer-state"].connect(update_file_info);
this.notify["file-transfer-mime-type"].connect(update_file_info);
file_transfer.progress_updated.connect(update_file_info);
update_file_info();
}
@ -155,13 +157,15 @@ public class FileDefaultWidgetController : Object {
file_uri = file.get_uri();
state = FileTransfer.State.COMPLETE;
widget.name_label.label = this.file_name = file_name;
widget.update_file_info(mime_type, state, -1);
widget.update_file_info(mime_type, 0, false, state, -1);
}
private void update_file_info() {
file_uri = file_transfer.get_file().get_uri();
state = file_transfer.state;
widget.update_file_info(file_transfer.mime_type, file_transfer.state, file_transfer.size);
widget.update_file_info(file_transfer.mime_type,
file_transfer.progress,
file_transfer.direction, file_transfer.state, file_transfer.size);
}
private void open_file() {

View File

@ -74,7 +74,8 @@ public class FileSendOverlay : Gtk.EventBox {
if (widget == null) {
FileDefaultWidget default_widget = new FileDefaultWidget() { visible=true };
default_widget.name_label.label = file_name;
default_widget.update_file_info(mime_type, FileTransfer.State.COMPLETE, (long)file_info.get_size());
default_widget.update_file_info(mime_type, 100, FileTransfer.DIRECTION_SENT,
FileTransfer.State.COMPLETE, (long)file_info.get_size());
widget = default_widget;
}

View File

@ -137,6 +137,22 @@ public class FileProvider : Dino.FileProvider, Object {
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
var get_message = new Soup.Message("GET", http_receive_data.url);
#if !SOUP_3_0
uint64 received_bytes = 0;
get_message.got_chunk.connect((chunk) => {
if (file_transfer.size != 0) {
received_bytes += chunk.length;
file_transfer.progress =
(int)((received_bytes * (uint64)100)
/ (uint64)file_transfer.size);
debug(@"length=$(chunk.length), received_bytes=$(received_bytes), progress=$(file_transfer.progress)");
}
});
#else
// Soup.Message.got_body_data was introduced on 3.4, which is
// too recent for most static release distributions.
#endif
try {
#if SOUP_3_0
InputStream stream = yield session.send_async(get_message, GLib.Priority.LOW, file_transfer.cancellable);

View File

@ -25,7 +25,11 @@ public class HttpFileSender : FileSender, Object {
if (stream == null) return null;
try {
var slot_result = yield stream_interactor.module_manager.get_module(file_transfer.account, Xmpp.Xep.HttpFileUpload.Module.IDENTITY).request_slot(stream, file_transfer.server_file_name, file_meta.size, file_meta.mime_type);
var slot_result = yield stream_interactor.module_manager
.get_module(file_transfer.account,
Xmpp.Xep.HttpFileUpload.Module.IDENTITY)
.request_slot(stream, file_transfer.server_file_name,
file_meta.size, file_meta.mime_type);
send_data.url_down = slot_result.url_get;
send_data.url_up = slot_result.url_put;
send_data.headers = slot_result.headers;
@ -106,6 +110,18 @@ public class HttpFileSender : FileSender, Object {
put_message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
put_message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
#endif
uint64 sent_bytes = 0;
put_message.wrote_body_data.connect((chunk) => {
if (file_transfer.size != 0) {
sent_bytes += chunk.length;
file_transfer.progress =
(int)((sent_bytes * (uint64)100)
/ (uint64)file_transfer.size);
debug(@"length=$(chunk.length), sent_bytes=$(sent_bytes), progress=$(file_transfer.progress)");
}
});
foreach (var entry in file_send_data.headers.entries) {
put_message.request_headers.append(entry.key, entry.value);
}

View File

@ -39,7 +39,11 @@ namespace Xmpp.MessageArchiveManagement.V2 {
}
}
private StanzaNode create_base_query(XmppStream stream, MamQueryParams mam_params) {
private StanzaNode create_base_query(XmppStream? stream, MamQueryParams mam_params) {
if (stream == null) {
return new StanzaNode();
}
var fields = new ArrayList<DataForms.DataForm.Field>();
if (mam_params.with != null) {
@ -61,7 +65,12 @@ namespace Xmpp.MessageArchiveManagement.V2 {
return MessageArchiveManagement.create_base_query(stream, MessageArchiveManagement.NS_URI_2, mam_params.query_id, fields);
}
public async QueryResult query_archive(XmppStream stream, MamQueryParams mam_params, Cancellable? cancellable = null) {
public async QueryResult query_archive(XmppStream? stream, MamQueryParams mam_params, Cancellable? cancellable = null) {
if (stream == null) {
var result = new QueryResult();
result.error = true;
return result;
}
var query_node = create_base_query(stream, mam_params);
if (!mam_params.use_ns2_extended) {
query_node.put_node(ResultSetManagement.create_set_rsm_node_before(mam_params.end_id));

View File

@ -53,7 +53,11 @@ public class Module : XmppStreamModule {
}
}
internal StanzaNode create_base_query(XmppStream stream, string ns, string? queryid, Gee.List<DataForms.DataForm.Field> fields) {
internal StanzaNode create_base_query(XmppStream? stream, string ns, string? queryid, Gee.List<DataForms.DataForm.Field> fields) {
if (stream == null) {
return new StanzaNode();
}
DataForms.DataForm data_form = new DataForms.DataForm();
DataForms.DataForm.HiddenField form_type_field = new DataForms.DataForm.HiddenField() { var="FORM_TYPE" };