mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-19 15:05:40 +02:00
mainview: prevent details panel from opening maximized
also-misc: Removes SplitPanel state-saving Gitlab: #1370 Change-Id: I71f5c209922ad69fb701e935a03078fb8e5ad2de
This commit is contained in:
parent
500681fb69
commit
762cbbff38
7 changed files with 155 additions and 122 deletions
|
@ -19,6 +19,7 @@ import QtQuick.Controls
|
|||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
// A SplitView that supports dynamic RTL and splitView state saving.
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ ListSelectionView {
|
|||
splitViewStateKey: "Main"
|
||||
hasValidSelection: CurrentConversation.id !== ''
|
||||
|
||||
visible: false
|
||||
onPresented: visible = true
|
||||
|
||||
Connections {
|
||||
target: CurrentConversation
|
||||
function onReloadInteractions() {
|
||||
|
@ -75,7 +78,7 @@ ListSelectionView {
|
|||
anchors.fill: parent
|
||||
inCallView: parent == callStackView.chatViewContainer
|
||||
|
||||
property string currentConvId: CurrentConversation.id
|
||||
readonly property string currentConvId: CurrentConversation.id
|
||||
onCurrentConvIdChanged: {
|
||||
if (!CurrentConversation.hasCall) {
|
||||
Qt.callLater(focusChatView);
|
||||
|
@ -86,7 +89,7 @@ ListSelectionView {
|
|||
}
|
||||
|
||||
onDismiss: {
|
||||
if (parent == chatViewContainer) {
|
||||
if (!inCallView) {
|
||||
viewNode.dismiss();
|
||||
} else {
|
||||
callStackView.chatViewContainer.visible = false;
|
||||
|
@ -94,13 +97,14 @@ ListSelectionView {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle visibility change for the in-call chat only.
|
||||
onVisibleChanged: {
|
||||
if (!inCallView)
|
||||
return;
|
||||
if (visible && !parent.showDetails) {
|
||||
focusChatView();
|
||||
} else {
|
||||
callStackView.contentView.forceActiveFocus();
|
||||
if (inCallView) {
|
||||
if (visible) {
|
||||
focusChatView();
|
||||
} else {
|
||||
callStackView.contentView.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import net.jami.Models 1.1
|
|||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Enums 1.1
|
||||
|
||||
import "../../commoncomponents"
|
||||
import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
|
||||
|
||||
|
@ -28,7 +29,7 @@ Rectangle {
|
|||
id: root
|
||||
|
||||
// An enum to make the details panels more readable.
|
||||
enum Panel {
|
||||
enum ExtrasPanel {
|
||||
SwarmDetailsPanel,
|
||||
MessagesResearchPanel,
|
||||
AddMemberPanel
|
||||
|
@ -40,6 +41,18 @@ Rectangle {
|
|||
|
||||
required property bool inCallView
|
||||
|
||||
// Hide the extrasPanel when going into a call view, but save the previous
|
||||
// state to restore it when leaving the call view.
|
||||
property int chatExtrasPanelIndex: extrasPanel.currentIndex
|
||||
onInCallViewChanged: {
|
||||
if (inCallView) {
|
||||
chatExtrasPanelIndex = extrasPanel.currentIndex;
|
||||
extrasPanel.closePanel();
|
||||
} else if (chatExtrasPanelIndex >= 0) {
|
||||
extrasPanel.openPanel(chatExtrasPanelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
signal dismiss
|
||||
|
||||
function focusChatView() {
|
||||
|
@ -61,6 +74,16 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// Used externally to switch to a extras panel.
|
||||
function switchToPanel(panel, toggle = true) {
|
||||
extrasPanel.switchToPanel(panel, toggle);
|
||||
}
|
||||
|
||||
// Used externally to close the extras panel.
|
||||
function closePanel() {
|
||||
extrasPanel.closePanel();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: PositionManager
|
||||
function onOpenNewMap() {
|
||||
|
@ -71,23 +94,13 @@ Rectangle {
|
|||
Connections {
|
||||
target: CurrentConversation
|
||||
function onIdChanged() {
|
||||
extrasPanel.restoreState();
|
||||
MessagesAdapter.loadMoreMessages();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: extrasPanel.restoreState()
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
chatViewSplitView.resolvePanes(true);
|
||||
if (root.parent.objectName === "CallViewChatViewContainer") {
|
||||
if (root.parent.showDetails) {
|
||||
extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel);
|
||||
} else {
|
||||
extrasPanel.closePanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,9 +112,6 @@ Rectangle {
|
|||
ChatViewHeader {
|
||||
id: chatViewHeader
|
||||
|
||||
addParticipantOpened: extrasPanel.currentIndex === ChatView.AddMemberPanel
|
||||
swarmDetailsOpened: extrasPanel.currentIndex === ChatView.SwarmDetailsPanel
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: JamiTheme.chatViewHeaderPreferredHeight
|
||||
|
@ -114,9 +124,6 @@ Rectangle {
|
|||
}
|
||||
|
||||
onBackClicked: root.dismiss()
|
||||
onShowDetailsClicked: extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel)
|
||||
onSearchClicked: extrasPanel.switchToPanel(ChatView.MessagesResearchPanel)
|
||||
onAddToConversationClicked: extrasPanel.switchToPanel(ChatView.AddMemberPanel)
|
||||
|
||||
Connections {
|
||||
target: CurrentConversation
|
||||
|
@ -190,47 +197,69 @@ Rectangle {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
splitViewStateKey: "Chat"
|
||||
|
||||
property real previousDetailsWidth: extrasPanel.width
|
||||
property real previousWidth: width
|
||||
onWidthChanged: resolvePanes()
|
||||
// This function governs the visibility of the chatContents and tracks the
|
||||
// the width of the SplitView and the details panel. This function should be
|
||||
// called when the width of the SplitView changes, when the SplitView is shown,
|
||||
// and when the details panel is shown. When called with force=true, it is being
|
||||
// called from a visibleChanged event, and we should not update the previous widths.
|
||||
onWidthChanged: {
|
||||
resolvePanes();
|
||||
// Track the previous width of the split view.
|
||||
previousWidth = width;
|
||||
}
|
||||
|
||||
// Track the previous width of the split view.
|
||||
property real extrasPanelWidth: extrasPanel.width
|
||||
// The previousExtrasPanelWidth is initialized to the minimum width
|
||||
// of the extras panel. The value is updated within the "open"-state
|
||||
// range of the panel (e.g. not 0 or maximized).
|
||||
property real previousExtrasPanelWidth: JamiTheme.extrasPanelMinWidth
|
||||
onExtrasPanelWidthChanged: {
|
||||
resolvePanes();
|
||||
// This range should ensure that the panel won't restore to maximized.
|
||||
if (extrasPanelWidth != 0 && extrasPanelWidth != width) {
|
||||
console.debug("Saving previous extras panel width: %1".arg(extrasPanelWidth));
|
||||
previousExtrasPanelWidth = extrasPanelWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Respond to visibility changes for the extras panel in order to
|
||||
// determine the structure of the split view.
|
||||
property bool extrasPanelVisible: extrasPanel.visible
|
||||
onExtrasPanelVisibleChanged: {
|
||||
if (extrasPanelVisible) {
|
||||
extrasPanelWidth = previousExtrasPanelWidth;
|
||||
} else {
|
||||
previousExtrasPanelWidth = extrasPanelWidth;
|
||||
}
|
||||
resolvePanes();
|
||||
}
|
||||
|
||||
function resolvePanes(force = false) {
|
||||
if (!viewNode.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the details panel is not visible, then show the chatContents.
|
||||
if (!extrasPanel.visible) {
|
||||
chatContents.visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Next we compute whether the SplitView is expanding or shrinking.
|
||||
const isExpanding = width > previousWidth;
|
||||
|
||||
// Provide a detailed log here, as this function seems problematic.
|
||||
console.debug("ChatViewSplitView.resolvePanes: f: %1 w: %2 pw: %3 epw: %4 pepw: %5 ie: %6"
|
||||
.arg(force).arg(width).arg(previousWidth)
|
||||
.arg(extrasPanelWidth).arg(previousExtrasPanelWidth).arg(isExpanding));
|
||||
|
||||
const maximizePredicate = (!isExpanding || force) && chatContents.visible;
|
||||
const minimizePredicate = (isExpanding || force) && !chatContents.visible;
|
||||
const mainViewMinWidth = JamiTheme.mainViewPaneMinWidth;
|
||||
|
||||
// If the SplitView is not wide enough to show both the chatContents
|
||||
// and the details panel, then hide the chatContents.
|
||||
if (width < JamiTheme.mainViewPaneMinWidth + extrasPanel.width && (!isExpanding || force) && chatContents.visible) {
|
||||
if (!force)
|
||||
previousDetailsWidth = extrasPanel.width;
|
||||
if (maximizePredicate && width < mainViewMinWidth + extrasPanelWidth) {
|
||||
chatContents.visible = false;
|
||||
} else if (width >= JamiTheme.mainViewPaneMinWidth + previousDetailsWidth && (isExpanding || force) && !chatContents.visible) {
|
||||
} else if (minimizePredicate && width >= mainViewMinWidth + previousExtrasPanelWidth) {
|
||||
chatContents.visible = true;
|
||||
}
|
||||
if (!force)
|
||||
previousWidth = width;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: viewNode
|
||||
function onPresented() {
|
||||
chatViewSplitView.restoreSplitViewState();
|
||||
}
|
||||
function onDismissed() {
|
||||
chatViewSplitView.saveSplitViewState();
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
@ -315,19 +344,12 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onResizingChanged: if (chatContents.visible)
|
||||
extrasPanel.previousWidth = extrasPanel.width
|
||||
|
||||
ConversationExtrasPanel {
|
||||
id: extrasPanel
|
||||
|
||||
property int previousWidth: JamiTheme.extrasPanelMinWidth
|
||||
|
||||
SplitView.maximumWidth: root.width
|
||||
SplitView.minimumWidth: JamiTheme.extrasPanelMinWidth
|
||||
SplitView.preferredWidth: JamiTheme.extrasPanelMinWidth
|
||||
|
||||
onVisibleChanged: chatViewSplitView.resolvePanes(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,16 +23,14 @@ import net.jami.Adapters 1.1
|
|||
import net.jami.Constants 1.1
|
||||
import net.jami.Enums 1.1
|
||||
import net.jami.Models 1.1
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
signal backClicked
|
||||
signal addToConversationClicked
|
||||
signal pluginSelector
|
||||
signal showDetailsClicked
|
||||
signal searchClicked
|
||||
|
||||
Connections {
|
||||
target: CurrentConversation
|
||||
|
@ -44,7 +42,7 @@ Rectangle {
|
|||
description.eText = CurrentConversation.description;
|
||||
}
|
||||
function onShowSwarmDetails() {
|
||||
root.showDetailsClicked();
|
||||
extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,11 +58,10 @@ Rectangle {
|
|||
return true;
|
||||
}
|
||||
|
||||
property bool addParticipantOpened: false
|
||||
property bool swarmDetailsOpened: false
|
||||
|
||||
property bool addMemberVisibility: {
|
||||
return swarmDetailsVisibility && !CurrentConversation.isCoreDialog && !CurrentConversation.isRequest;
|
||||
return swarmDetailsVisibility
|
||||
&& !CurrentConversation.isCoreDialog
|
||||
&& !CurrentConversation.isRequest;
|
||||
}
|
||||
|
||||
property bool swarmDetailsVisibility: {
|
||||
|
@ -171,9 +168,7 @@ Rectangle {
|
|||
MessagesAdapter.searchbarPrompt = text;
|
||||
}
|
||||
|
||||
onSearchClicked: {
|
||||
root.searchClicked();
|
||||
}
|
||||
onSearchClicked: extrasPanel.switchToPanel(ChatView.MessagesResearchPanel)
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+Shift+F"
|
||||
|
@ -209,12 +204,12 @@ Rectangle {
|
|||
id: addParticipantsButton
|
||||
|
||||
checkable: true
|
||||
checked: root.addParticipantOpened
|
||||
checked: extrasPanel.isOpen(ChatView.AddMemberPanel)
|
||||
visible: interactionButtonsVisibility && addMemberVisibility
|
||||
source: JamiResources.add_people_24dp_svg
|
||||
toolTipText: JamiStrings.addParticipants
|
||||
|
||||
onClicked: addToConversationClicked()
|
||||
onClicked: extrasPanel.switchToPanel(ChatView.AddMemberPanel)
|
||||
}
|
||||
|
||||
JamiPushButton {
|
||||
|
@ -241,12 +236,12 @@ Rectangle {
|
|||
id: detailsButton
|
||||
|
||||
checkable: true
|
||||
checked: root.swarmDetailsOpened
|
||||
checked: extrasPanel.isOpen(ChatView.SwarmDetailsPanel)
|
||||
visible: interactionButtonsVisibility && (swarmDetailsVisibility || LRCInstance.currentAccountType === Profile.Type.SIP) // TODO if SIP not a request
|
||||
source: JamiResources.swarm_details_panel_svg
|
||||
toolTipText: JamiStrings.details
|
||||
|
||||
onClicked: showDetailsClicked()
|
||||
onClicked: extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,24 +21,46 @@ import net.jami.Adapters 1.1
|
|||
StackLayout {
|
||||
id: root
|
||||
|
||||
// We need to set the currentIndex to -1 to make sure the
|
||||
// panel is closed when the application starts.
|
||||
Component.onCompleted: closePanel()
|
||||
|
||||
// The index of the tab in the swarm details panel.
|
||||
property int detailsIndex: -1
|
||||
|
||||
// Best to avoid using the visible property directly.
|
||||
// Pass through the following open/close wrappers instead.
|
||||
function openPanel(panel) {
|
||||
currentIndex = panel;
|
||||
visible = true;
|
||||
}
|
||||
|
||||
function closePanel() {
|
||||
currentIndex = -1;
|
||||
visible = false;
|
||||
}
|
||||
|
||||
function isOpen(panel) {
|
||||
return visible && currentIndex === panel;
|
||||
}
|
||||
|
||||
visible: currentIndex > -1
|
||||
|
||||
property bool detailsShouldOpen: false
|
||||
onVisibleChanged: if (visible)
|
||||
detailsShouldOpen = true
|
||||
|
||||
function restoreState() {
|
||||
// Only applies to Jami accounts, and we musn't be in a call.
|
||||
if (detailsShouldOpen && !inCallView && !CurrentConversation.needsSyncing && !CurrentConversation.isRequest) {
|
||||
switchToPanel(ChatView.SwarmDetailsPanel, false);
|
||||
// This will open the details panel if it's not already visible.
|
||||
// Additionally, `toggle` being true (default) will close the panel
|
||||
// if it is already open to `panel`.
|
||||
function switchToPanel(panel, toggle = true) {
|
||||
console.debug("switchToPanel: %1, toggle: %2".arg(panel).arg(toggle));
|
||||
if (visible) {
|
||||
// We need to close the panel if it's open and we're switching to
|
||||
// the same panel.
|
||||
if (toggle && currentIndex === panel) {
|
||||
// Toggle off.
|
||||
closePanel();
|
||||
} else {
|
||||
// Switch to the new panel.
|
||||
openPanel(panel);
|
||||
}
|
||||
} else {
|
||||
closePanel();
|
||||
openPanel(panel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,24 +76,6 @@ StackLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// This will open the details panel if it's not already visible.
|
||||
// Additionally, `toggle` being true (default) will close the panel
|
||||
// if it is already open to `panel`.
|
||||
function switchToPanel(panel, toggle = true) {
|
||||
if (visible && toggle && currentIndex === panel) {
|
||||
closePanel();
|
||||
} else {
|
||||
currentIndex = panel;
|
||||
}
|
||||
}
|
||||
|
||||
function closePanel() {
|
||||
// We need to close the panel, but not save it when appropriate.
|
||||
currentIndex = -1;
|
||||
if (!inCallView)
|
||||
detailsShouldOpen = false;
|
||||
}
|
||||
|
||||
SwarmDetailsPanel {
|
||||
id: detailsPanel
|
||||
|
||||
|
@ -81,8 +85,6 @@ StackLayout {
|
|||
// Save it when it changes.
|
||||
onTabBarIndexChanged: root.detailsIndex = tabBarIndex
|
||||
}
|
||||
MessagesResearchPanel {
|
||||
}
|
||||
AddMemberPanel {
|
||||
}
|
||||
MessagesResearchPanel {}
|
||||
AddMemberPanel {}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ Rectangle {
|
|||
property alias chatViewContainer: chatViewContainer
|
||||
property string callPreviewId
|
||||
|
||||
// A link to the first child will provide access to the chat view.
|
||||
property var chatView: chatViewContainer.children[0]
|
||||
|
||||
onCallPreviewIdChanged: {
|
||||
controlPreview.start();
|
||||
}
|
||||
|
@ -61,6 +64,20 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
function setCallChatVisibility(visible) {
|
||||
if (visible) {
|
||||
mainColumnLayout.isHorizontal = UtilsAdapter.getAppValue(Settings.Key.ShowChatviewHorizontally);
|
||||
chatViewContainer.visible = false;
|
||||
chatViewContainer.visible = true;
|
||||
} else {
|
||||
chatViewContainer.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleCallChatVisibility() {
|
||||
setCallChatVisibility(!chatViewContainer.visible);
|
||||
}
|
||||
|
||||
function openInCallConversation() {
|
||||
mainColumnLayout.isHorizontal = UtilsAdapter.getAppValue(Settings.Key.ShowChatviewHorizontally);
|
||||
chatViewContainer.visible = false;
|
||||
|
@ -291,10 +308,7 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
|
||||
function toggleConversation() {
|
||||
if (inCallMessageWebViewStack.visible)
|
||||
closeInCallConversation();
|
||||
else
|
||||
openInCallConversation();
|
||||
toggleCallChatVisibility();
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
@ -322,19 +336,13 @@ Rectangle {
|
|||
participantsLayer.hoveredOverVideoMuted = true;
|
||||
}
|
||||
|
||||
onChatButtonClicked: {
|
||||
var detailsVisible = chatViewContainer.showDetails;
|
||||
chatViewContainer.showDetails = false;
|
||||
!chatViewContainer.visible || detailsVisible ? openInCallConversation() : closeInCallConversation();
|
||||
}
|
||||
|
||||
onFullScreenClicked: {
|
||||
callStackView.toggleFullScreen();
|
||||
}
|
||||
|
||||
onChatButtonClicked: toggleCallChatVisibility()
|
||||
onFullScreenClicked: callStackView.toggleFullScreen()
|
||||
onSwarmDetailsClicked: {
|
||||
chatViewContainer.showDetails = !chatViewContainer.showDetails;
|
||||
chatViewContainer.showDetails ? openInCallConversation() : closeInCallConversation();
|
||||
toggleCallChatVisibility();
|
||||
if (chatViewContainer.visible) {
|
||||
chatView.switchToPanel(ChatView.SwarmDetailsPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import Qt5Compat.GraphicalEffects
|
|||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
import "../../commoncomponents"
|
||||
import "../../settingsview/components"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue