really fix empty lists ui + display contacts on init when necessary + fix ensureVisible contact form

This commit is contained in:
Gaelle Braud 2024-11-06 17:27:09 +01:00
parent d11b3bce3d
commit 48ccfe95c7
18 changed files with 71 additions and 63 deletions

View file

@ -69,7 +69,7 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo>
mUri = address && address->isValid() && !address->getDomain().empty()
? Utils::coreStringToAppString(address->asStringUriOnly())
: "";
mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000, Qt::LocalTime);
mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000);
mDuration = conferenceInfo->getDuration();
mEndDateTime = mDateTime.addSecs(mDuration * 60);
mIsScheduled = mDateTime.isValid();

View file

@ -66,7 +66,6 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
mJob = Utils::coreStringToAppString(vcard->getJobTitle());
mGivenName = Utils::coreStringToAppString(vcard->getGivenName());
mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName());
mFullName = Utils::coreStringToAppString(vcard->getFullName());
mVCardString = Utils::coreStringToAppString(vcard->asVcard4String());
}
auto addresses = contact->getAddresses();
@ -102,6 +101,8 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact);
connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged);
connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged);
connect(this, &FriendCore::givenNameChanged, &FriendCore::displayNameChanged);
connect(this, &FriendCore::familyNameChanged, &FriendCore::displayNameChanged);
}
FriendCore::FriendCore(const FriendCore &friendCore) {
@ -111,7 +112,6 @@ FriendCore::FriendCore(const FriendCore &friendCore) {
mDefaultAddress = friendCore.mDefaultAddress;
mGivenName = friendCore.mGivenName;
mFamilyName = friendCore.mFamilyName;
mFullName = friendCore.mFullName;
mOrganization = friendCore.mOrganization;
mJob = friendCore.mJob;
mPictureUri = friendCore.mPictureUri;
@ -232,7 +232,6 @@ void FriendCore::reset(const FriendCore &contact) {
resetAddresses(contact.getAddresses());
resetPhoneNumbers(contact.getPhoneNumbers());
setDefaultAddress(contact.getDefaultAddress());
setDisplayName(contact.getDisplayName());
setGivenName(contact.getGivenName());
setFamilyName(contact.getFamilyName());
setOrganization(contact.getOrganization());
@ -242,15 +241,7 @@ void FriendCore::reset(const FriendCore &contact) {
}
QString FriendCore::getDisplayName() const {
return !mFullName.isEmpty() ? mFullName : mGivenName + " " + mFamilyName;
}
void FriendCore::setDisplayName(const QString &name) {
if (mFullName != name) {
mFullName = name;
emit displayNameChanged();
setIsSaved(false);
}
return mGivenName + " " + mFamilyName;
}
QString FriendCore::getGivenName() const {
@ -261,7 +252,6 @@ void FriendCore::setGivenName(const QString &name) {
if (mGivenName != name) {
mGivenName = name;
emit givenNameChanged(name);
emit displayNameChanged();
setIsSaved(false);
}
}
@ -298,7 +288,6 @@ void FriendCore::setFamilyName(const QString &name) {
if (mFamilyName != name) {
mFamilyName = name;
emit familyNameChanged(name);
emit displayNameChanged();
setIsSaved(false);
}
}
@ -518,9 +507,7 @@ void FriendCore::writeIntoModel(std::shared_ptr<FriendModel> model) const {
mustBeInLinphoneThread(QString("[") + gClassName + "] " + Q_FUNC_INFO);
model->getFriend()->edit();
// needed to create the vcard if not created yet
model->setName(!mFullName.isEmpty()
? mFullName
: mGivenName + (mFamilyName.isEmpty() || mGivenName.isEmpty() ? "" : " ") + mFamilyName);
model->setName(mGivenName + (mFamilyName.isEmpty() || mGivenName.isEmpty() ? "" : " ") + mFamilyName);
auto core = CoreModel::getInstance()->getCore();
std::list<std::shared_ptr<linphone::Address>> addresses;

View file

@ -57,7 +57,7 @@ class FriendCore : public QObject, public AbstractObject {
Q_PROPERTY(int verifiedDeviceCount MEMBER mVerifiedDeviceCount NOTIFY verifiedDevicesChanged)
Q_PROPERTY(QString givenName READ getGivenName WRITE setGivenName NOTIFY givenNameChanged)
Q_PROPERTY(QString familyName READ getFamilyName WRITE setFamilyName NOTIFY familyNameChanged)
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString organization READ getOrganization WRITE setOrganization NOTIFY organizationChanged)
Q_PROPERTY(QString job READ getJob WRITE setJob NOTIFY jobChanged)
Q_PROPERTY(QString defaultAddress READ getDefaultAddress WRITE setDefaultAddress NOTIFY defaultAddressChanged)
@ -178,7 +178,6 @@ protected:
QDateTime mPresenceTimestamp;
QString mGivenName;
QString mFamilyName;
QString mFullName;
QString mOrganization;
QString mJob;
bool mStarred;

View file

@ -112,8 +112,15 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
} else if (auto address = it->getAddress()) {
auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
contact = FriendCore::create(linphoneFriend);
contact->setDisplayName(Utils::coreStringToAppString(address->getDisplayName()));
contact->setGivenName(Utils::coreStringToAppString(address->getUsername()));
auto displayname = Utils::coreStringToAppString(address->getDisplayName());
auto splitted = displayname.split(" ");
if (splitted.size() > 0) {
contact->setGivenName(splitted[0]);
splitted.removeFirst();
contact->setFamilyName(splitted.join(" "));
} else {
contact->setGivenName(Utils::coreStringToAppString(address->getUsername()));
}
contact->appendAddress(Utils::coreStringToAppString(address->asStringUriOnly()));
contacts->append(contact);
} else if (!it->getPhoneNumber().empty()) {

View file

@ -79,7 +79,7 @@ void ConferenceInfoModel::setConferenceScheduler(const std::shared_ptr<Conferenc
QDateTime ConferenceInfoModel::getDateTime() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000, Qt::LocalTime);
return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000);
}
int ConferenceInfoModel::getDuration() const {

View file

@ -12,7 +12,7 @@ FocusScope{
property alias errorTextItem: errorText
property alias errorMessage: errorText.text
property bool enableErrorText: false
property bool errorTextVisible: errorText.text.length > 0
property bool errorTextVisible: errorText.isVisible
implicitHeight: layout.implicitHeight
function clearErrorText() {

View file

@ -25,7 +25,7 @@ ListView {
property bool initialHeadersVisible: true
property bool displayNameCapitalization: true
property bool showFavoritesOnly: false
property bool showDefaultAddress: true
property bool showDefaultAddress: false
property bool showLdapContacts: false
property bool searchOnInitialization: false
@ -203,10 +203,11 @@ ListView {
Layout.fillWidth: true
}
Text {
Layout.topMargin: 2 * DefaultStyle.dp
maximumLineCount: 1
visible: mainItem.showDefaultAddress
text: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(modelData.core.defaultAddress) : modelData.core.defaultAddress
Layout.fillWidth: true
Layout.topMargin: 2 * DefaultStyle.dp
font {
weight: 300 * DefaultStyle.dp
pixelSize: 12 * DefaultStyle.dp
@ -244,8 +245,8 @@ ListView {
icon.width: 24 * DefaultStyle.dp
icon.height: 24 * DefaultStyle.dp
icon.source: AppIcons.phone
contentImageColor: DefaultStyle.main2_600
focus: visible
contentImageColor: DefaultStyle.main2_500main
background: Rectangle {
anchors.fill: parent
radius: 40 * DefaultStyle.dp

View file

@ -7,7 +7,7 @@ import Linphone
Text {
id: mainItem
color: DefaultStyle.danger_500main
visible: text.length > 0
property bool isVisible: text.length > 0
function clear() {
autoHideErrorMessage.stop()
text = ""

View file

@ -19,7 +19,7 @@ ColumnLayout {
id: usernameEdit
Layout.preferredWidth: 360 * DefaultStyle.dp
Layout.preferredHeight: 49 * DefaultStyle.dp
isError: username.errorTextVisible || errorText.visible
isError: username.errorTextVisible || (errorText.isVisible && text.length > 0)
}
}
Item {
@ -34,7 +34,7 @@ ColumnLayout {
id: passwordEdit
Layout.preferredWidth: 360 * DefaultStyle.dp
Layout.preferredHeight: 49 * DefaultStyle.dp
isError: password.errorTextVisible || errorText.visible
isError: password.errorTextVisible || (errorText.isVisible && text.length > 0)
hidden: true
}
TemporaryText {
@ -43,7 +43,8 @@ ColumnLayout {
Connections {
target: LoginPageCpp
function onErrorMessageChanged() {
errorText.setText(LoginPageCpp.errorMessage)
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
errorText.setText(LoginPageCpp.errorMessage)
}
function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {

View file

@ -163,6 +163,7 @@ FocusScope {
Layout.preferredHeight: contentHeight
Control.ScrollBar.vertical.visible: false
contactMenuVisible: false
searchOnInitialization: true
searchBarText: searchBar.text
onContactClicked: (contact) => {
mainItem.contactClicked(contact)

View file

@ -72,9 +72,11 @@ MainRightPanel {
button.text: mainItem.saveButtonText
button.onClicked: {
if (contact.core.givenName.length === 0 || (addressesList.count === 0 && phoneNumberList.count === 0)) {
if (contact.core.givenName.length === 0) givenName.errorMessage = qsTr("Veuillez saisir un prénom")
if (addressesList.count === 0 && phoneNumberList.count === 0) addressesErrorText.text = qsTr("Veuillez saisir une adresse ou un numéro de téléphone")
if (contact.core.givenName.length === 0) {
givenName.errorMessage = qsTr("Veuillez saisir un prénom")
return
} else if (addressesList.count === 0 && phoneNumberList.count === 0) {
addressesErrorText.setText(qsTr("Veuillez saisir une adresse ou un numéro de téléphone"))
return
}
mainItem.contact.core.save()
@ -135,11 +137,12 @@ MainRightPanel {
content: Flickable {
id: editionLayout
contentWidth: 421 * DefaultStyle.dp
contentY: 0
function ensureVisible(r) {
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height+content.spacing)
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
@ -162,7 +165,9 @@ MainRightPanel {
id: givenNameEdit
Layout.preferredHeight: 49 * DefaultStyle.dp
initialText: contact.core.givenName
onTextEdited: contact.core.givenName = text
onTextChanged: {
contact.core.givenName = givenNameEdit.text
}
backgroundColor: DefaultStyle.grey_0
backgroundBorderColor: givenName.errorTextVisible ? DefaultStyle.danger_500main : DefaultStyle.grey_200
KeyNavigation.up: editButton.visible ? editButton : addPictureButton
@ -175,7 +180,7 @@ MainRightPanel {
contentItem: TextField {
id: nameTextField
initialText: contact.core.familyName
onTextEdited: contact.core.familyName = text
onEditingFinished: contact.core.familyName = text
backgroundColor: DefaultStyle.grey_0
KeyNavigation.up: givenNameEdit
KeyNavigation.down: companyTextField
@ -187,7 +192,7 @@ MainRightPanel {
contentItem: TextField {
id: companyTextField
initialText: contact.core.organization
onTextEdited: contact.core.organization = text
onEditingFinished: contact.core.organization = text
backgroundColor: DefaultStyle.grey_0
KeyNavigation.up: nameTextField
KeyNavigation.down: jobTextField
@ -199,7 +204,7 @@ MainRightPanel {
contentItem: TextField {
id: jobTextField
initialText: contact.core.job
onTextEdited: contact.core.job = text
onEditingFinished: contact.core.job = text
backgroundColor: DefaultStyle.grey_0
KeyNavigation.up: companyTextField
Keys.onPressed: (event) => {
@ -274,7 +279,7 @@ MainRightPanel {
FormItemLayout {
label: qsTr("Adresse SIP")
Layout.fillWidth: true
onYChanged: editionLayout.ensureVisible(this)
// onYChanged: editionLayout.ensureVisible(this)
contentItem: TextField {
id: newAddressTextField
backgroundColor: DefaultStyle.grey_0
@ -294,8 +299,9 @@ MainRightPanel {
}
}
onEditingFinished: {
mainItem.contact.core.appendAddress(text)
if (text.length > 0) mainItem.contact.core.appendAddress(text)
newAddressTextField.clear()
editionLayout.ensureVisible(this)
}
}
}
@ -359,7 +365,7 @@ MainRightPanel {
id: phoneNumberInput
Layout.fillWidth: true
label: qsTr("Phone")
onYChanged: editionLayout.ensureVisible(this)
// onYChanged: editionLayout.ensureVisible(this)
contentItem: TextField {
id: phoneNumberInputTextField
backgroundColor: DefaultStyle.grey_0
@ -380,7 +386,8 @@ MainRightPanel {
}
onEditingFinished: {
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(phoneNumberInput.label, text)
text = ""
phoneNumberInputTextField.clear()
editionLayout.ensureVisible(this)
}
}
}
@ -389,7 +396,7 @@ MainRightPanel {
Layout.fillWidth: true
wrapMode: Text.WordWrap
elide: Text.ElideRight
onTextChanged: editionLayout.ensureVisible(this)
onTextChanged: if(text.length > 0) editionLayout.ensureVisible(this)
}
Item{Layout.fillHeight: true}
}

View file

@ -208,7 +208,7 @@ LoginLayout {
Layout.fillWidth: true
contentItem: TextField {
id: usernameEdit
isError: username.errorTextVisible
isError: username.errorTextVisible || errorText.isVisible
Layout.preferredWidth: 360 * DefaultStyle.dp
KeyNavigation.down: passwordEdit
}
@ -221,7 +221,7 @@ LoginLayout {
Layout.fillWidth: true
contentItem: TextField {
id: passwordEdit
isError: password.errorTextVisible
isError: password.errorTextVisible || errorText.isVisible
hidden: true
Layout.preferredWidth: 360 * DefaultStyle.dp
KeyNavigation.up: usernameEdit
@ -287,7 +287,7 @@ LoginLayout {
Connections {
target: LoginPageCpp
function onErrorMessageChanged(error) {
errorText.text = error
errorText.setText(error)
}
function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
@ -345,7 +345,7 @@ LoginLayout {
username.errorMessage = ""
password.errorMessage = ""
domain.errorMessage = ""
errorText.text = ""
errorText.clear()
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) {
if (usernameEdit.text.length == 0)

View file

@ -137,6 +137,7 @@ FocusScope{
contactMenuVisible: false
confInfoGui: mainItem.conferenceInfoGui
searchBarText: searchbar.text
searchOnInitialization: true
onContactAddedToSelection: (address) => {
suggestionList.addContactToSelection(address)
}

View file

@ -17,6 +17,7 @@ FocusScope {
ColumnLayout {
id: formLayout
spacing: 16 * DefaultStyle.dp
anchors.fill: parent
Connections {
target: mainItem.conferenceInfoGui.core
function onSchedulerStateChanged() {
@ -153,7 +154,6 @@ FocusScope {
TimeComboBox {
id: startHour
indicator.visible: mainItem.isCreation
// Layout.fillWidth: true
Layout.preferredWidth: 94 * DefaultStyle.dp
Layout.preferredHeight: 30 * DefaultStyle.dp
background.visible: mainItem.isCreation
@ -196,7 +196,7 @@ FocusScope {
ComboBox {
id: timeZoneCbox
Layout.preferredWidth: 307 * DefaultStyle.dp
Layout.fillWidth: true
Layout.preferredHeight: 30 * DefaultStyle.dp
hoverEnabled: true
oneLine: true

View file

@ -21,11 +21,11 @@ LoginLayout {
else if (field == "password") pwdItem.errorMessage = errorMessage
else if (field == "phone") phoneNumberInput.errorMessage = errorMessage
else if (field == "email") emailItem.errorMessage = errorMessage
else otherErrorText.text = errorMessage
else otherErrorText.setText(errorMessage)
}
function onRegisterNewAccountFailed(errorMessage) {
console.log("register failed", errorMessage)
otherErrorText.text = errorMessage
otherErrorText.setText(errorMessage)
}
}

View file

@ -55,7 +55,7 @@ AbstractMainPage {
onNoItemButtonPressed: goToNewCall()
showDefaultItem: listStackView.currentItem && listStackView.currentItem.listView && listStackView.currentItem.listView.count === 0
showDefaultItem: listStackView.currentItem && listStackView.currentItem.objectName == "historyListItem" && listStackView.currentItem.listView.count === 0
function goToNewCall() {
if (listStackView.currentItem && listStackView.currentItem.objectName != "newCallItem") listStackView.push(newCallItem)
@ -185,6 +185,7 @@ AbstractMainPage {
Layout.rightMargin: 39 * DefaultStyle.dp
icon.width: 28 * DefaultStyle.dp
icon.height: 28 * DefaultStyle.dp
contentImageColor: DefaultStyle.main2_600
KeyNavigation.left: removeHistory
KeyNavigation.down: listStackView
onClicked: {
@ -199,7 +200,7 @@ AbstractMainPage {
id: historyListItem
FocusScope{
objectName: "historyListItem"
property var listView: historyListView
property alias listView: historyListView
Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle
ColumnLayout {
anchors.fill: parent
@ -231,7 +232,7 @@ AbstractMainPage {
background: Item{}
contentItem: ColumnLayout {
Text {
visible: historyListView.count === 0 || searchBar.text.length != 0
visible: historyListView.count === 0
Layout.alignment: Qt.AlignHCenter
text: qsTr("Aucun appel%1").arg(searchBar.text.length != 0 ? " correspondant" : "")
font {
@ -362,6 +363,7 @@ AbstractMainPage {
Layout.preferredHeight: 24 * DefaultStyle.dp
icon.width: 24 * DefaultStyle.dp
icon.height: 24 * DefaultStyle.dp
contentImageColor: DefaultStyle.main2_600
focus: true
activeFocusOnTab: false
onClicked: {

View file

@ -52,7 +52,7 @@ AbstractMainPage {
// rightPanelStackView.initialItem: contactDetail
showDefaultItem: rightPanelStackView.depth == 0 && contactList.count === 0 && searchBar.text.length === 0
showDefaultItem: rightPanelStackView.depth == 0 && leftPanelNoItemText.visible && searchBar.text.length === 0
MagicSearchProxy {
id: allFriends
@ -236,7 +236,8 @@ AbstractMainPage {
width: parent.width
spacing: 15 * DefaultStyle.dp
Text {
visible: contactList.count === 0 || searchBar.text.length != 0
id: leftPanelNoItemText
visible: contactList.count === 0
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 137 * DefaultStyle.dp
text: qsTr("Aucun contact%1").arg(searchBar.text.length !== 0 ? " correspondant" : "")

View file

@ -175,7 +175,7 @@ AbstractMainPage {
}
}
Text {
visible: conferenceList.count === 0 || searchBar.text.length != 0
visible: conferenceList.count === 0
Layout.topMargin: 137 * DefaultStyle.dp
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
@ -191,7 +191,6 @@ AbstractMainPage {
Layout.topMargin: 38 * DefaultStyle.dp - 24 * DefaultStyle.dp
Layout.fillWidth: true
Layout.fillHeight: true
implicitHeight: contentHeight
hoverEnabled: mainItem.leftPanelEnabled
highlightFollowsCurrentItem: true
preferredHighlightBegin: height/2 - 10
@ -343,14 +342,14 @@ AbstractMainPage {
id: editFocusScope
property bool isCreation
property ConferenceInfoGui conferenceInfoGui
width: parent?.width
width: overridenRightPanelStackView.width
height: editLayout.implicitHeight
ColumnLayout {
id: editLayout
anchors.fill: parent
anchors.topMargin: 58 * DefaultStyle.dp
spacing: 0
Section {
Layout.topMargin: 58 * DefaultStyle.dp
content: RowLayout {
spacing: 10 * DefaultStyle.dp
Button {
@ -420,6 +419,7 @@ AbstractMainPage {
property bool isCreation
isCreation: editFocusScope.isCreation
conferenceInfoGui: editFocusScope.conferenceInfoGui
Layout.fillWidth: true
Connections {
target: conferenceEdit.conferenceInfoGui ? conferenceEdit.conferenceInfoGui.core : null
function onConferenceSchedulerStateChanged() {
@ -464,6 +464,7 @@ AbstractMainPage {
}
}
}
Item { Layout.fillHeight: true}
}
}
}
@ -551,10 +552,10 @@ AbstractMainPage {
ColumnLayout {
id: meetingDetailsLayout
anchors.fill: parent
anchors.topMargin: 58 * DefaultStyle.dp
visible: mainItem.selectedConference
spacing: 25 * DefaultStyle.dp
Section {
Layout.topMargin: 58 * DefaultStyle.dp
visible: mainItem.selectedConference
content: RowLayout {
spacing: 8 * DefaultStyle.dp