Implement basic UI with QML (MailListPage) and batching DbChangeProcessor (Step 3-4 of transition plan)
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Item {
|
||||
id: mailListPage
|
||||
anchors.fill: parent
|
||||
|
||||
// Layout: SplitView for resizable panes
|
||||
SplitView {
|
||||
anchors.fill: parent
|
||||
|
||||
// Left pane: Folder list
|
||||
Rectangle {
|
||||
width: 200
|
||||
color: "#fafafa"
|
||||
ListView {
|
||||
id: folderListView
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
model: FolderModel {}
|
||||
delegate: Item {
|
||||
height: 40
|
||||
Layout.fillWidth: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: ListView.isCurrentItem ? "#e3f2fd" : "transparent"
|
||||
Text {
|
||||
text: folderName
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pointSize: 14
|
||||
color: ListView.isCurrentItem ? "#1976d2" : "#666"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
folderListView.currentIndex = index
|
||||
// TODO: Load emails for selected folder
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Right pane: Email list and preview
|
||||
Rectangle {
|
||||
color: "#fafafa"
|
||||
SplitView {
|
||||
orientation: Qt.Vertical
|
||||
anchors.fill: parent
|
||||
|
||||
// Email list (top)
|
||||
Rectangle {
|
||||
Layout.minimumHeight: 200
|
||||
color: "#fafafa"
|
||||
ListView {
|
||||
id: emailListView
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
model: EmailModel {}
|
||||
delegate: Item {
|
||||
height: 60
|
||||
Layout.fillWidth: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: ListView.isCurrentItem ? "#e3f2fd" : "transparent"
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
// Sender avatar/initial
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 40
|
||||
color: "#cccccc"
|
||||
Text {
|
||||
text: senderInitial
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 16
|
||||
color: "#666"
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text {
|
||||
text: senderName
|
||||
font.pointSize: 14
|
||||
color: "#333"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: subject
|
||||
font.pointSize: 13
|
||||
color: "#666"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: time
|
||||
font.pointSize: 12
|
||||
color: "#999"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
emailListView.currentIndex = index
|
||||
// TODO: Show email preview in the bottom pane
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Email preview (bottom)
|
||||
Rectangle {
|
||||
Layout.minimumHeight: 200
|
||||
color: "#ffffff"
|
||||
Text {
|
||||
id: emailPreview
|
||||
text: "Select an email to preview"
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 14
|
||||
color: "#666"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
ApplicationWindow {
|
||||
id: shell
|
||||
visible: true
|
||||
width: 1024
|
||||
height: 768
|
||||
title: qsTr("Wino Mail Qt")
|
||||
|
||||
// Set the title from translator in Component.onCompleted
|
||||
Component.onCompleted: {
|
||||
title = translator.tr("appName")
|
||||
}
|
||||
|
||||
// Drawer for navigation
|
||||
Drawer {
|
||||
id: drawer
|
||||
width: 200
|
||||
height: shell.height
|
||||
Container {
|
||||
anchors.fill: parent
|
||||
Layout.alignment: Qt.AlignTop
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
// App logo/name
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 60
|
||||
color: "#1976D2"
|
||||
Text {
|
||||
text: qsTr("Wino Mail")
|
||||
color: "white"
|
||||
font.pointSize: 18
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
// Navigation items
|
||||
NavigationItem {
|
||||
text: qsTr("Mail")
|
||||
icon: "mail"
|
||||
isChecked: stackView.currentIndex === 0
|
||||
onClicked: {
|
||||
drawer.close()
|
||||
stackView.currentIndex = 0
|
||||
}
|
||||
}
|
||||
NavigationItem {
|
||||
text: qsTr("Calendar")
|
||||
icon: "calendar"
|
||||
isChecked: stackView.currentIndex === 1
|
||||
onClicked: {
|
||||
drawer.close()
|
||||
stackView.currentIndex = 1
|
||||
}
|
||||
}
|
||||
NavigationItem {
|
||||
text: qsTr("Contacts")
|
||||
icon: "contacts"
|
||||
isChecked: stackView.currentIndex === 2
|
||||
onClicked: {
|
||||
drawer.close()
|
||||
stackView.currentIndex = 2
|
||||
}
|
||||
}
|
||||
NavigationItem {
|
||||
text: qsTr("Settings")
|
||||
icon: "settings"
|
||||
isChecked: stackView.currentIndex === 3
|
||||
onClicked: {
|
||||
drawer.close()
|
||||
stackView.currentIndex = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main content area with StackView for pages
|
||||
StackView {
|
||||
id: stackView
|
||||
anchors.fill: parent
|
||||
initialItem: mailListPage
|
||||
}
|
||||
|
||||
// Define pages
|
||||
MailListPage {
|
||||
id: mailListPage
|
||||
}
|
||||
// Placeholder for other pages
|
||||
Rectangle {
|
||||
color: "#f0f0f0"
|
||||
Text {
|
||||
text: qsTr("Calendar Page")
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
color: "#f0f0f0"
|
||||
Text {
|
||||
text: qsTr("Contacts Page")
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
color: "#f0f0f0"
|
||||
Text {
|
||||
text: qsTr("Settings Page")
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
// Hamburger button to open drawer
|
||||
MenuButton {
|
||||
icon: "menu"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 10
|
||||
onClicked: drawer.open()
|
||||
}
|
||||
}
|
||||
|
||||
// Helper components
|
||||
component NavigationItem: Button {
|
||||
Layout.fillWidth: true
|
||||
height: 48
|
||||
padding: 0
|
||||
contentItem: RowLayout {
|
||||
spacing: 16
|
||||
anchors.fill: parent
|
||||
anchors.margins: 24
|
||||
Icon {
|
||||
source: icon
|
||||
width: 24
|
||||
height: 24
|
||||
color: isChecked ? "#1976D2" : "#666"
|
||||
}
|
||||
Text {
|
||||
text: text
|
||||
font.pointSize: 14
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: isChecked ? "#1976D2" : "#666"
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: isChecked ? "#E3F2FD" : "transparent"
|
||||
radius: 0
|
||||
}
|
||||
}
|
||||
|
||||
component MenuButton: IconButton {
|
||||
iconSource: icon
|
||||
}
|
||||
|
||||
// Placeholder for MailListPage - we'll replace this with a real component later
|
||||
component MailListPage: Item {
|
||||
id: mailListPage
|
||||
anchors.fill: parent
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#fafafa"
|
||||
Text {
|
||||
text: qsTr("Mail List Placeholder")
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 16
|
||||
color: "#666"
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-24
@@ -2,28 +2,6 @@ import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Window {
|
||||
width: 1024
|
||||
height: 768
|
||||
visible: true
|
||||
title: qsTr("Wino Mail Qt")
|
||||
|
||||
// Use the translator to set the title
|
||||
// Note: we can't directly call translator.tr here because it's a C++ object.
|
||||
// We'll set the title in Component.onCompleted by accessing the context property.
|
||||
Component.onCompleted: {
|
||||
title = translator.tr("appName")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#f0f0f0"
|
||||
|
||||
Text {
|
||||
text: qsTr("Welcome to Wino Mail Qt!")
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 24
|
||||
color: "#333"
|
||||
}
|
||||
}
|
||||
// We'll load the Shell component from Shell.qml
|
||||
Shell {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import QtQuick 2.15
|
||||
|
||||
ListModel {
|
||||
ListElement {
|
||||
folderName: "Inbox"
|
||||
unreadCount: 5
|
||||
}
|
||||
ListElement {
|
||||
folderName: "Sent"
|
||||
unreadCount: 0
|
||||
}
|
||||
ListElement {
|
||||
folderName: "Drafts"
|
||||
unreadCount: 0
|
||||
}
|
||||
ListElement {
|
||||
folderName: "Trash"
|
||||
unreadCount: 0
|
||||
}
|
||||
ListElement {
|
||||
folderName: "Spam"
|
||||
unreadCount: 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user