1
0
Fork 0
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:
Andreas Traczyk 2023-10-02 13:56:55 -04:00
parent 500681fb69
commit 762cbbff38
7 changed files with 155 additions and 122 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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