~nicohman/signal-rs

323c129fa86bb81c565d359f329f8b986f9ee021 — nicohman 5 months ago 65a31f5 qt
Re-add editcontact, and fix createchat lag
M Cargo.lock => Cargo.lock +2 -2
@@ 1220,9 1220,9 @@ checksum = "f44db4199cdb049b494a92d105acbfa43c25b3925e33803923ba9580b7bc9e1a"

[[package]]
name = "libc"
version = "0.2.82"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"

[[package]]
name = "libdbus-sys"

M qml/ChatHistory.qml => qml/ChatHistory.qml +12 -1
@@ 10,6 10,12 @@ Kirigami.ScrollablePage {
    property var msgImgComponent: Qt.createComponent(Qt.resolvedUrl("MessageImage.qml"))
    objectName: "chatHistory"
    title: signalState.currentName
    actions.main: Kirigami.Action {
        id: editContactAction
        icon.name: "document-edit"
        text: "Edit Chat"
        onTriggered: signalState.openView("editContact");
    }
    function sendMessage() {
        console.log("Sending "+ msgTextInput.text +" to "+signalState.current);
        if (signalState.currentChat.is_group) {


@@ 19,6 25,10 @@ Kirigami.ScrollablePage {
        }
        msgTextInput.text = "";
    }
    Connections {
        target: signal
        function msgs_changed() {}
    }
    FileDialog {
        id: fd
        title: "Upload an attachment"


@@ 37,7 47,8 @@ Kirigami.ScrollablePage {
        }
        }
    }
            ListView {
           ListView {
            verticalLayoutDirection: ListView.BottomToTop
                anchors.fill: parent
            Layout.topMargin: 10
            highlight: Rectangle {

M qml/CreateChat.qml => qml/CreateChat.qml +28 -38
@@ 3,46 3,36 @@ import QtQuick.Controls 2.5
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.13 as Kirigami

Kirigami.Page {
Kirigami.ScrollablePage {
	title: "Create Chat"
	ColumnLayout {
		anchors.leftMargin: 10
	ListView {
		anchors.fill: parent
		Row {
			Label {
				font.pixelSize: Qt.application.font.pixelSize * 1.3
				text: "Create a new chat"
				height: 20
			}
		}
		ListView {
			Layout.topMargin: 20
			Layout.fillWidth: true
			Layout.fillHeight: true
			model: signal.contacts
			delegate: ItemDelegate {
				width: parent.width
				height: 40
				onClicked: {
					// Dumb hack to get around fact that we don't have an official Chat yet
	                signalState.currentChat = {
	                	is_group: false
	                };
	                signalState.currentName = model.name;
	                signalState.setCurrent(model.tel);
	                signal.show_chat(model.tel);
	                signalState.openView("chatHistory");
				}
				Row {
					Avatar {
						tel: model.tel
						width: 40
						height: 40
					}
					Label {
						height: 20
						text: model.name
					}
		model: signal.contacts
		delegate: ItemDelegate {
			//width: parent.width
			width: crLa.width //+ crAv.width
			height: 40
			/*onClicked: {
				// Dumb hack to get around fact that we don't have an official Chat yet
                signalState.currentChat = {
                	is_group: false
                };
                signalState.currentName = model.name;
                signalState.setCurrent(model.tel);
                signal.show_chat(model.tel);
                signalState.openView("chatHistory");
			}*/
			Row {
				/*Avatar {
					id: crAv
					tel: model.tel
					width: 40
					height: 40
				}*/
				Label {
					id: crLa
					height: 20
					text: model.name
				}
			}
		}

M qml/EditContact.qml => qml/EditContact.qml +1 -1
@@ 61,7 61,7 @@ Kirigami.Page {
				onClicked: {
					console.log("Sending edit contact");
					signal.edit_contact(editContactName.text, editContactTel.text, editContact.currentTel)
					stackView.pop();
					window.pageStack.layers.pop();
				}
			}
		}

M qml/MessageImage.qml => qml/MessageImage.qml +2 -4
@@ 15,11 15,9 @@ Image {
	MouseArea {
		anchors.fill: parent
		onClicked: {
			msgImgOver.filePath = messageImage.filePath;
			msgImgOver.open();
		}
	}
	PictureOverlay {
		id: msgImgOver
		filePath: messageImage.filePath
	}

}
\ No newline at end of file

M qml/MessageUI.qml => qml/MessageUI.qml +13 -5
@@ 22,16 22,21 @@ ItemDelegate {
    Component.onCompleted : {
        if (message.message.attachment && message.message.attachment !== "[]") {
            var attachments  = JSON.parse(new String(message.message.attachment));
            if (attachments && attachments.length) {
            attachments.forEach(function(at) {
                message.attachmentModel.append(at);
            });
        }
        }
        if (message.message.reactions && message.message.reactions !== "[]") {
            var reactions = JSON.parse(new String(message.message.reactions));
                        if (reactions && reactions.length) {

            reactions.forEach(function(r) {
                message.reactionModel.append(r);
            });
        }
        }
    }
    Row {
        id: row


@@ 78,6 83,7 @@ ItemDelegate {
                Row {
                    leftPadding: 5
                    TextEdit {
                        textFormat: Text.RichText
                        Kirigami.Theme.inherit: true
                        selectByMouse: !Kirigami.Settings.isMobile
                        readOnly: true


@@ 86,7 92,10 @@ ItemDelegate {
                            cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
                            acceptedButtons: Qt.NoButton
                        }
                        onLinkActivated: Qt.openUrlExternally(link)
                        onLinkActivated: {
                            console.log("Opening link " + link);
                            Qt.openUrlExternally(link);
                        }
                    	color:  Kirigami.Theme.textColor
                        font.pixelSize: Qt.application.font.pixelSize
                        font.bold: false


@@ 96,7 105,7 @@ ItemDelegate {
                            var regex = new RegExp("http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+");
                            return message.message.message.toString().replace(regex, "<a href=\"$&\">$&</a>");
                        }
                        wrapMode: Text.Wrap
                        wrapMode: Text.WordWrap
                    }
                }
                Row {


@@ 115,7 124,7 @@ ItemDelegate {
                            Component.onCompleted: {
                                switch (CType) {
                                    case 2:
                                        var obj = msgimgover.createObject(atRow, {filePath: File});//Qt.createQmlObject(`import QtQuick 2.15; Image { width: 350\nfillMode: Image.PreserveAspectFit\nsource: "file://${File}"}`,atRow,  "imageDel");
                                        var obj = msgimgover.createObject(atRow, {filePath: File});
                                        if (obj.width > rectangle.width) {
                                            rectangle.width = obj.width + 10;
                                        }


@@ 133,8 142,7 @@ ItemDelegate {
                	id: dynName
                	leftPadding: 5
                	Label {
                		color: theme.highlightedText
                		text: signal.resolve_name(message.message.source)//signalState.contact(message.message.source).Name || message.message.source
                		text: signal.resolve_name(message.message.source)
                		visible: signalState.currentChat && signalState.currentChat.is_group
                	}
                }

M qml/PictureOverlay.qml => qml/PictureOverlay.qml +3 -0
@@ 16,6 16,9 @@ Kirigami.OverlaySheet {
		}
		fillMode: Image.PreserveAspectFit
		source: {
			if (!photoOverlay.filePath) {
				return ""
			}
			return "file://"+photoOverlay.filePath;
		}
	}

M qml/Settings.qml => qml/Settings.qml +2 -4
@@ 1,13 1,11 @@
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.13 as Kirigami

Page {
Kirigami.Page {
	anchors.fill: stackView
    title: qsTr("Settings")
    background:Rectangle {
    	color: theme.background
    }
    ColumnLayout {
    	Layout.fillWidth: true
    	Row {

M qml/SignalState.qml => qml/SignalState.qml +3 -3
@@ 18,7 18,7 @@ Item {
                window.pageStack.push(chatViewStack);
                break;
            case "createContact":
                window.pageStack.push(Qt.resolvedUrl("CreateContact.qml"));
                window.pageStack.layers.push(Qt.resolvedUrl("CreateContact.qml"));
                break;
            case "settings":
                window.pageStack.push(Qt.resolvedUrl("Settings.qml"));


@@ 29,10 29,10 @@ Item {
                }
                break;
            case "editContact":
                window.pageStack.push(Qt.resolvedUrl("EditContact.qml"));
                window.pageStack.layers.push(Qt.resolvedUrl("EditContact.qml"));
                break;
            case "createChat":
                window.pageStack.push(Qt.resolvedUrl("CreateChat.qml"));
                window.pageStack.push(createChatStack);
                break;
        }
    }

M qml/main.qml => qml/main.qml +16 -1
@@ 18,6 18,10 @@ Kirigami.ApplicationWindow {
        id: systemPalette
        colorGroup: SystemPalette.Active
    }
        PictureOverlay {
        id: msgImgOver
        filePath: ""
    }
    SignalState {
        id: signalState
    }


@@ 30,6 34,7 @@ Kirigami.ApplicationWindow {
        }
        name: "signal"
        onReady: {
            //Kirigami.Settings.setIsMobile(true);
            signalState.currentView = "chats";
            window.pageStack.replace(chatViewStack);
            //toolButton.enabled = true;


@@ 59,6 64,13 @@ Kirigami.ApplicationWindow {
                }
            },
            Kirigami.Action {
                text: "Settings"
                icon.name: "settings-configure"
                onTriggered: {
                    signalState.openView("settings")
                }
            },
            Kirigami.Action {
                text: i18n("Quit")
                icon.name: "gtk-quit"
                shortcut: StandardKey.Quit


@@ 201,7 213,10 @@ Kirigami.ApplicationWindow {
        id: msgimgover
        MessageImage {}
    }

    Component {
        id: createChatStack
        CreateChat {}
    }
}



M src/main.rs => src/main.rs +15 -8
@@ 154,7 154,6 @@ impl SignalUI {
        serde_json::to_string(&fetched).unwrap()
    }
    fn update_chat(&mut self, chat_id: String) {
        let mut i = 0;
        let name = self.resolve_name(chat_id.clone());
        if let Some(msgs) = self
            .state


@@ 167,7 166,7 @@ impl SignalUI {
            if msgs.len() > 0 {
                let latest = msgs.values().max_by_key(|x| x.sent_at).unwrap();
                let mut chats = self.chats.borrow_mut();
                loop {
                for i in 0..chats.row_count() as usize {
                    let mut chat = chats[i].clone();
                    if chat.tel == chat_id {
                        chat.name = name.clone();


@@ 179,7 178,6 @@ impl SignalUI {
                        chats.insert(0, chat);
                        break;
                    }
                    i += 1;
                }
            }
        }


@@ 232,6 230,7 @@ impl SignalUI {
                .unwrap()
                .values()
                .cloned()
                .rev()
                .map(|x| QMLSignalMessage::from_msg(x))
                .collect(),
        );


@@ 262,8 261,9 @@ impl SignalUI {
                        slf.chats.borrow_mut().reset_data(chats.clone());
                        slf.chats_changed();
                    }
                    SignalResponse::ContactList(ref contacts) => {
                        slf.contacts.borrow_mut().reset_data(contacts.clone());
                    SignalResponse::ModelContactList(contacts) => {
                        println!("Rec up contacts");
                        slf.contacts.borrow_mut().reset_data(contacts);
                        slf.contacts_changed();
                    }
                    SignalResponse::AddHist(ref msg, new) => {


@@ 271,7 271,7 @@ impl SignalUI {
                            if msg.chat_id == slf.current_messages {
                                slf.messages
                                    .get_mut()
                                    .push(QMLSignalMessage::from_msg(msg.clone()));
                                    .insert(0, QMLSignalMessage::from_msg(msg.clone()));
                            }
                            let cfg = cfg;
                            if cfg.notifications == NotificationPolicy::Enabled {


@@ 326,6 326,7 @@ impl SignalUI {
                            }
                        }
                        println!("Finished initialization");
                        slf.state.as_ref().unwrap().update_contacts();
                        slf.show_view("chats".to_string());
                        slf.ready();
                        slf.signalResponse(serde_json::to_string(&res).unwrap());


@@ 498,10 499,16 @@ impl SignalState {
        return self.sbackend.resolve_name(source.as_str()).unwrap();
    }
    pub fn update_contacts(&self) {
        let mut contacts: Vec<Contact> = self.sbackend.contacts().values().cloned().collect();
        let mut contacts: Vec<Contact> = self
            .sbackend
            .contacts()
            .into_iter()
            .map(|(_k, v)| v)
            .collect();
        contacts.sort_by_key(|x| x.name.clone());
        println!("Updated contacts");
        self.res_sender
            .send(SignalResponse::ContactList(contacts))
            .send(SignalResponse::ModelContactList(contacts))
            .expect("Couldn't send ContactList");
    }
    /// Shows a given chat by tel

M src/scli.rs => src/scli.rs +2 -1
@@ 539,7 539,7 @@ impl SCLISession {
        self.groups.clone()
    }
    pub fn contacts<'a>(&'a self) -> HashMap<String, Contact> {
        let map = self
        let map: HashMap<String, Contact> = self
            .contact_store
            .all()
            .unwrap()


@@ 549,6 549,7 @@ impl SCLISession {
                (x.tel.clone(), x)
            })
            .collect();
        println!("{}", map.len());
        map
    }
    pub fn process_response(&mut self, response: SignalResponse) {

M src/signal.rs => src/signal.rs +3 -1
@@ 159,6 159,8 @@ pub enum SignalResponse {
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    ContactList(Vec<Contact>),
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    ModelContactList(Vec<Contact>),
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    ChatList(Vec<Chat>),
    #[evt(derive(Clone, Serialize, Deserialize, Debug))]
    MessageList(SignalMessageList),


@@ 377,7 379,7 @@ trait SignalResponseTrait {}
impl SignalResponseTrait for SignalResponse {}
#[serde(rename_all = "PascalCase")]
#[pallet(tree_name = "contacts")]
#[derive(Serialize, Deserialize, Clone, Debug, DocumentLike, QGadget, Default, SimpleListItem)]
#[derive(Serialize, Deserialize, Clone, Debug, DocumentLike, Default, SimpleListItem)]
pub struct Contact {
    pub tel: String,
    //pub uuid: String,