Compare commits

...

14 Commits

Author SHA1 Message Date
Nicolas Fella
488b76d27b Enable color scheme switching on Android 2023-09-12 18:08:29 +02:00
l10n daemon script
cbab810a2e GIT_SILENT Sync po/docbooks with svn 2023-09-12 01:47:54 +00:00
Tobias Fella
e78dfaec34 Use view background color for SpaceDrawer 2023-09-11 20:20:49 +00:00
ivan tkachenko
3cfa773820 Settings: Port to AvatarButton and fix OpenFileDialog lifespan
The dialog won't show again after being closed first time, so we need
to dynamically destroy it on both accept and reject. It helps clear out
any state on its way.
2023-09-11 22:47:33 +03:00
Tobias Fella
94c0e8b6cd Port ChatBar actions to Button
Cleans up the code and improves accessibility
2023-09-11 19:23:13 +00:00
Tobias Fella
35b1f24cb7 Fix roomlist when switching accounts
Fixes #605
2023-09-11 19:03:30 +00:00
Tobias Fella
de3072125e Change all remaining QML file ids to "root" 2023-09-11 20:47:32 +02:00
Tobias Fella
f7d2ffac66 Move Controller::createRoom and Controller::createSpace to NeoChatConnection 2023-09-11 17:55:52 +00:00
James Graham
ff0990bb7c Emit Room Selected from JoinRoomPage
Change the `JoinRoomPage` so that it emits a `roomSelected` signal with the selected delegate's info instead of calling the functions to join or enter the room itself. This is so that the `JoinRoomPage` can be used for other purposes like selecting an existing child to add to a space.
2023-09-11 17:16:12 +00:00
James Graham
8285961c42 Restore compact mode background
Restore compact mode using the darker/lighter depending on color scheme background (i.e. the same as the bubble background) it broke somewhere in the refactor of roompage
2023-09-11 07:19:32 +00:00
James Graham
cd39d5b129 Shutup LinkPreviewDelegate
Make sure that the console isn't spammed having `linkpreviewer` undefined in `LinkPreviewDelegate`, even though it shouldn't ever be and I couldn't find any case where it was but my console was still intermittently getting spammed.
2023-09-11 06:27:13 +00:00
l10n daemon script
83b3fefbf5 GIT_SILENT Sync po/docbooks with svn 2023-09-11 01:48:45 +00:00
l10n daemon script
3718bd716a GIT_SILENT made messages (after extraction) 2023-09-11 00:46:51 +00:00
Akseli Lahtinen
a18257ee17 Taskbar badge highlight counter
Instead of the taskbar badge showing count for all notifications, only show the count for total highlights.
2023-09-10 20:57:39 +00:00
96 changed files with 8304 additions and 8193 deletions

View File

@@ -13,6 +13,7 @@ Dependencies:
'frameworks/kitemmodels': '@stable'
'frameworks/kquickcharts': '@stable'
'frameworks/knotifications': '@stable'
'frameworks/kconfigwidgets': '@stable'
'libraries/kquickimageeditor': '@stable'
'frameworks/sonnet': '@stable'
'libraries/kirigami-addons': '@latest'
@@ -25,7 +26,6 @@ Dependencies:
'frameworks/qqc2-desktop-style': '@stable'
'frameworks/kio': '@stable'
'frameworks/kwindowsystem': '@stable'
'frameworks/kconfigwidgets': '@stable'
- 'on': ['Linux/Qt5', 'FreeBSD/Qt5']
'require':
'frameworks/kdbusaddons': '@stable'

View File

@@ -82,7 +82,7 @@ set_package_properties(Qt${QT_MAJOR_VERSION} PROPERTIES
TYPE REQUIRED
PURPOSE "Basic application components"
)
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet ItemModels)
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet ItemModels ConfigWidgets)
set_package_properties(KF${QT_MAJOR_VERSION} PROPERTIES
TYPE REQUIRED
PURPOSE "Basic application components"
@@ -105,7 +105,7 @@ if(ANDROID)
)
else()
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} COMPONENTS Widgets)
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle ConfigWidgets KIO WindowSystem)
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem)
set_package_properties(KF${QT_MAJOR_VERSION}QQC2DesktopStyle PROPERTIES
TYPE RUNTIME
)

View File

@@ -159,6 +159,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">투표 - MSC3381</li>
<li xml:lang="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pl">Ankiety - MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="sv">Polls - MSC3381</li>
@@ -183,6 +184,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">스티커 팩 - MSC2545</li>
<li xml:lang="nl">Sticker Packs - MSC2545</li>
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="sv">Sticker Packs - MSC2545</li>
@@ -207,6 +209,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
<li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="sv">Location Events - MSC3488</li>
@@ -294,6 +297,7 @@ to provide a convergent experience across multiple platforms.</p>
<caption xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</caption>
<caption xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</caption>
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
@@ -319,6 +323,7 @@ to provide a convergent experience across multiple platforms.</p>
<caption xml:lang="ko">로그인 화면</caption>
<caption xml:lang="nl">Aanmeldscherm</caption>
<caption xml:lang="nn">Innloggingsbilete</caption>
<caption xml:lang="pl">Ekran logowania</caption>
<caption xml:lang="pt">Ecrã de autenticação</caption>
<caption xml:lang="sl">Prijavni zaslon</caption>
<caption xml:lang="sv">Inloggningsfönster</caption>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -136,6 +136,7 @@ add_library(neochat STATIC
mediasizehelper.h
eventhandler.cpp
enums/delegatetype.h
colorschemer.cpp
)
ecm_qt_declare_logging_category(neochat
@@ -175,7 +176,6 @@ ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID)
target_sources(neochat PRIVATE colorschemer.cpp colorschemer.h)
if (NOT WIN32 AND NOT APPLE)
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
if(QT_MAJOR_VERSION STREQUAL "6")
@@ -184,8 +184,7 @@ if(NOT ANDROID)
else()
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
endif()
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem)
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::WindowSystem)
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
endif()
@@ -199,7 +198,7 @@ else()
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark QCoro::Core)
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels KF${QT_MAJOR_VERSION}::ConfigWidgets Quotient${QUOTIENT_SUFFIX} cmark::cmark QCoro::Core)
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)

View File

@@ -371,36 +371,6 @@ void Controller::saveWindowGeometry()
WindowController::instance().saveGeometry();
}
void Controller::createRoom(const QString &name, const QString &topic)
{
auto createRoomJob = m_connection->createRoom(Connection::PublishRoom, QString(), name, topic, QStringList());
connect(createRoomJob, &CreateRoomJob::failure, this, [this, createRoomJob] {
Q_EMIT errorOccured(i18n("Room creation failed: %1", createRoomJob->errorString()));
});
connectSingleShot(this, &Controller::roomAdded, &RoomManager::instance(), &RoomManager::enterRoom, Qt::QueuedConnection);
}
void Controller::createSpace(const QString &name, const QString &topic)
{
auto createRoomJob = m_connection->createRoom(Connection::UnpublishRoom,
{},
name,
topic,
QStringList(),
{},
{},
false,
{},
{},
QJsonObject{
{"type"_ls, "m.space"_ls},
});
connect(createRoomJob, &CreateRoomJob::failure, this, [this, createRoomJob] {
Q_EMIT errorOccured(i18n("Space creation failed: %1", createRoomJob->errorString()));
});
connectSingleShot(this, &Controller::roomAdded, &RoomManager::instance(), &RoomManager::enterRoom, Qt::QueuedConnection);
}
bool Controller::isOnline() const
{
return m_isOnline;

View File

@@ -113,16 +113,6 @@ public:
*/
bool saveAccessTokenToKeyChain(const Quotient::AccountSettings &account, const QByteArray &accessToken);
/**
* @brief Create new room for a group chat.
*/
Q_INVOKABLE void createRoom(const QString &name, const QString &topic);
/**
* @brief Create new space.
*/
Q_INVOKABLE void createSpace(const QString &name, const QString &topic);
/**
* @brief Join a room.
*/
@@ -216,7 +206,6 @@ Q_SIGNALS:
void userConsentRequired(QUrl url);
void isOnlineChanged(bool isOnline);
void activeConnectionIndexChanged();
void roomAdded(NeoChatRoom *room);
public Q_SLOTS:
void saveWindowGeometry();

View File

@@ -93,4 +93,9 @@ void LinkPreviewer::loadUrlPreview()
}
}
bool LinkPreviewer::empty() const
{
return m_url.isEmpty();
}
#include "moc_linkpreviewer.cpp"

View File

@@ -44,6 +44,13 @@ class LinkPreviewer : public QObject
*/
Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
/**
* @brief Whether the there is a link to preview.
*
* A linkPreviwer is empty if the URL is empty.
*/
Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged)
public:
explicit LinkPreviewer(QObject *parent = nullptr, const NeoChatRoom *room = nullptr, const QUrl &url = {});
@@ -53,6 +60,7 @@ public:
[[nodiscard]] QString title() const;
[[nodiscard]] QString description() const;
[[nodiscard]] QUrl imageSource() const;
[[nodiscard]] bool empty() const;
private:
const NeoChatRoom *m_currentRoom = nullptr;
@@ -71,5 +79,6 @@ Q_SIGNALS:
void descriptionChanged();
void imageSourceChanged();
void urlChanged();
void emptyChanged();
};
Q_DECLARE_METATYPE(LinkPreviewer *)

