Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 145 additions & 121 deletions amm-ui/qml/Main.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import "components"
import "state"
import "pages"

Item {
id: root
Expand All @@ -14,139 +17,160 @@ Item {
{ symbol: "TOK6", name: "Token 6", color: "#9b59b6", letter: "L", address: "0x1337000000000000000000000000000000000cafe", usdPrice: 0.42 }
]

// ── Theme ─────────────────────────────────────────────────────────────────
QtObject {
id: theme
property bool isDark: false
property var colors: isDark ? dark : light

readonly property var light: ({
background: "#f7f7f5",
cardBg: "#ffffff",
inputBg: "#f0f0ee",
panelBg: "#e8e8e4",
panelHoverBg: "#ddddd8",
textPrimary: "#111111",
textSecondary: "#777770",
textPlaceholder: "#bbbbb5",
border: Qt.rgba(0,0,0,0.08),
borderStrong: Qt.rgba(0,0,0,0.10),
divider: Qt.rgba(0,0,0,0.06),
ctaBg: "#111111",
ctaHoverBg: "#2a2a28",
selection: "#b5c4a5",
noTokenCircle: "#c8c8c4",
orb1: "#7a8c6a",
orb2: "#b5c4a5",
orb3: "#7a8c6a",
orb4: "#c8d4b8"
})

readonly property var dark: ({
background: "#0d0d12",
cardBg: "#1a1a22",
inputBg: "#222230",
panelBg: "#2a2a38",
panelHoverBg: "#363650",
textPrimary: "#ffffff",
textSecondary: "#888899",
textPlaceholder: "#444455",
border: Qt.rgba(1,1,1,0.08),
borderStrong: Qt.rgba(1,1,1,0.10),
divider: Qt.rgba(1,1,1,0.06),
ctaBg: "#2d1530",
ctaHoverBg: "#3d1f40",
selection: "#4c1d4b",
noTokenCircle: "#444455",
orb1: "#627eea",
orb2: "#9b59b6",
orb3: "#fc72ff",
orb4: "#26a17b"
})
// ── Navigation bar ────────────────────────────────────────────────────────
// Pinned to the top; self-contained styling, unaffected by view themes.
NavBar {
id: navbar
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
z: 100
}

// ── Root background ───────────────────────────────────────────────────────
Rectangle {
anchors.fill: parent
color: theme.colors.background
Behavior on color { ColorAnimation { duration: 300 } }

// Theme toggle
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 16
width: 44; height: 24; radius: 12
color: theme.colors.panelBg
border.color: theme.colors.border
border.width: 1
Text {
anchors.centerIn: parent
text: theme.isDark ? "☀" : "☾"
font.pixelSize: 13
color: theme.colors.textSecondary
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: theme.isDark = !theme.isDark
}
}
// ── Content area (below the nav bar) ──────────────────────────────────────
Item {
anchors.top: navbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom

// Decorative orbs
Rectangle { x: -180; y: -120; width: 560; height: 560; radius: 280; color: theme.colors.orb1; opacity: 0.07 }
Rectangle { x: parent.width - 280; y: parent.height - 320; width: 480; height: 480; radius: 240; color: theme.colors.orb2; opacity: 0.09 }
Rectangle { x: parent.width - 200; y: -80; width: 380; height: 380; radius: 190; color: theme.colors.orb3; opacity: 0.05 }
Rectangle { x: 40; y: parent.height - 260; width: 320; height: 320; radius: 160; color: theme.colors.orb4; opacity: 0.08 }

ColumnLayout {
anchors.centerIn: parent
spacing: 28

Text {
Layout.alignment: Qt.AlignHCenter
text: "Logos AMM"
color: theme.colors.textPrimary
font.pixelSize: 48
font.weight: Font.Bold
// ── Trade view ────────────────────────────────────────────────────────
Item {
anchors.fill: parent
visible: navbar.currentIndex === 0

// Trade view theme — scoped here, invisible to NavBar and LP view.
QtObject {
id: theme
property bool isDark: false
property var colors: isDark ? dark : light

readonly property var light: ({
background: "#f7f7f5",
cardBg: "#ffffff",
inputBg: "#f0f0ee",
panelBg: "#e8e8e4",
panelHoverBg: "#ddddd8",
textPrimary: "#111111",
textSecondary: "#777770",
textPlaceholder: "#bbbbb5",
border: Qt.rgba(0,0,0,0.08),
borderStrong: Qt.rgba(0,0,0,0.10),
divider: Qt.rgba(0,0,0,0.06),
ctaBg: "#111111",
ctaHoverBg: "#2a2a28",
selection: "#b5c4a5",
noTokenCircle: "#c8c8c4",
orb1: "#7a8c6a",
orb2: "#b5c4a5",
orb3: "#7a8c6a",
orb4: "#c8d4b8"
})

readonly property var dark: ({
background: "#0d0d12",
cardBg: "#1a1a22",
inputBg: "#222230",
panelBg: "#2a2a38",
panelHoverBg: "#363650",
textPrimary: "#ffffff",
textSecondary: "#888899",
textPlaceholder: "#444455",
border: Qt.rgba(1,1,1,0.08),
borderStrong: Qt.rgba(1,1,1,0.10),
divider: Qt.rgba(1,1,1,0.06),
ctaBg: "#2d1530",
ctaHoverBg: "#3d1f40",
selection: "#4c1d4b",
noTokenCircle: "#444455",
orb1: "#627eea",
orb2: "#9b59b6",
orb3: "#fc72ff",
orb4: "#26a17b"
})
}

SwapCard {
id: swapCard
Layout.alignment: Qt.AlignHCenter
theme: theme
tokens: root.tokenData
width: Math.min(480, root.width - 32)
Rectangle {
anchors.fill: parent
color: theme.colors.background
Behavior on color { ColorAnimation { duration: 300 } }

// Theme toggle
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 16
width: 44; height: 24; radius: 12
color: theme.colors.panelBg
border.color: theme.colors.border
border.width: 1
Text {
anchors.centerIn: parent
text: theme.isDark ? "☀" : "☾"
font.pixelSize: 13
color: theme.colors.textSecondary
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: theme.isDark = !theme.isDark
}
}

onRequestTokenSelect: function(side) {
tokenModal.targetSide = side
tokenModal.open()
// Decorative orbs
Rectangle { x: -180; y: -120; width: 560; height: 560; radius: 280; color: theme.colors.orb1; opacity: 0.07 }
Rectangle { x: parent.width - 280; y: parent.height - 320; width: 480; height: 480; radius: 240; color: theme.colors.orb2; opacity: 0.09 }
Rectangle { x: parent.width - 200; y: -80; width: 380; height: 380; radius: 190; color: theme.colors.orb3; opacity: 0.05 }
Rectangle { x: 40; y: parent.height - 260; width: 320; height: 320; radius: 160; color: theme.colors.orb4; opacity: 0.08 }

ColumnLayout {
anchors.centerIn: parent
spacing: 28

SwapCard {
id: swapCard
Layout.alignment: Qt.AlignHCenter
theme: theme
tokens: root.tokenData
width: Math.min(480, root.width - 32)

onRequestTokenSelect: function(side) {
tokenModal.targetSide = side
tokenModal.open()
}
}

Text {
Layout.alignment: Qt.AlignHCenter
text: "Buy and sell crypto on <font color='" + theme.colors.textPrimary + "'>LEZ</font>."
textFormat: Text.RichText
color: theme.colors.textSecondary
font.pixelSize: 15
horizontalAlignment: Text.AlignHCenter
}
}
}

Text {
Layout.alignment: Qt.AlignHCenter
text: "Buy and sell crypto on <font color='" + theme.colors.textPrimary + "'>LEZ</font>."
textFormat: Text.RichText
color: theme.colors.textSecondary
font.pixelSize: 15
horizontalAlignment: Text.AlignHCenter
TokenSelectorModal {
id: tokenModal
anchors.fill: parent
z: 10
theme: theme
tokens: root.tokenData

property string targetSide: "sell"

onTokenSelected: function(tok) {
swapCard.setToken(targetSide, tok)
tokenModal.close()
}
}
}
}

TokenSelectorModal {
id: tokenModal
// ── Liquidity view ────────────────────────────────────────────────────
LiquidityPage {
anchors.fill: parent
z: 10
theme: theme
tokens: root.tokenData

property string targetSide: "sell"

onTokenSelected: function(tok) {
swapCard.setToken(targetSide, tok)
tokenModal.close()
}
visible: navbar.currentIndex === 1
}
}
}
86 changes: 86 additions & 0 deletions amm-ui/qml/NavBar.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15

// Self-contained navigation bar — styling is independent of any view's theme.
// Use currentIndex to read the active tab; tabChanged(index) fires on selection.
Item {
id: root

property int currentIndex: 0
readonly property var tabs: ["Trade", "Liquidity"]

signal tabChanged(int index)

implicitHeight: 56

Rectangle {
anchors.fill: parent
color: "#ffffff"

// Bottom separator
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: Qt.rgba(0, 0, 0, 0.08)
}

RowLayout {
anchors.fill: parent
anchors.leftMargin: 20
anchors.rightMargin: 20
spacing: 4

// App identity
Text {
text: "Logos AMM"
color: "#111111"
font.pixelSize: 17
font.weight: Font.Bold
}

Item { Layout.fillWidth: true }

// Tab pills
Row {
spacing: 4

Repeater {
model: root.tabs

delegate: Rectangle {
readonly property bool active: root.currentIndex === index

height: 36
width: tabLabel.implicitWidth + 28
radius: 18
color: active ? "#111111" : "transparent"

Behavior on color { ColorAnimation { duration: 150 } }

Text {
id: tabLabel
anchors.centerIn: parent
text: modelData
color: active ? "#ffffff" : "#666666"
font.pixelSize: 14
font.weight: active ? Font.Medium : Font.Normal

Behavior on color { ColorAnimation { duration: 150 } }
}

MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
root.currentIndex = index
root.tabChanged(index)
}
}
}
}
}
}
}
}
Loading
Loading