1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-03 14:25:38 +02:00

misc: fix contact request UI issues

- switch between "conversations" - "invitations" smartlists according to call origin
- "Accept Request" button from msg's view header: hide on contact accepted, set on view load according to userType
- correct requests smartlist item selection on tab switch
- accept incoming call from pending contact makes conversation permanent

Gitlab: #74

Change-Id: Iadfef0d7e4032002d8007a4f18a9eae27f7ba230
This commit is contained in:
ababi 2020-09-14 16:15:28 +02:00 committed by Andreas Traczyk
parent 2df280c3fb
commit 95df47c717
17 changed files with 113 additions and 80 deletions

View file

@ -285,6 +285,12 @@ AccountAdapter::setSelectedConvId(const QString& convId)
LRCInstance::setSelectedConvId(convId);
}
lrc::api::profile::Type
AccountAdapter::getCurrentAccountType()
{
return LRCInstance::getCurrentAccountInfo().profileInfo.type;
}
void
AccountAdapter::onCurrentAccountChanged()
{

View file

@ -104,6 +104,7 @@ public:
Q_INVOKABLE bool isPreviewing();
Q_INVOKABLE void setCurrAccDisplayName(const QString& text);
Q_INVOKABLE void setSelectedConvId(const QString& convId = {});
Q_INVOKABLE lrc::api::profile::Type getCurrentAccountType();
signals:
/*

View file

@ -100,6 +100,18 @@ CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
LRCInstance::getAccountInfo(accountId).callModel->accept(convInfo.callId);
auto& accInfo = LRCInstance::getAccountInfo(convInfo.accountId);
accInfo.callModel->setCurrentCall(convInfo.callId);
auto contactUri = convInfo.participants.front();
if (contactUri.isEmpty()) {
return;
}
try {
auto& contact = accInfo.contactModel->getContact(contactUri);
if (contact.profileInfo.type == lrc::api::profile::Type::PENDING) {
LRCInstance::getCurrentConversationModel()->makePermanent(convInfo.uid);
}
} catch (...) {
}
}
}
@ -294,7 +306,9 @@ CallAdapter::showNotification(const QString& accountId, const QString& convUid)
#else
emit LRCInstance::instance().notificationClicked(true);
#endif
callSetupMainViewRequired(convInfo.accountId, convInfo.uid);
if (!convInfo.uid.isEmpty()) {
emit callSetupMainViewRequired(convInfo.accountId, convInfo.uid);
}
};
emit LRCInstance::instance().updateSmartList();
Utils::showNotification(tr("is calling you"), from, accountId, convUid, onClicked);

View file

@ -30,7 +30,11 @@
ConversationsAdapter::ConversationsAdapter(QObject* parent)
: QmlAdapterBase(parent)
{}
{
connect(this, &ConversationsAdapter::currentTypeFilterChanged, [this]() {
LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
});
}
void
ConversationsAdapter::safeInit()
@ -56,6 +60,10 @@ ConversationsAdapter::safeInit()
&ConversationsAdapter::onCurrentAccountIdChanged);
connectConversationModel();
setProperty("currentTypeFilter", QVariant::fromValue(
LRCInstance::getCurrentAccountInfo().profileInfo.type));
}
void
@ -71,21 +79,22 @@ ConversationsAdapter::selectConversation(const QString& accountId, const QString
auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
const auto& convInfo = convModel->getConversationForUID(convUid);
if (LRCInstance::getCurrentConvUid() != convInfo.uid
&& convInfo.participants.size() > 0) {
if (LRCInstance::getCurrentConvUid() != convInfo.uid && convInfo.participants.size() > 0) {
// If the account is not currently selected, do that first, then
// proceed to select the conversation.
auto selectConversation = [convInfo] {
auto selectConversation = [this, convInfo] {
auto& accInfo = LRCInstance::getAccountInfo(convInfo.accountId);
LRCInstance::setSelectedConvId(convInfo.uid);
accInfo.conversationModel->clearUnreadInteractions(convInfo.uid);
// Set contact filter (for conversation tab selection)
auto& contact = accInfo.contactModel->getContact(convInfo.participants.front());
setProperty("currentTypeFilter", QVariant::fromValue(contact.profileInfo.type));
};
if (convInfo.accountId != LRCInstance::getCurrAccId()) {
Utils::oneShotConnect(&LRCInstance::instance(),
&LRCInstance::currentAccountChanged,
[selectConversation] {
selectConversation();
});
[selectConversation] { selectConversation(); });
LRCInstance::setSelectedConvId(); // Hack UI
LRCInstance::setSelectedAccountId(convInfo.accountId);
} else {
@ -117,15 +126,11 @@ ConversationsAdapter::deselectConversation()
void
ConversationsAdapter::onCurrentAccountIdChanged()
{
auto accountId = LRCInstance::getCurrAccId();
auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
currentTypeFilter_ = accountInfo.profileInfo.type;
LRCInstance::getCurrentConversationModel()->setFilter(accountInfo.profileInfo.type);
updateConversationsFilterWidget();
disconnectConversationModel();
connectConversationModel();
setProperty("currentTypeFilter", QVariant::fromValue(
LRCInstance::getCurrentAccountInfo().profileInfo.type));
}
void
@ -141,7 +146,10 @@ ConversationsAdapter::onNewUnreadInteraction(const QString& accountId,
auto& accInfo = LRCInstance::getAccountInfo(accountId);
auto& contact = accInfo.contactModel->getContact(interaction.authorUri);
auto from = Utils::bestNameForContact(contact);
auto onClicked = [this, accountId, convUid, uri = interaction.authorUri] {
auto onClicked = [this,
accountId,
convUid,
uri = interaction.authorUri] {
#ifdef Q_OS_WINDOWS
emit LRCInstance::instance().notificationClicked();
#else
@ -166,37 +174,11 @@ ConversationsAdapter::updateConversationsFilterWidget()
// Update status of "Conversations" and "Invitations".
auto invites = LRCInstance::getCurrentAccountInfo().contactModel->pendingRequestCount();
if (invites == 0 && currentTypeFilter_ == lrc::api::profile::Type::PENDING) {
currentTypeFilter_ = lrc::api::profile::Type::RING;
LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
setProperty("currentTypeFilter", QVariant::fromValue(lrc::api::profile::Type::RING));
}
showConversationTabs(invites);
}
void
ConversationsAdapter::setConversationFilter(const QString& type)
{
// Set conversation filter according to type,
// type needs to be recognizable by lrc::api::profile::to_type.
if (type.isEmpty()) {
if (LRCInstance::getCurrentAccountInfo().profileInfo.type == lrc::api::profile::Type::RING)
setConversationFilter(lrc::api::profile::Type::RING);
else
setConversationFilter(lrc::api::profile::Type::SIP);
} else {
setConversationFilter(lrc::api::profile::to_type(type));
}
}
void
ConversationsAdapter::setConversationFilter(lrc::api::profile::Type filter)
{
if (currentTypeFilter_ == filter) {
return;
}
currentTypeFilter_ = filter;
LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
}
void
ConversationsAdapter::refill()
{
@ -290,8 +272,9 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
emit updateListViewRequested();
});
if (updateFilter)
currentConversationModel->setFilter("");
if (updateFilter) {
currentTypeFilter_ = lrc::api::profile::Type::INVALID;
}
return true;
}

View file

@ -28,6 +28,9 @@
class ConversationsAdapter final : public QmlAdapterBase
{
Q_OBJECT
Q_PROPERTY(lrc::api::profile::Type currentTypeFilter MEMBER currentTypeFilter_ NOTIFY
currentTypeFilterChanged)
public:
explicit ConversationsAdapter(QObject* parent = nullptr);
~ConversationsAdapter() = default;
@ -42,7 +45,6 @@ public:
Q_INVOKABLE void deselectConversation();
Q_INVOKABLE void refill();
Q_INVOKABLE void updateConversationsFilterWidget();
Q_INVOKABLE void setConversationFilter(const QString& type);
signals:
void showConversation(const QString& accountId, const QString& convUid);
@ -53,6 +55,7 @@ signals:
void modelSorted(const QVariant& uri);
void updateListViewRequested();
void navigateToWelcomePageRequested();
void currentTypeFilterChanged();
private slots:
void onCurrentAccountIdChanged();
@ -62,7 +65,6 @@ private slots:
const interaction::Info& interaction);
private:
void setConversationFilter(lrc::api::profile::Type filter);
void backToWelcomePage();
void updateConversationForNewContact(const QString& convUid);

View file

@ -124,6 +124,7 @@ Window {
return UtilsAdapter.hasCall(AccountAdapter.currentAccountId)
}
// Only called onWidthChanged
function recursionStackViewItemMove(stackOne, stackTwo, depth=1) {
// Move all items (expect the bottom item) to stacktwo by the same order in stackone.
if (stackOne.depth === depth) {
@ -461,7 +462,7 @@ Window {
mainViewWindowSidePanel.forceUpdateConversationSmartListView()
}
function onContactBanned() {
function onNavigateToWelcomePageRequested() {
backToMainView()
}
}

View file

@ -192,6 +192,8 @@ Rectangle {
onCallAcceptButtonIsClicked: {
CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
mainViewWindowSidePanel.selectTab(SidePanelTabBar.Conversations)
}
onCallCancelButtonIsClicked: {

View file

@ -43,6 +43,7 @@ Item {
responsibleAccountId,
responsibleConvUid, false)
CallAdapter.placeCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
})
ContextMenuGenerator.addMenuItem(qsTr("Start audio call"),
"qrc:/images/icons/ic_phone_24px.svg",
@ -51,6 +52,7 @@ Item {
responsibleAccountId,
responsibleConvUid, false)
CallAdapter.placeAudioOnlyCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
})
ContextMenuGenerator.addMenuItem(qsTr("Clear conversation"),
@ -80,7 +82,8 @@ Item {
})
}
if ((contactType === Profile.Type.RING || contactType === Profile.Type.PENDING)) {
if ((contactType === Profile.Type.RING || contactType === Profile.Type.PENDING
|| contactType === Profile.Type.TEMPORARY)) {
if (contactType === Profile.Type.PENDING || !hasCall) {
ContextMenuGenerator.addMenuSeparator()
}
@ -91,7 +94,10 @@ Item {
function (){
MessagesAdapter.acceptInvitation(
responsibleConvUid)
communicationPageMessageWebView.
setSendContactRequestButtonVisible(false)
})
ContextMenuGenerator.addMenuItem(JamiStrings.declineContactRequest,
"qrc:/images/icons/round-close-24px.svg",
function (){

View file

@ -89,6 +89,7 @@ ListView {
enabled: root.visible
onActivated: {
CallAdapter.placeCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}
@ -98,6 +99,7 @@ ListView {
enabled: root.visible
onActivated: {
CallAdapter.placeAudioOnlyCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}

View file

@ -175,6 +175,7 @@ ItemDelegate {
UID,
false)
CallAdapter.placeCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}
onReleased: {

View file

@ -156,6 +156,7 @@ Rectangle {
incomingCallPage.close()
CallAdapter.acceptACall(responsibleAccountId,
responsibleConvUid)
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}

View file

@ -152,14 +152,17 @@ Rectangle {
function acceptInvitation() {
MessagesAdapter.acceptInvitation()
messageWebViewHeader.sendContactRequestButtonVisible = false
}
function refuseInvitation() {
MessagesAdapter.refuseInvitation()
messageWebViewHeader.sendContactRequestButtonVisible = false
}
function blockConversation() {
MessagesAdapter.blockConversation()
messageWebViewHeader.sendContactRequestButtonVisible = false
}
function emitMessagesCleared() {

View file

@ -150,6 +150,7 @@ Rectangle {
onClicked: {
MessagesAdapter.sendContactRequest()
CallAdapter.placeAudioOnlyCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}
@ -171,6 +172,7 @@ Rectangle {
onClicked: {
MessagesAdapter.sendContactRequest()
CallAdapter.placeCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}

View file

@ -61,8 +61,6 @@ Rectangle {
function accountChangedUIReset() {
contactSearchBar.clearText()
sidePanelTabBar.converstationTabDown = true
sidePanelTabBar.invitationTabDown = false
}
function refreshAccountComboBox(index) {
@ -80,6 +78,10 @@ Rectangle {
conversationSmartListView.updateListView()
}
function selectTab(tabIndex) {
sidePanelTabBar.selectTab(tabIndex)
}
// Intended -> since strange behavior will happen without this for stackview.
anchors.top: parent.top
anchors.fill: parent

View file

@ -1,4 +1,3 @@
/*
* Copyright (C) 2020 by Savoir-faire Linux
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@ -16,18 +15,40 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.12
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import "../../commoncomponents"
TabBar {
id: tabBar
property alias converstationTabDown: pageOne.down
property alias invitationTabDown: pageTwo.down
enum TabIndex {
Conversations,
Requests
}
Connections {
target: ConversationsAdapter
function onCurrentTypeFilterChanged() {
pageOne.down = ConversationsAdapter.currentTypeFilter !== Profile.Type.PENDING
pageTwo.down = ConversationsAdapter.currentTypeFilter === Profile.Type.PENDING
setCurrentUidSmartListModelIndex()
forceReselectConversationSmartListCurrentIndex()
}
}
function selectTab(tabIndex) {
ConversationsAdapter.currentTypeFilter = tabIndex ===
SidePanelTabBar.Conversations ? AccountAdapter.getCurrentAccountType() :
Profile.Type.PENDING
}
property alias converstationTabWidth: pageOne.width
property alias invitationTabWidth: pageTwo.width
property alias converstationTabHeight: pageOne.height
@ -76,14 +97,6 @@ TabBar {
height: tabBar.height
color: JamiTheme.backgroundColor
function showConversations() {
ConversationsAdapter.setConversationFilter("")
pageOne.down = true
pageTwo.down = false
setCurrentUidSmartListModelIndex()
forceReselectConversationSmartListCurrentIndex()
}
Image {
id: imgRectOne
anchors.horizontalCenter: buttonRectOne.horizontalCenter
@ -135,7 +148,7 @@ TabBar {
anchors.fill: parent
hoverEnabled: true
onPressed: {
buttonRectOne.showConversations()
selectTab(SidePanelTabBar.Conversations)
}
onReleased: {
buttonRectOne.color = JamiTheme.backgroundColor
@ -153,7 +166,7 @@ TabBar {
context: Qt.ApplicationShortcut
enabled: buttonRectOne.visible
onActivated: {
buttonRectOne.showConversations()
selectTab(SidePanelTabBar.Conversations)
}
}
}
@ -195,12 +208,6 @@ TabBar {
height: tabBar.height
color: JamiTheme.backgroundColor
function showRequests() {
ConversationsAdapter.setConversationFilter("PENDING")
pageTwo.down = true
pageOne.down = false
}
Image {
id: imgRectTwo
anchors.horizontalCenter: buttonRectTwo.horizontalCenter
@ -254,7 +261,7 @@ TabBar {
anchors.fill: parent
hoverEnabled: true
onPressed: {
buttonRectTwo.showRequests()
selectTab(SidePanelTabBar.Requests)
}
onReleased: {
buttonRectTwo.color = JamiTheme.backgroundColor
@ -272,7 +279,7 @@ TabBar {
context: Qt.ApplicationShortcut
enabled: buttonRectTwo.visible
onActivated: {
buttonRectTwo.showRequests()
selectTab(SidePanelTabBar.Requests)
}
}
}

View file

@ -67,22 +67,18 @@ MessagesAdapter::setupChatView(const QString& uid)
QString contactURI = convInfo.participants.at(0);
bool isContact = false;
auto selectedAccountId = LRCInstance::getCurrAccId();
auto& accountInfo = LRCInstance::accountModel().getAccountInfo(selectedAccountId);
lrc::api::profile::Type contactType;
lrc::api::profile::Type contactType = lrc::api::profile::Type::INVALID;
try {
auto contactInfo = accountInfo.contactModel->getContact(contactURI);
if (contactInfo.isTrusted) {
isContact = true;
}
contactType = contactInfo.profileInfo.type;
} catch (...) {
}
bool shouldShowSendContactRequestBtn = !isContact
&& contactType != lrc::api::profile::Type::SIP;
bool shouldShowSendContactRequestBtn = (contactType == lrc::api::profile::Type::PENDING
|| contactType == lrc::api::profile::Type::TEMPORARY);
QMetaObject::invokeMethod(qmlObj_,
"setSendContactRequestButtonVisible",
@ -453,7 +449,8 @@ MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info&
try {
auto& contact = accInfo->contactModel->getContact(contactUri);
auto bestName = Utils::bestNameForConversation(convInfo, *convModel);
setInvitation(contact.profileInfo.type == lrc::api::profile::Type::PENDING,
setInvitation(contact.profileInfo.type == lrc::api::profile::Type::PENDING
|| contact.profileInfo.type == lrc::api::profile::Type::TEMPORARY,
bestName,
contactUri);
@ -652,6 +649,7 @@ MessagesAdapter::refuseInvitation(const QString& convUid)
const auto currentConvUid = convUid.isEmpty() ? LRCInstance::getCurrentConvUid() : convUid;
LRCInstance::getCurrentConversationModel()->removeConversation(currentConvUid, false);
setInvitation(false);
emit navigateToWelcomePageRequested();
}
void
@ -661,4 +659,5 @@ MessagesAdapter::blockConversation(const QString& convUid)
LRCInstance::getCurrentConversationModel()->removeConversation(currentConvUid, true);
setInvitation(false);
emit contactBanned();
emit navigateToWelcomePageRequested();
}

View file

@ -88,6 +88,7 @@ protected:
signals:
void needToUpdateSmartList();
void contactBanned();
void navigateToWelcomePageRequested();
public slots:
void slotSendMessageContentSaved(const QString& content);