View File

@@ -45,6 +45,7 @@
#include "blurhashimageprovider.h"
#include "chatdocumenthandler.h"
#include "clipboard.h"
#include "colorschemer.h"
#include "controller.h"
#include "delegatesizehelper.h"
#include "enums/delegatetype.h"
@@ -91,9 +92,6 @@
#include "urlhelper.h"
#include "windowcontroller.h"
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
#include "models/completionmodel.h"
#include "models/statemodel.h"
@@ -228,13 +226,11 @@ int main(int argc, char *argv[])
Login *login = new Login();
UrlHelper urlHelper;
#ifdef HAVE_COLORSCHEME
ColorSchemer colorScheme;
qmlRegisterSingletonInstance<ColorSchemer>("org.kde.neochat", 1, 0, "ColorSchemer", &colorScheme);
if (!config->colorScheme().isEmpty()) {
colorScheme.apply(config->colorScheme());
}
#endif
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Controller", &Controller::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "NotificationsManager", &NotificationsManager::instance());

View File

@@ -36,13 +36,13 @@ RoomListModel::RoomListModel(QObject *parent)
m_categoryVisibility[collapsedSection] = false;
}
connect(this, &RoomListModel::notificationCountChanged, this, [this]() {
connect(this, &RoomListModel::highlightCountChanged, this, [this]() {
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#ifndef Q_OS_ANDROID
// copied from Telegram desktop
const auto launcherUrl = "application://org.kde.neochat.desktop"_ls;
// Gnome requires that count is a 64bit integer
const qint64 counterSlice = std::min(m_notificationCount, 9999);
const qint64 counterSlice = std::min(m_highlightCount, 9999);
QVariantMap dbusUnityProperties;
if (counterSlice > 0) {
@@ -59,7 +59,7 @@ RoomListModel::RoomListModel(QObject *parent)
QDBusConnection::sessionBus().send(signal);
#endif // Q_OS_ANDROID
#else
qGuiApp->setBadgeNumber(m_notificationCount);
qGuiApp->setBadgeNumber(m_highlightCount);
#endif // QT_VERSION_CHECK(6, 6, 0)
});
connect(&SpaceHierarchyCache::instance(), &SpaceHierarchyCache::spaceHierarchyChanged, this, [this]() {
@@ -144,7 +144,6 @@ void RoomListModel::doAddRoom(Room *r)
m_rooms.append(room);
connectRoomSignals(room);
Q_EMIT roomAdded(room);
Q_EMIT Controller::instance().roomAdded(room);
} else {
qCritical() << "Attempt to add nullptr to the room list";
Q_ASSERT(false);
@@ -162,6 +161,9 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
connect(room, &Room::notificationCountChanged, this, [this, room] {
refresh(room);
});
connect(room, &Room::highlightCountChanged, this, [this, room] {
refresh(room);
});
connect(room, &Room::avatarChanged, this, [this, room] {
refresh(room, {AvatarRole});
});
@@ -178,6 +180,7 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
refresh(room, {LastEventRole, SubtitleTextRole});
});
connect(room, &Room::unreadStatsChanged, this, &RoomListModel::refreshNotificationCount);
connect(room, &Room::highlightCountChanged, this, &RoomListModel::refreshHighlightCount);
}
int RoomListModel::notificationCount() const
@@ -185,6 +188,11 @@ int RoomListModel::notificationCount() const
return m_notificationCount;
}
int RoomListModel::highlightCount() const
{
return m_highlightCount;
}
void RoomListModel::refreshNotificationCount()
{
int count = 0;
@@ -198,6 +206,19 @@ void RoomListModel::refreshNotificationCount()
Q_EMIT notificationCountChanged();
}
void RoomListModel::refreshHighlightCount()
{
int count = 0;
for (auto room : std::as_const(m_rooms)) {
count += room->highlightCount();
}
if (m_highlightCount == count) {
return;
}
m_highlightCount = count;
Q_EMIT highlightCountChanged();
}
void RoomListModel::updateRoom(Room *room, Room *prev)
{
// There are two cases when this method is called:

View File

@@ -85,6 +85,7 @@ public:
void setConnection(Quotient::Connection *connection);
[[nodiscard]] int notificationCount() const;
[[nodiscard]] int highlightCount() const;
/**
* @brief Get the given role value at the given index.
@@ -155,6 +156,7 @@ private Q_SLOTS:
void deleteRoom(Quotient::Room *room);
void refresh(NeoChatRoom *room, const QVector<int> &roles = {});
void refreshNotificationCount();
void refreshHighlightCount();
private:
Quotient::Connection *m_connection = nullptr;
@@ -163,6 +165,7 @@ private:
QMap<int, bool> m_categoryVisibility;
int m_notificationCount = 0;
int m_highlightCount = 0;
QString m_activeSpaceId;
void connectRoomSignals(NeoChatRoom *room);
@@ -170,6 +173,7 @@ private:
Q_SIGNALS:
void connectionChanged();
void notificationCountChanged();
void highlightCountChanged();
void roomAdded(NeoChatRoom *_t1);
};

View File

@@ -8,6 +8,7 @@
#include "controller.h"
#include "jobs/neochatchangepasswordjob.h"
#include "jobs/neochatdeactivateaccountjob.h"
#include "roommanager.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <qt5keychain/keychain.h>
@@ -15,8 +16,11 @@
#include <qt6keychain/keychain.h>
#endif
#include <KLocalizedString>
#include <Quotient/csapi/content-repo.h>
#include <Quotient/csapi/profile.h>
#include <Quotient/qt_connection_util.h>
#include <Quotient/settings.h>
#include <Quotient/user.h>
@@ -156,4 +160,26 @@ void NeoChatConnection::deactivateAccount(const QString &password)
});
}
void NeoChatConnection::createRoom(const QString &name, const QString &topic)
{
const auto job = Connection::createRoom(Connection::PublishRoom, {}, name, topic, {});
connect(job, &CreateRoomJob::failure, this, [this, job] {
Q_EMIT Controller::instance().errorOccured(i18n("Room creation failed: %1", job->errorString()));
});
connectSingleShot(this, &Connection::newRoom, this, [](Room *room) {
RoomManager::instance().enterRoom(dynamic_cast<NeoChatRoom *>(room));
});
}
void NeoChatConnection::createSpace(const QString &name, const QString &topic)
{
const auto job = Connection::createRoom(Connection::UnpublishRoom, {}, name, topic, {}, {}, {}, false, {}, {}, QJsonObject{{"type"_ls, "m.space"_ls}});
connect(job, &CreateRoomJob::failure, this, [this, job] {
Q_EMIT Controller::instance().errorOccured(i18n("Space creation failed: %1", job->errorString()));
});
connectSingleShot(this, &Connection::newRoom, this, [](Room *room) {
RoomManager::instance().enterRoom(dynamic_cast<NeoChatRoom *>(room));
});
}
#include "moc_neochatconnection.cpp"

View File

@@ -48,6 +48,16 @@ public:
Q_INVOKABLE void deactivateAccount(const QString &password);
/**
* @brief Create new room for a group chat.
*/
Q_INVOKABLE void createRoom(const QString &name, const QString &topic);
/**
* @brief Create new space.
*/
Q_INVOKABLE void createSpace(const QString &name, const QString &topic);
Q_SIGNALS:
void labelChanged();
};

View File

@@ -357,38 +357,26 @@ QQC2.Control {
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
}
Row {
RowLayout {
id: actionsRow
padding: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
anchors.right: parent.right
property var requiredMargin: (root.width - chatBarSizeHelper.currentWidth) / 2 + Kirigami.Units.largeSpacing + (chatBarScrollView.QQC2.ScrollBar.vertical.visible && !(root.width > chatBarSizeHelper.currentWidth) ? Kirigami.Units.largeSpacing * 2.5 : 0)
anchors.bottom: parent.bottom
anchors.leftMargin: layoutDirection === Qt.RightToLeft ? requiredMargin : 0
anchors.rightMargin: layoutDirection === Qt.RightToLeft ? 0 : requiredMargin
anchors.bottom: parent.bottom
anchors.bottomMargin: Kirigami.Units.largeSpacing - 2
anchors.bottomMargin: Kirigami.Units.smallSpacing
spacing: 0
property var requiredMargin: (root.width - chatBarSizeHelper.currentWidth) / 2 + Kirigami.Units.largeSpacing + (chatBarScrollView.QQC2.ScrollBar.vertical.visible && !(root.width > chatBarSizeHelper.currentWidth) ? Kirigami.Units.largeSpacing * 2.5 : 0)
Repeater {
model: root.actions
Kirigami.Icon {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: Kirigami.Units.iconSizes.smallMedium
delegate: QQC2.ToolButton {
Layout.alignment: Qt.AlignVCenter
icon.name: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
onClicked: modelData.trigger()
source: modelData.isBusy ? "" : (modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source)
active: actionArea.containsPress
visible: modelData.visible
enabled: modelData.enabled
MouseArea {
id: actionArea
anchors.fill: parent
onClicked: modelData.trigger()
cursorShape: Qt.PointingHandCursor
}
QQC2.ToolTip.visible: modelData.tooltip !== "" && hoverHandler.hovered
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: modelData.tooltip
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
HoverHandler { id: hoverHandler }
PieProgressBar {
visible: modelData.isBusy

View File

@@ -14,7 +14,7 @@ import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
QQC2.Popup {
id: completionMenu
id: root
width: parent.width
visible: completions.count > 0
@@ -38,7 +38,7 @@ QQC2.Popup {
}
function complete() {
completionMenu.chatDocumentHandler.complete(completions.currentIndex)
root.chatDocumentHandler.complete(completions.currentIndex)
}
leftPadding: 0
@@ -52,7 +52,7 @@ QQC2.Popup {
id: completions
anchors.fill: parent
model: completionMenu.chatDocumentHandler.completionModel
model: root.chatDocumentHandler.completionModel
currentIndex: 0
keyNavigationWraps: true
highlightMoveDuration: 100
@@ -81,7 +81,7 @@ QQC2.Popup {
subtitleItem.textFormat: Text.PlainText
}
}
onClicked: completionMenu.chatDocumentHandler.complete(completionDelegate.index)
onClicked: root.chatDocumentHandler.complete(completionDelegate.index)
}
}

View File

@@ -6,15 +6,15 @@ import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.20 as Kirigami
QQC2.ItemDelegate {
id: emojiDelegate
id: root
property string name
property string emoji
property bool showTones: false
property bool isImage: false
QQC2.ToolTip.text: emojiDelegate.name
QQC2.ToolTip.visible: hovered && emojiDelegate.name !== ""
QQC2.ToolTip.text: root.name
QQC2.ToolTip.visible: hovered && root.name !== ""
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
leftInset: Kirigami.Units.smallSpacing
topInset: Kirigami.Units.smallSpacing
@@ -24,8 +24,8 @@ QQC2.ItemDelegate {
contentItem: Item {
Kirigami.Heading {
anchors.fill: parent
visible: !emojiDelegate.emoji.startsWith("image") && !emojiDelegate.isImage
text: emojiDelegate.emoji
visible: !root.emoji.startsWith("image") && !root.isImage
text: root.emoji
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: "emoji"
@@ -36,25 +36,25 @@ QQC2.ItemDelegate {
source: "arrow-down"
anchors.bottom: parent.bottom
anchors.right: parent.right
visible: emojiDelegate.showTones
visible: root.showTones
}
}
Image {
anchors.fill: parent
visible: emojiDelegate.emoji.startsWith("image") || emojiDelegate.isImage
source: visible ? emojiDelegate.emoji : ""
visible: root.emoji.startsWith("image") || root.isImage
source: visible ? root.emoji : ""
}
}
background: Rectangle {
color: emojiDelegate.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
color: root.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing
Rectangle {
radius: Kirigami.Units.smallSpacing
anchors.fill: parent
color: Kirigami.Theme.highlightColor
opacity: emojiDelegate.hovered && !emojiDelegate.pressed ? 0.2 : 0
opacity: root.hovered && !root.pressed ? 0.2 : 0
}
}
}

View File

@@ -7,7 +7,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
QQC2.ScrollView {
id: emojiGrid
id: root
property alias model: emojis.model
property alias count: emojis.count
@@ -40,10 +40,10 @@ QQC2.ScrollView {
}
onModelChanged: currentIndex = -1
cellWidth: emojis.width / emojiGrid.emojisPerRow
cellHeight: emojiGrid.targetIconSize
cellWidth: emojis.width / root.emojisPerRow
cellHeight: root.targetIconSize
KeyNavigation.up: emojiGrid.header
KeyNavigation.up: root.header
clip: true
@@ -56,14 +56,14 @@ QQC2.ScrollView {
width: emojis.cellWidth
height: emojis.cellHeight
isImage: emojiGrid.stickers
isImage: root.stickers
Keys.onEnterPressed: clicked()
Keys.onReturnPressed: clicked()
onClicked: {
if (emojiGrid.stickers) {
emojiGrid.stickerChosen(model.index)
if (root.stickers) {
root.stickerChosen(model.index)
}
emojiGrid.chosen(modelData.isCustom ? modelData.shortName : modelData.unicode)
root.chosen(modelData.isCustom ? modelData.shortName : modelData.unicode)
EmojiModel.emojiUsed(modelData)
}
Keys.onSpacePressed: pressAndHold()
@@ -71,7 +71,7 @@ QQC2.ScrollView {
if (EmojiModel.tones(modelData.shortName).length === 0) {
return;
}
let tones = tonesPopupComponent.createObject(emojiDelegate, {shortName: modelData.shortName, unicode: modelData.unicode, categoryIconSize: emojiGrid.targetIconSize})
let tones = tonesPopupComponent.createObject(emojiDelegate, {shortName: modelData.shortName, unicode: modelData.unicode, categoryIconSize: root.targetIconSize})
tones.open()
tones.forceActiveFocus()
}
@@ -80,14 +80,14 @@ QQC2.ScrollView {
Kirigami.PlaceholderMessage {
anchors.centerIn: parent
text: emojiGrid.stickers ? i18n("No stickers") : i18n("No emojis")
text: root.stickers ? i18n("No stickers") : i18n("No emojis")
visible: emojis.count === 0
}
}
Component {
id: tonesPopupComponent
EmojiTonesPicker {
onChosen: emojiGrid.chosen(emoji)
onChosen: root.chosen(emoji)
}
}
}

View File

@@ -8,7 +8,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
QQC2.Popup {
id: tones
id: root
signal chosen(string emoji)
@@ -20,14 +20,14 @@ QQC2.Popup {
required property string shortName
required property string unicode
required property int categoryIconSize
width: tones.categoryIconSize * tonesList.count + 2 * padding
height: tones.categoryIconSize + 2 * padding
width: root.categoryIconSize * tonesList.count + 2 * padding
height: root.categoryIconSize + 2 * padding
y: -height
padding: 2
modal: true
dim: true
clip: false
onOpened: x = Math.min(parent.mapFromGlobal(QQC2.Overlay.overlay.width - tones.width, 0).x, -(width - parent.width) / 2)
onOpened: x = Math.min(parent.mapFromGlobal(QQC2.Overlay.overlay.width - root.width, 0).x, -(width - parent.width) / 2)
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.mediumSpacing
@@ -47,7 +47,7 @@ QQC2.Popup {
width: parent.width
height: parent.height
orientation: Qt.Horizontal
model: EmojiModel.tones(tones.shortName)
model: EmojiModel.tones(root.shortName)
keyNavigationEnabled: true
keyNavigationWraps: true
@@ -57,15 +57,15 @@ QQC2.Popup {
emoji: modelData.unicode
name: modelData.shortName
width: tones.categoryIconSize
width: root.categoryIconSize
height: width
Keys.onEnterPressed: clicked()
Keys.onReturnPressed: clicked()
onClicked: {
tones.chosen(modelData.unicode)
root.chosen(modelData.unicode)
EmojiModel.emojiUsed(modelData)
tones.close()
root.close()
}
}
}

View File

@@ -8,7 +8,7 @@ import QtQuick.Particles 2.15
import org.kde.kirigami 2.15 as Kirigami
Item {
id: item
id: root
property bool enabled: false
property int effectInterval: Kirigami.Units.veryLongDuration*10;
property color darkSnowColor: "grey"
@@ -30,12 +30,12 @@ Item {
Timer {
id: confettiTimer
interval: item.effectInterval;
interval: root.effectInterval;
running: false;
repeat: false;
triggeredOnStart: true;
onTriggered: {
if (item.enabled) {
if (root.enabled) {
confettiSystem.running = !confettiSystem.running
}
}
@@ -92,12 +92,12 @@ Item {
Timer {
id: snowTimer
interval: item.effectInterval;
interval: root.effectInterval;
running: false;
repeat: false;
triggeredOnStart: true;
onTriggered: {
if (item.enabled) {
if (root.enabled) {
snowSystem.running = !snowSystem.running
}
}
@@ -127,7 +127,7 @@ Item {
width: 10
height: width
radius: width
color: item.isThemeDark ? "white" : darkSnowColor
color: root.isThemeDark ? "white" : darkSnowColor
scale: Math.random()
opacity: Math.random()
}
@@ -157,12 +157,12 @@ Item {
Timer {
id: fireworksTimer
interval: item.effectInterval;
interval: root.effectInterval;
running: false;
repeat: false;
triggeredOnStart: true;
onTriggered: {
if (item.enabled) {
if (root.enabled) {
fireworksInternalTimer.running = !fireworksInternalTimer.running
}
}
@@ -206,8 +206,8 @@ Item {
id: fireworksParticleA
system: fireworksSystem
source: "qrc:/glowdot.png"
alphaVariation: item.isThemeDark ? 0.1 : 0.1
alpha: item.isThemeDark ? 0.5 : 1
alphaVariation: root.isThemeDark ? 0.1 : 0.1
alpha: root.isThemeDark ? 0.5 : 1
groups: ["a"]
opacity: fireworksSystem.opacity
entryEffect: ImageParticle.Scale
@@ -217,9 +217,9 @@ Item {
ImageParticle {
system: fireworksSystem
source: "qrc:/glowdot.png"
color: item.isThemeDark ? "white" : "gold"
alphaVariation: item.isThemeDark ? 0.1 : 0.1
alpha: item.isThemeDark ? 0.5 : 1
color: root.isThemeDark ? "white" : "gold"
alphaVariation: root.isThemeDark ? 0.1 : 0.1
alpha: root.isThemeDark ? 0.5 : 1
groups: ["light"]
opacity: fireworksSystem.opacity
entryEffect: ImageParticle.Scale
@@ -230,8 +230,8 @@ Item {
id: fireworksParticleB
system: fireworksSystem
source: "qrc:/glowdot.png"
alphaVariation: item.isThemeDark ? 0.1 : 0.1
alpha: item.isThemeDark ? 0.5 : 1
alphaVariation: root.isThemeDark ? 0.1 : 0.1
alpha: root.isThemeDark ? 0.5 : 1
groups: ["b"]
opacity: fireworksSystem.opacity
entryEffect: ImageParticle.Scale
@@ -257,7 +257,7 @@ Item {
onTriggered: {
container.destroy();
var randomHue = Math.random()
var lightness = item.isThemeDark ? 0.8 : 0.7
var lightness = root.isThemeDark ? 0.8 : 0.7
fireworksParticleA.color = Qt.hsla(randomHue, 0.8, lightness, 1)
fireworksParticleB.color = Qt.hsla(1-randomHue, 0.8, lightness, 1)
}

View File

@@ -9,7 +9,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: locationsPage
id: root
required property var room
@@ -31,7 +31,7 @@ Kirigami.Page {
MapItemView {
model: LocationsModel {
id: locationsModel
room: locationsPage.room
room: root.room
}
delegate: LocationMapItem {
isLive: true
@@ -42,7 +42,7 @@ Kirigami.Page {
MapItemView {
model: LiveLocationsModel {
id: liveLocationsModel
room: locationsPage.room
room: root.room
}
delegate: LocationMapItem {}
}

View File

@@ -8,7 +8,7 @@ import QtQuick 2.15
import org.kde.kirigami 2.15 as Kirigami
Gradient {
id: gradient
id: root
orientation: Gradient.Horizontal
@@ -25,7 +25,7 @@ Gradient {
from: -2.0
to: 2.0
duration: 700
target: gradient
target: root
properties: "pos"
}
PauseAnimation {
@@ -33,7 +33,7 @@ Gradient {
}
}
GradientStop { position: gradient.pos-gradient.offset; color: gradient.translucent }
GradientStop { position: gradient.pos; color: gradient.bright }
GradientStop { position: gradient.pos+gradient.offset; color: gradient.translucent }
}
GradientStop { position: root.pos-root.offset; color: root.translucent }
GradientStop { position: root.pos; color: root.bright }
GradientStop { position: root.pos+root.offset; color: root.translucent }
}

View File

@@ -23,7 +23,7 @@ Loader {
* - description - the description of the URL preview.
* - imageSource - a source URL for the preview image.
*/
property var linkPreviewer
required property var linkPreviewer
/**
* @brief Standard height for the link preview.
@@ -39,7 +39,7 @@ Loader {
property bool indicatorEnabled: false
visible: active
sourceComponent: linkPreviewer.loaded ? linkPreviewComponent : loadingComponent
sourceComponent: linkPreviewer && linkPreviewer.loaded ? linkPreviewComponent : loadingComponent
Component {
id: linkPreviewComponent
@@ -61,10 +61,10 @@ Loader {
color: Kirigami.Theme.highlightColor
}
Image {
visible: linkPreviewer.imageSource
visible: root.linkPreviewer.imageSource
Layout.maximumHeight: root.defaultHeight
Layout.maximumWidth: root.defaultHeight
source: linkPreviewer.imageSource
source: root.linkPreviewer.imageSource
fillMode: Image.PreserveAspectFit
}
ColumnLayout {

View File

@@ -68,7 +68,7 @@ TimelineContainer {
}
LinkPreviewDelegate {
Layout.fillWidth: true
active: !currentRoom.usesEncryption && currentRoom.urlPreviewEnabled && Config.showLinkPreview && root.showLinkPreview
active: !currentRoom.usesEncryption && currentRoom.urlPreviewEnabled && Config.showLinkPreview && root.showLinkPreview && !root.linkPreview.empty
linkPreviewer: root.linkPreview
indicatorEnabled: root.isVisibleInTimeline()
}

View File

@@ -11,7 +11,8 @@ import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
QQC2.ItemDelegate {
id: readMarkerDelegate
id: root
padding: Kirigami.Units.largeSpacing
topInset: Kirigami.Units.largeSpacing
topPadding: Kirigami.Units.largeSpacing * 2
@@ -41,7 +42,7 @@ QQC2.ItemDelegate {
State {
name: "alignLeft"
AnchorChanges {
target: readMarkerDelegate
target: root
anchors.horizontalCenter: undefined
anchors.left: parent ? parent.left : undefined
}
@@ -49,7 +50,7 @@ QQC2.ItemDelegate {
State {
name: "alignCenter"
AnchorChanges {
target: readMarkerDelegate
target: root
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
anchors.left: undefined
}
@@ -72,7 +73,7 @@ QQC2.ItemDelegate {
background: Kirigami.ShadowedRectangle {
id: readMarkerBackground
color: {
if (readMarkerDelegate.isTemporaryHighlighted) {
if (root.isTemporaryHighlighted) {
return Kirigami.Theme.positiveBackgroundColor
} else {
return Kirigami.Theme.backgroundColor
@@ -80,7 +81,7 @@ QQC2.ItemDelegate {
}
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View
opacity: readMarkerDelegate.isTemporaryHighlighted ? 1 : 0.6
opacity: root.isTemporaryHighlighted ? 1 : 0.6
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)

View File

@@ -11,7 +11,7 @@ import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
QQC2.ItemDelegate {
id: sectionDelegate
id: root
property alias labelText: sectionLabel.text
property var maxWidth: Number.POSITIVE_INFINITY
@@ -44,6 +44,6 @@ QQC2.ItemDelegate {
background: Rectangle {
color: Config.blur ? "transparent" : Kirigami.Theme.backgroundColor
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: sectionDelegate.colorSet
Kirigami.Theme.colorSet: root.colorSet
}
}

View File

@@ -11,7 +11,7 @@ import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
QQC2.Control {
id: stateDelegate
id: root
readonly property bool sectionVisible: model.showSection
@@ -23,7 +23,7 @@ QQC2.Control {
State {
name: "alignLeft"
AnchorChanges {
target: stateDelegate
target: root
anchors.horizontalCenter: undefined
anchors.left: parent ? parent.left : undefined
}
@@ -31,7 +31,7 @@ QQC2.Control {
State {
name: "alignCenter"
AnchorChanges {
target: stateDelegate
target: root
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
anchors.left: undefined
}
@@ -62,6 +62,7 @@ QQC2.Control {
Layout.fillWidth: true
visible: sectionVisible
labelText: sectionVisible ? section : ""
colorSet: Config.compactLayout ? Kirigami.Theme.View : Kirigami.Theme.Window
}
RowLayout {
Layout.fillWidth: true
@@ -203,6 +204,6 @@ QQC2.Control {
endPercentWidth: Config.compactLayout ? 100 : 85
maxWidth: Config.compactLayout ? -1 : Kirigami.Units.gridUnit * 60
parentWidth: stateDelegate.parent ? stateDelegate.parent.width : 0
parentWidth: root.parent ? root.parent.width : 0
}
}

View File

@@ -116,6 +116,7 @@ QQC2.ScrollView {
z: 3
visible: !!messageListView.sectionBannerItem && messageListView.sectionBannerItem.ListView.section !== "" && !Config.blur
labelText: messageListView.sectionBannerItem ? messageListView.sectionBannerItem.ListView.section : ""
colorSet: Config.compactLayout ? Kirigami.Theme.View : Kirigami.Theme.Window
}
footerPositioning: ListView.OverlayHeader

View File

@@ -10,7 +10,7 @@ import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
QQC2.Dialog {
id: confirmEncryptionDialog
id: root
property NeoChatRoom room
@@ -31,15 +31,15 @@ QQC2.Dialog {
QQC2.Button {
text: i18n("Cancel")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
onClicked: confirmEncryptionDialog.close()
onClicked: root.close()
}
QQC2.Button {
text: i18n("Activate Encryption")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
onClicked: {
confirmEncryptionDialog.room.activateEncryption()
confirmEncryptionDialog.close();
root.room.activateEncryption()
root.close();
}
}
}

View File

@@ -12,6 +12,8 @@ FormCard.FormCardPage {
title: i18nc("@title", "Create a Room")
required property NeoChatConnection connection
Component.onCompleted: roomNameField.forceActiveFocus()
FormCard.FormHeader {
@@ -35,7 +37,7 @@ FormCard.FormCardPage {
text: i18nc("@action:button", "Ok")
enabled: roomNameField.text.length > 0
onClicked: {
Controller.createRoom(roomNameField.text, roomTopicField.text);
root.connection.createRoom(roomNameField.text, roomTopicField.text);
root.closeDialog()
}
}

View File

@@ -11,6 +11,8 @@ import org.kde.kirigamiaddons.formcard 1.0 as FormCard
FormCard.FormCardPage {
id: root
required property NeoChatConnection connection
title: i18n("Create a Space")
Kirigami.Theme.colorSet: Kirigami.Theme.Window
@@ -30,7 +32,7 @@ FormCard.FormCardPage {
FormCard.FormButtonDelegate {
text: i18n("Create space")
onClicked: {
Controller.createSpace(nameDelegate.text, topicDelegate.text)
root.connection.createSpace(nameDelegate.text, topicDelegate.text)
root.close()
root.destroy()
}

View File

@@ -9,7 +9,7 @@ import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
QQC2.Popup {
id: emojiPopup
id: root
/**
* @brief The current room that user is viewing.
@@ -25,7 +25,7 @@ QQC2.Popup {
Connections {
target: RoomManager
function onCurrentRoomChanged() {
emojiPopup.close()
root.close()
}
}
@@ -64,11 +64,11 @@ QQC2.Popup {
id: emojiPicker
height: 400
currentRoom: root.currentRoom
includeCustom: emojiPopup.includeCustom
showQuickReaction: emojiPopup.showQuickReaction
includeCustom: root.includeCustom
showQuickReaction: root.showQuickReaction
onChosen: emoji => {
emojiPopup.chosen(emoji)
if (emojiPopup.closeOnChosen) emojiPopup.close()
root.chosen(emoji)
if (root.closeOnChosen) root.close()
}
}
}

View File

@@ -9,7 +9,7 @@ import org.kde.kirigami 2.19 as Kirigami
import org.kde.neochat 1.0
Column {
id: emojiItem
id: root
property string emoji
property string description
@@ -23,7 +23,7 @@ Column {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: emojiItem.emoji
text: root.emoji
font.family: "emoji"
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 4
}
@@ -32,7 +32,7 @@ Column {
y: parent.height * 0.75
width: parent.width
height: parent.height * 0.25
text: emojiItem.description
text: root.description
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}

View File

@@ -7,7 +7,7 @@ import QtQml 2.15
import org.kde.neochat 1.0
Row {
id: emojiRow
id: root
property alias model: repeater.model
anchors.horizontalCenter: parent.horizontalCenter
@@ -16,7 +16,7 @@ Row {
delegate: EmojiItem {
emoji: modelData.emoji
description: modelData.description
width: emojiRow.height
width: root.height
height: width
}
}

View File

@@ -9,7 +9,7 @@ import org.kde.kirigami 2.19 as Kirigami
import org.kde.neochat 1.0
Column {
id: emojiSas
id: root
required property var model
@@ -25,12 +25,12 @@ Column {
EmojiRow {
anchors.horizontalCenter: parent.horizontalCenter
height: Kirigami.Units.gridUnit * 4
model: emojiSas.model.slice(0, 4)
model: root.model.slice(0, 4)
}
EmojiRow {
anchors.horizontalCenter: parent.horizontalCenter
height: Kirigami.Units.gridUnit * 4
model: emojiSas.model.slice(4, 7)
model: root.model.slice(4, 7)
}
Row {
anchors.horizontalCenter: parent.horizontalCenter
@@ -38,13 +38,13 @@ Column {
anchors.bottom: parent.bottom
text: i18n("They match")
icon.name: "dialog-ok"
onClicked: emojiSas.accept()
onClicked: root.accept()
}
QQC2.Button {
anchors.bottom: parent.bottom
text: i18n("They don't match")
icon.name: "dialog-cancel"
onClicked: emojiSas.reject()
onClicked: root.reject()
}
}
}

View File

@@ -10,7 +10,8 @@ import org.kde.kirigami 2.19 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: dialog
id: root
title: i18n("Session Verification")
required property var session
@@ -18,31 +19,31 @@ Kirigami.Page {
Item {
anchors.fill: parent
VerificationCanceled {
visible: dialog.session.state === KeyVerificationSession.CANCELED
visible: root.session.state === KeyVerificationSession.CANCELED
anchors.centerIn: parent
reason: dialog.session.error
reason: root.session.error
}
EmojiSas {
anchors.centerIn: parent
visible: dialog.session.state === KeyVerificationSession.WAITINGFORVERIFICATION
model: dialog.session.sasEmojis
onReject: dialog.session.cancelVerification(KeyVerificationSession.MISMATCHED_SAS)
onAccept: dialog.session.sendMac()
visible: root.session.state === KeyVerificationSession.WAITINGFORVERIFICATION
model: root.session.sasEmojis
onReject: root.session.cancelVerification(KeyVerificationSession.MISMATCHED_SAS)
onAccept: root.session.sendMac()
}
Message {
visible: dialog.session.state === KeyVerificationSession.WAITINGFORREADY
visible: root.session.state === KeyVerificationSession.WAITINGFORREADY
anchors.centerIn: parent
icon: "security-medium-symbolic"
text: i18n("Waiting for device to accept verification.")
}
Message {
visible: dialog.session.state === KeyVerificationSession.INCOMING
visible: root.session.state === KeyVerificationSession.INCOMING
anchors.centerIn: parent
icon: "security-medium-symbolic"
text: i18n("Incoming key verification request from device **%1**", dialog.session.remoteDeviceId)
text: i18n("Incoming key verification request from device **%1**", root.session.remoteDeviceId)
}
Message {
visible: dialog.session.state === KeyVerificationSession.WAITINGFORMAC
visible: root.session.state === KeyVerificationSession.WAITINGFORMAC
anchors.centerIn: parent
icon: "security-medium-symbolic"
text: i18n("Waiting for other party to verify.")
@@ -50,35 +51,35 @@ Kirigami.Page {
Kirigami.BasicListItem {
id: emojiVerification
text: "Emoji Verification"
visible: dialog.session.state === KeyVerificationSession.READY
visible: root.session.state === KeyVerificationSession.READY
subtitle: i18n("Compare a set of emoji on both devices")
onClicked: {
dialog.session.sendStartSas()
root.session.sendStartSas()
}
}
Message {
visible: dialog.session.state === KeyVerificationSession.DONE
visible: root.session.state === KeyVerificationSession.DONE
anchors.centerIn: parent
text: i18n("Successfully verified device **%1**", dialog.session.remoteDeviceId)
text: i18n("Successfully verified device **%1**", root.session.remoteDeviceId)
icon: "security-high"
}
}
footer: QQC2.ToolBar {
visible: dialog.session.state === KeyVerificationSession.INCOMING
visible: root.session.state === KeyVerificationSession.INCOMING
QQC2.DialogButtonBox {
anchors.fill: parent
Item { Layout.fillWidth: true }
QQC2.Button {
text: i18n("Accept")
icon.name: "dialog-ok"
onClicked: dialog.session.sendReady()
onClicked: root.session.sendReady()
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
}
QQC2.Button {
text: i18n("Decline")
icon.name: "dialog-cancel"
onClicked: dialog.session.cancelVerification("m.user", "Declined")
onClicked: root.session.cancelVerification("m.user", "Declined")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
}
}

View File

@@ -9,7 +9,8 @@ import org.kde.kirigami 2.19 as Kirigami
import org.kde.neochat 1.0
Column {
id: message
id: root
required property string icon
required property string text
@@ -18,10 +19,10 @@ Column {
width: Kirigami.Units.iconSizes.enormous
height: width
anchors.horizontalCenter: parent.horizontalCenter
source: message.icon
source: root.icon
}
QQC2.Label {
text: message.text
text: root.text
textFormat: Text.MarkdownText
}
}

View File

@@ -7,14 +7,14 @@ import QtQml 2.15
import org.kde.neochat 1.0
Message {
id: verificationCanceled
id: root
required property int reason
anchors.centerIn: parent
icon: "security-low"
text: {
switch(verificationCanceled.reason) {
switch(root.reason) {
case KeyVerificationSession.NONE:
return i18n("The session verification was canceled for unknown reason.");
case KeyVerificationSession.TIMEOUT:

View File

@@ -6,27 +6,27 @@ import QtQuick 2.15
import QtQuick.Layouts 1.10
Labs.Menu {
id: editMenu
id: root
required property Item field
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.canUndo
enabled: root.field !== null && root.field.canUndo
text: i18nc("text editing menu action", "Undo")
shortcut: StandardKey.Undo
onTriggered: {
editMenu.field.undo()
editMenu.close()
root.field.undo()
root.close()
}
}
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.canRedo
enabled: root.field !== null && root.field.canRedo
text: i18nc("text editing menu action", "Redo")
shortcut: StandardKey.Redo
onTriggered: {
editMenu.field.undo()
editMenu.close()
root.field.undo()
root.close()
}
}
@@ -34,42 +34,42 @@ Labs.Menu {
}
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.selectedText
enabled: root.field !== null && root.field.selectedText
text: i18nc("text editing menu action", "Cut")
shortcut: StandardKey.Cut
onTriggered: {
editMenu.field.cut()
editMenu.close()
root.field.cut()
root.close()
}
}
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.selectedText
enabled: root.field !== null && root.field.selectedText
text: i18nc("text editing menu action", "Copy")
shortcut: StandardKey.Copy
onTriggered: {
editMenu.field.copy()
editMenu.close()
root.field.copy()
root.close()
}
}
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.canPaste
enabled: root.field !== null && root.field.canPaste
text: i18nc("text editing menu action", "Paste")
shortcut: StandardKey.Paste
onTriggered: {
editMenu.field.paste()
editMenu.close()
root.field.paste()
root.close()
}
}
Labs.MenuItem {
enabled: editMenu.field !== null && editMenu.field.selectedText !== ""
enabled: root.field !== null && root.field.selectedText !== ""
text: i18nc("text editing menu action", "Delete")
shortcut: ""
onTriggered: {
editMenu.field.remove(editMenu.field.selectionStart, editMenu.field.selectionEnd)
editMenu.close()
root.field.remove(root.field.selectionStart, root.field.selectionEnd)
root.close()
}
}
@@ -77,12 +77,12 @@ Labs.Menu {
}
Labs.MenuItem {
enabled: editMenu.field !== null
enabled: root.field !== null
text: i18nc("text editing menu action", "Select All")
shortcut: StandardKey.SelectAll
onTriggered: {
editMenu.field.selectAll()
editMenu.close()
root.field.selectAll()
root.close()
}
}
}

View File

@@ -54,7 +54,16 @@ Labs.MenuBar {
}
Labs.MenuItem {
text: i18nc("menu", "Browse Chats…")
onTriggered: pushReplaceLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection})
onTriggered: {
let dialog = pageStack.pushDialogLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection}, {title: i18nc("@title", "Explore Rooms")})
dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
if (isJoined) {
RoomManager.enterRoom(Controller.activeConnection.room(roomId))
} else {
Controller.joinRoom(roomId)
}
})
}
}
}
EditMenu {

View File

@@ -13,7 +13,8 @@ import org.kde.kirigami 2.14 as Kirigami
* TODO add Android support
*/
Kirigami.Action {
id: shareAction
id: root
icon.name: "emblem-shared-symbolic"
text: i18n("Share")
tooltip: i18n("Share the selected media")
@@ -40,12 +41,12 @@ Kirigami.Action {
const purposeModel = Qt.createQmlObject('import org.kde.purpose 1.0 as Purpose;
Purpose.PurposeAlternativesModel {
pluginType: "Export"
}', shareAction._instantiator);
}', root._instantiator);
purposeModel.inputData = Qt.binding(function() {
return shareAction.inputData;
return root.inputData;
});
_instantiator.model = purposeModel;
shareAction.visible = true;
root.visible = true;
}
delegate: Kirigami.Action {
@@ -55,16 +56,16 @@ Purpose.PurposeAlternativesModel {
onTriggered: {
doBeforeSharing();
applicationWindow().pageStack.pushDialogLayer('qrc:/ShareDialog.qml', {
title: shareAction.tooltip,
title: root.tooltip,
index: index,
model: shareAction._instantiator.model
model: root._instantiator.model
})
}
}
onObjectAdded: (index, object) => {
object.index = index;
shareAction.children.push(object)
root.children.push(object)
}
onObjectRemoved: (index, object) => shareAction.children = Array.from(shareAction.children).filter(obj => obj.pluginId !== object.pluginId)
onObjectRemoved: (index, object) => root.children = Array.from(root.children).filter(obj => obj.pluginId !== object.pluginId)
}
}

View File

@@ -13,7 +13,7 @@ import org.kde.notification 1.0
import org.kde.kirigami 2.14 as Kirigami
Kirigami.Page {
id: window
id: root
leftPadding: 0
rightPadding: 0
@@ -25,7 +25,7 @@ Kirigami.Page {
QQC2.Action {
shortcut: 'Escape'
onTriggered: window.closeDialog()
onTriggered: root.closeDialog()
}
Notification {
@@ -54,15 +54,15 @@ Kirigami.Page {
sharingSuccess.sendEvent();
Clipboard.saveText(jobView.output.url);
}
window.closeDialog()
root.closeDialog()
} else if (state === Purpose.PurposeJobController.Error) {
// Show failure notification
sharingFailed.sendEvent();
window.closeDialog()
root.closeDialog()
} else if (state === Purpose.PurposeJobController.Cancelled) {
// Do nothing
window.closeDialog()
root.closeDialog()
}
}
}

View File

@@ -10,7 +10,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: banSheet
id: root
property NeoChatRoom room
property string userId
@@ -35,14 +35,14 @@ Kirigami.Page {
icon.name: "im-ban-user"
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
onClicked: {
banSheet.room.ban(banSheet.userId, reason.text)
banSheet.closeDialog()
root.room.ban(root.userId, reason.text)
root.closeDialog()
}
}
QQC2.Button {
text: i18nc("@action", "Cancel")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
onClicked: banSheet.closeDialog()
onClicked: root.closeDialog()
}
}
}

View File

@@ -11,7 +11,7 @@ import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
Loader {
id: loadRoot
id: root
required property var author
required property string eventId
@@ -31,7 +31,7 @@ Loader {
currentRoom.chatBoxEditId = eventId;
currentRoom.chatBoxReplyId = "";
}
visible: author.id === Controller.activeConnection.localUserId && (loadRoot.eventType === DelegateType.Emote || loadRoot.eventType === DelegateType.Message)
visible: author.id === Controller.activeConnection.localUserId && (root.eventType === DelegateType.Emote || root.eventType === DelegateType.Message)
},
Kirigami.Action {
text: i18n("Reply")
@@ -50,7 +50,7 @@ Loader {
width: Kirigami.Units.gridUnit * 25
})
page.chosen.connect(function(targetRoomId) {
Controller.activeConnection.room(targetRoomId).postHtmlMessage(loadRoot.plainText, loadRoot.htmlText ? loadRoot.htmlText : loadRoot.plainText)
Controller.activeConnection.room(targetRoomId).postHtmlMessage(root.plainText, root.htmlText ? root.htmlText : root.plainText)
page.closeDialog()
})
}
@@ -68,7 +68,7 @@ Loader {
Kirigami.Action {
text: i18n("Copy")
icon.name: "edit-copy"
onTriggered: Clipboard.saveText(loadRoot.selectedText === "" ? loadRoot.plainText : loadRoot.selectedText)
onTriggered: Clipboard.saveText(root.selectedText === "" ? root.plainText : root.selectedText)
},
Kirigami.Action {
text: i18nc("@action:button 'Report' as in 'Report this event to the administrators'", "Report")
@@ -84,7 +84,7 @@ Loader {
icon.name: "code-context"
onTriggered: {
applicationWindow().pageStack.pushDialogLayer('qrc:/MessageSourceSheet.qml', {
sourceText: loadRoot.source
sourceText: root.eventSource
}, {
title: i18n("Message Source"),
width: Kirigami.Units.gridUnit * 25
@@ -95,7 +95,7 @@ Loader {
text: i18n("Copy Link")
icon.name: "edit-copy"
onTriggered: {
Clipboard.saveText("https://matrix.to/#/" + currentRoom.id + "/" + loadRoot.eventId)
Clipboard.saveText("https://matrix.to/#/" + currentRoom.id + "/" + root.eventId)
}
}
]
@@ -106,7 +106,7 @@ Loader {
QQC2.Menu {
id: menu
Instantiator {
model: loadRoot.nestedActions
model: root.nestedActions
delegate: QQC2.Menu {
id: menuItem
visible: modelData.visible
@@ -131,12 +131,12 @@ Loader {
}
Repeater {
model: loadRoot.actions
model: root.actions
QQC2.MenuItem {
id: menuItem
visible: modelData.visible
action: modelData
onClicked: loadRoot.item.close();
onClicked: root.item.close();
}
}
QQC2.Menu {
@@ -150,7 +150,7 @@ Loader {
Instantiator {
model: WebShortcutModel {
id: webshortcutmodel
selectedText: loadRoot.selectedText ? loadRoot.selectedText : loadRoot.plainText
selectedText: root.selectedText ? root.selectedText : root.plainText
onOpenUrl: RoomManager.visitNonMatrix(url)
}
delegate: QQC2.MenuItem {
@@ -222,7 +222,7 @@ Loader {
text: modelData.text
onClicked: {
modelData.triggered()
loadRoot.item.close();
root.item.close();
}
implicitHeight: visible ? Kirigami.Units.gridUnit * 3 : 0
}
@@ -285,7 +285,7 @@ Loader {
onClicked: {
currentRoom.toggleReaction(eventId, modelData);
loadRoot.item.close();
root.item.close();
}
}
}
@@ -295,7 +295,7 @@ Loader {
}
Repeater {
id: listViewAction
model: loadRoot.actions
model: root.actions
Kirigami.BasicListItem {
icon: modelData.icon.name
@@ -305,14 +305,14 @@ Loader {
text: modelData.text
onClicked: {
modelData.triggered()
loadRoot.item.close();
root.item.close();
}
implicitHeight: visible ? Kirigami.Units.gridUnit * 3 : 0
}
}
Repeater {
model: loadRoot.nestedActions
model: root.nestedActions
Kirigami.BasicListItem {
action: modelData

View File

@@ -10,7 +10,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: deleteSheet
id: root
property NeoChatRoom room
property string eventId
@@ -37,18 +37,18 @@ Kirigami.Page {
icon.name: "delete"
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
onClicked: {
if (deleteSheet.userId.length > 0) {
deleteSheet.room.deleteMessagesByUser(deleteSheet.userId, reason.text)
if (root.userId.length > 0) {
root.room.deleteMessagesByUser(root.userId, reason.text)
} else {
deleteSheet.room.redactEvent(deleteSheet.eventId, reason.text);
root.room.redactEvent(root.eventId, reason.text);
}
deleteSheet.closeDialog()
root.closeDialog()
}
}
QQC2.Button {
text: i18nc("@action", "Cancel")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
onClicked: deleteSheet.closeDialog()
onClicked: root.closeDialog()
}
}
}

View File

@@ -10,7 +10,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.Page {
id: reportSheet
id: root
property NeoChatRoom room
property string eventId
@@ -35,14 +35,14 @@ Kirigami.Page {
icon.name: "dialog-warning-symbolic"
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
onClicked: {
reportSheet.room.reportEvent(eventId, reason.text)
reportSheet.closeDialog()
root.room.reportEvent(eventId, reason.text)
root.closeDialog()
}
}
QQC2.Button {
text: i18nc("@action", "Cancel")
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
onClicked: reportSheet.closeDialog()
onClicked: root.closeDialog()
}
}
}

View File

@@ -14,7 +14,6 @@ import org.kde.neochat 1.0
Delegates.RoundedItemDelegate {
id: root
required property NeoChatConnection connection
required property string roomId
required property string displayName
required property url avatarUrl
@@ -24,16 +23,32 @@ Delegates.RoundedItemDelegate {
required property bool isJoined
property bool justJoined: false
signal roomSelected()
/**
* @brief Signal emitted when a room delegate is selected.
*
* The signal contains all the delegate's model info so that it can be acted
* upon as required, e.g. joining or entering the room or adding the room as
* the child of a space.
*/
signal roomSelected(string roomId,
string displayName,
url avatarUrl,
string alias,
string topic,
int memberCount,
bool isJoined)
onClicked: {
if (!isJoined) {
Controller.joinRoom(root.roomId)
justJoined = true;
} else {
RoomManager.enterRoom(root.connection.room(root.roomId))
}
root.roomSelected()
root.roomSelected(root.roomId,
root.displayName,
root.avatarUrl,
root.alias,
root.topic,
root.memberCount,
root.isJoined)
}
contentItem: RowLayout {

View File

@@ -20,6 +20,21 @@ Kirigami.ScrollablePage {
property alias keyword: identifierField.text
property string server
/**
* @brief Signal emitted when a room is selected.
*
* The signal contains all the room's info so that it can be acted
* upon as required, e.g. joinng or entering the room or adding the room as
* the child of a space.
*/
signal roomSelected(string roomId,
string displayName,
url avatarUrl,
string alias,
string topic,
int memberCount,
bool isJoined)
title: i18n("Explore Rooms")
Component.onCompleted: identifierField.forceActiveFocus()
@@ -211,7 +226,10 @@ Kirigami.ScrollablePage {
}
delegate: ExplorerDelegate {
connection: root.connection
onRoomSelected: root.closeDialog()
onRoomSelected: (roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
root.roomSelected(roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined);
root.closeDialog();
}
}
footer: RowLayout {

View File

@@ -14,12 +14,20 @@ RowLayout {
property var desiredWidth
property bool collapsed: false
required property NeoChatConnection connection
property Kirigami.Action exploreAction: Kirigami.Action {
text: i18n("Explore rooms")
icon.name: "compass"
onTriggered: {
pageStack.pushDialogLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection}, {title: i18nc("@title", "Explore Rooms")})
let dialog = pageStack.pushDialogLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection}, {title: i18nc("@title", "Explore Rooms")})
dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
if (isJoined) {
RoomManager.enterRoom(Controller.activeConnection.room(roomId))
} else {
Controller.joinRoom(roomId)
}
})
}
}
property Kirigami.Action chatAction: Kirigami.Action {
@@ -31,7 +39,7 @@ RowLayout {
text: i18n("Create a Room")
icon.name: "system-users"
onTriggered: {
pageStack.pushDialogLayer("qrc:/CreateRoomDialog.qml", {}, {title: i18nc("@title", "Create a Room")})
pageStack.pushDialogLayer("qrc:/CreateRoomDialog.qml", {connection: root.connection}, {title: i18nc("@title", "Create a Room")})
}
shortcut: StandardKey.New
}
@@ -39,7 +47,7 @@ RowLayout {
text: i18n("Create a Space")
icon.name: "list-add"
onTriggered: {
pageStack.pushDialogLayer("qrc:/CreateSpaceDialog.qml", {}, {title: i18nc("@title", "Create a Space")})
pageStack.pushDialogLayer("qrc:/CreateSpaceDialog.qml", {connection: root.connection}, {title: i18nc("@title", "Create a Space")})
}
}

View File

@@ -89,13 +89,14 @@ Kirigami.Page {
Layout.fillWidth: true
desiredWidth: root.width - Kirigami.Units.largeSpacing
collapsed: root.collapsed
connection: root.connection
}
padding: 0
RowLayout {
anchors.fill: parent
spacing: 1
spacing: 0
NeoChat.SpaceDrawer {
id: spaceDrawer
@@ -103,6 +104,11 @@ Kirigami.Page {
Layout.fillHeight: true
}
Kirigami.Separator {
Layout.fillHeight: true
Layout.preferredWidth: 1
}
QQC2.ScrollView {
id: scrollView
Layout.fillWidth: true
@@ -153,10 +159,21 @@ Kirigami.Page {
helpfulAction: Kirigami.Action {
icon.name: sortFilterRoomListModel.filterText.length > 0 ? "search" : "list-add"
text: sortFilterRoomListModel.filterText.length > 0 ? i18n("Search in room directory") : i18n("Explore rooms")
onTriggered: pageStack.layers.push("qrc:/JoinRoomPage.qml", {
connection: Controller.activeConnection,
keyword: sortFilterRoomListModel.filterText
})
onTriggered: {
let dialog = pageStack.layers.push("qrc:/JoinRoomPage.qml", {
connection: Controller.activeConnection,
keyword: sortFilterRoomListModel.filterText
}, {
title: i18nc("@title", "Explore Rooms")
})
dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
if (isJoined) {
RoomManager.enterRoom(Controller.activeConnection.room(roomId))
} else {
Controller.joinRoom(roomId)
}
})
}
}
}

View File

@@ -41,6 +41,11 @@ QQC2.Control {
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
contentWidth: -1 // disable horizontal scroll
background: Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
}
ColumnLayout {
id: column
width: scrollView.width

View File

@@ -11,7 +11,7 @@ import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.neochat 1.0
QQC2.ToolBar {
id: userInfo
id: root
padding: 0
@@ -33,7 +33,7 @@ QQC2.ToolBar {
id: addButton
width: parent.width
highlighted: focus || (addAccount.highlighted || addAccount.ListView.isCurrentItem) && !addAccount.pressed
Component.onCompleted: userInfo.addAccount = this
Component.onCompleted: root.addAccount = this
icon {
name: "list-add"
width: Kirigami.Units.iconSizes.smallMedium

View File

@@ -97,6 +97,8 @@ Kirigami.Page {
}
background: Rectangle {
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
color: Config.compactLayout ? Kirigami.Theme.backgroundColor : "transparent"
}

View File

@@ -10,23 +10,24 @@ import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
Kirigami.ApplicationWindow {
id: window
id: root
required property NeoChatRoom currentRoom
minimumWidth: Kirigami.Units.gridUnit * 10
minimumHeight: Kirigami.Units.gridUnit * 15
Shortcut {
sequence: StandardKey.Cancel
onActivated: window.close()
onActivated: root.close()
}
pageStack.initialPage: RoomPage {
visible: true
currentRoom: window.currentRoom
currentRoom: root.currentRoom
disableCancelShortcut: true
}
onCurrentRoomChanged: if (!currentRoom) {
window.close()
root.close()
}
property Item hoverLinkIndicator: QQC2.Control {

View File

@@ -10,7 +10,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.neochat 1.0
Kirigami.ScrollablePage {
id: searchPage
id: root
property NeoChatRoom currentRoom
@@ -22,7 +22,7 @@ Kirigami.ScrollablePage {
id: searchModel
connection: Controller.activeConnection
searchText: searchField.text
room: searchPage.currentRoom
room: root.currentRoom
}
header: RowLayout {

View File

@@ -9,8 +9,8 @@ import Qt.labs.platform 1.1
import QtQuick.Window 2.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
FormCard.FormCardPage {
@@ -19,8 +19,10 @@ FormCard.FormCardPage {
title: i18n("Edit Account")
property NeoChatConnection connection
QQC2.RoundButton {
property var fileDialog: null;
KirigamiComponents.AvatarButton {
id: avatar
property OpenFileDialog fileDialog: null
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: Kirigami.Units.largeSpacing
@@ -31,26 +33,20 @@ FormCard.FormCardPage {
padding: 0
contentItem: KirigamiComponents.Avatar {
id: avatar
source: root.connection && root.connection.localUser.avatarMediaId ? ("image://mxc/" + root.connection.localUser.avatarMediaId) : ""
name: root.connection.localUser.displayName
}
source: root.connection && root.connection.localUser.avatarMediaId ? ("image://mxc/" + root.connection.localUser.avatarMediaId) : ""
name: root.connection.localUser.displayName
onClicked: {
if (fileDialog != null) {
if (fileDialog) {
return;
}
fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.Overlay)
fileDialog.chosen.connect(function(receivedSource) {
fileDialog = openFileDialog.createObject(this);
fileDialog.chosen.connect((receivedSource) => {
if (!receivedSource) {
return;
}
avatar.source = receivedSource;
});
fileDialog.onRejected.connect(function() {
mouseArea.fileDialog = null;
source = receivedSource;
});
fileDialog.open();
}
@@ -94,6 +90,9 @@ FormCard.FormCardPage {
OpenFileDialog {
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
parentWindow: root.Window.window
onAccepted: destroy()
onRejected: destroy()
}
}
}

View File

@@ -12,7 +12,7 @@ import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.neochat 1.0
FormCard.AbstractFormDelegate {
id: deviceDelegate
id: root
required property string id
required property string timestamp
@@ -21,7 +21,7 @@ FormCard.AbstractFormDelegate {
property bool editDeviceName: false
property bool showVerifyButton
onClicked: deviceDelegate.editDeviceName = true
onClicked: root.editDeviceName = true
contentItem: RowLayout {
spacing: Kirigami.Units.largeSpacing
@@ -35,11 +35,11 @@ FormCard.AbstractFormDelegate {
id: deviceLabel
Layout.fillWidth: true
spacing: Kirigami.Units.smallSpacing
visible: !deviceDelegate.editDeviceName
visible: !root.editDeviceName
QQC2.Label {
Layout.fillWidth: true
text: deviceDelegate.displayName
text: root.displayName
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 2
@@ -47,7 +47,7 @@ FormCard.AbstractFormDelegate {
QQC2.Label {
Layout.fillWidth: true
text: i18nc("@label", "%1, Last activity: %2", deviceDelegate.id, deviceDelegate.timestamp)
text: i18nc("@label", "%1, Last activity: %2", root.id, root.timestamp)
color: Kirigami.Theme.disabledTextColor
font: Kirigami.Theme.smallFont
elide: Text.ElideRight
@@ -59,29 +59,29 @@ FormCard.AbstractFormDelegate {
Accessible.description: i18n("New device name")
Layout.fillWidth: true
Layout.preferredHeight: deviceLabel.implicitHeight
visible: deviceDelegate.editDeviceName
visible: root.editDeviceName
text: deviceDelegate.displayName
text: root.displayName
rightActions: [
Kirigami.Action {
text: i18n("Cancel editing display name")
icon.name: "edit-delete-remove"
onTriggered: {
deviceDelegate.editDeviceName = false
root.editDeviceName = false
}
},
Kirigami.Action {
text: i18n("Confirm new display name")
icon.name: "checkmark"
visible: nameField.text !== deviceDelegate.displayName
visible: nameField.text !== root.displayName
onTriggered: {
devicesModel.setName(deviceDelegate.id, nameField.text)
devicesModel.setName(root.id, nameField.text)
}
}
]
onAccepted: devicesModel.setName(deviceDelegate.id, nameField.text)
onAccepted: devicesModel.setName(root.id, nameField.text)
}
QQC2.ToolButton {
display: QQC2.AbstractButton.IconOnly
@@ -89,7 +89,7 @@ FormCard.AbstractFormDelegate {
id: editDeviceAction
text: i18n("Edit device name")
icon.name: "document-edit"
onTriggered: deviceDelegate.editDeviceName = true
onTriggered: root.editDeviceName = true
}
QQC2.ToolTip {
text: editDeviceAction.text
@@ -98,13 +98,13 @@ FormCard.AbstractFormDelegate {
}
QQC2.ToolButton {
display: QQC2.AbstractButton.IconOnly
visible: deviceDelegate.showVerifyButton
visible: root.showVerifyButton
action: Kirigami.Action {
id: verifyDeviceAction
text: i18n("Verify device")
icon.name: "security-low-symbolic"
onTriggered: {
devicesModel.connection.startKeyVerificationSession(devicesModel.connection.localUserId, deviceDelegate.id)
devicesModel.connection.startKeyVerificationSession(devicesModel.connection.localUserId, root.id)
}
}
QQC2.ToolTip {
@@ -119,7 +119,7 @@ FormCard.AbstractFormDelegate {
text: i18n("Logout device")
icon.name: "edit-delete-remove"
onTriggered: {
passwordSheet.deviceId = deviceDelegate.id
passwordSheet.deviceId = root.id
passwordSheet.open()
}
}

View File

@@ -9,7 +9,7 @@ import QtQuick.Layouts 1.15
import org.kde.neochat 1.0
KirigamiSettings.CategorizedSettings {
id: settingsPage
id: root
required property NeoChatConnection connection
@@ -66,7 +66,7 @@ KirigamiSettings.CategorizedSettings {
page: Qt.resolvedUrl("DevicesPage.qml")
initialProperties: {
return {
connection: settingsPage.connection
connection: root.connection
}
}
},

View File

@@ -9,7 +9,7 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
QQC2.RadioButton {
id: delegate
id: root
implicitWidth: contentItem.implicitWidth
implicitHeight: contentItem.implicitHeight
@@ -20,7 +20,7 @@ QQC2.RadioButton {
contentItem: ColumnLayout {
Kirigami.ShadowedRectangle {
implicitWidth: implicitHeight * 1.6
implicitHeight: delegate.thin ? Kirigami.Units.gridUnit * 5 : Kirigami.Units.gridUnit * 6
implicitHeight: root.thin ? Kirigami.Units.gridUnit * 5 : Kirigami.Units.gridUnit * 6
radius: Kirigami.Units.smallSpacing
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View
@@ -31,9 +31,9 @@ QQC2.RadioButton {
shadow.color: Qt.rgba(0, 0, 0, 0.3)
color: {
if (delegate.checked) {
if (root.checked) {
return Kirigami.Theme.highlightColor;
} else if (delegate.hovered) {
} else if (root.hovered) {
// Match appearance of hovered list items
return Qt.rgba(Kirigami.Theme.highlightColor.r,
Kirigami.Theme.highlightColor.g,
@@ -54,7 +54,7 @@ QQC2.RadioButton {
QQC2.Label {
id: label
Layout.fillWidth: true
text: delegate.text
text: root.text
horizontalAlignment: Text.AlignHCenter
}
}

View File

@@ -190,6 +190,8 @@ Kirigami.ApplicationWindow {
RoomList.Page {
id: roomList
connection: Controller.activeConnection
Shortcut {
sequences: ["Ctrl+PgUp", "Ctrl+Backtab", "Alt+Up"]
onActivated: {
@@ -239,9 +241,7 @@ Kirigami.ApplicationWindow {
if (AccountRegistry.accountCount === 0) {
pageStack.replace("qrc:/WelcomePage.qml", {});
} else if (!roomListLoaded) {
pageStack.replace(roomListComponent, {
connection: Controller.activeConnection
});
pageStack.replace(roomListComponent);
roomListLoaded = true;
roomListPage = pageStack.currentItem
RoomManager.loadInitialRoom();
@@ -320,12 +320,16 @@ Kirigami.ApplicationWindow {
Component {
id: createRoomDialog
CreateRoomDialog {}
CreateRoomDialog {
connection: Controller.activeConnection
}
}
Component {
id: createSpaceDialog
CreateSpaceDialog {}
CreateSpaceDialog {
connection: Controller.activeConnection
}
}
Component {