Skip to content
Open
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
10 changes: 6 additions & 4 deletions apps/amm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ Account/keystore sharing follows the runtime:
startup the backend **adopts** the already-open wallet (see
`openOrAdoptWallet()`), surfacing **shared** accounts across apps.

> Follow-up: the wallet FFI requires explicit `config_path`/`storage_path` even
> though the wallet crate already defines defaults (`~/.lee/wallet`,
> `from_path_or_initialize_default`). A `wallet_ffi_create_new_default()` /
> `_open_default()` upstream would let the app drop its path handling entirely.
> Follow-up: the app reconstructs the wallet paths itself because the
> `logos_execution_zone` module only exposes path-taking `create_new`/`open`.
> LEZ's wallet FFI now provides path-free variants (`wallet_ffi_create_new_default`,
> `wallet_ffi_open_default`, plus `wallet_ffi_default_config_path` /
> `_storage_path` / `wallet_ffi_wallet_exists_default`). Once the module surfaces
> those over QtRO, the app can drop its `defaultWalletHome/Config/Storage` logic.

## Setup

Expand Down
9 changes: 7 additions & 2 deletions apps/amm/qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Item {
height: show ? 32 : 0
visible: height > 0
clip: true
color: Theme.palette.warning
color: Theme.palette.error

Behavior on height { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }

Expand All @@ -56,7 +56,7 @@ Item {
elide: Text.ElideMiddle
font.pixelSize: 12
font.weight: Font.Medium
color: Theme.palette.background
color: Theme.palette.text
text: qsTr("Unable to connect to network")
}
}
Expand Down Expand Up @@ -89,5 +89,10 @@ Item {
anchors.fill: parent
visible: navbar.currentIndex === 1
}

CreatePoolPage {
anchors.fill: parent
visible: navbar.currentIndex === 2
}
}
}
2 changes: 1 addition & 1 deletion apps/amm/qml/NavBar.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Item {
id: root

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

// Wallet wiring, passed down from Main.qml.
property var backend: null
Expand Down
116 changes: 116 additions & 0 deletions apps/amm/qml/components/pool/PoolStepRail.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import QtQuick
import QtQuick.Layouts

import Logos.Theme
import Logos.Controls

// Vertical progress rail for the pool-creation flow (Uniswap-style): numbered
// steps connected by a line, with the active step highlighted and completed
// steps marked done. Read currentStep to drive which step is active. Clicking an
// already-reached step (index <= currentStep) emits stepClicked so the page can
// navigate back to it.
Item {
id: root

property int currentStep: 0
readonly property var steps: [
{ title: qsTr("Select token pair"), subtitle: qsTr("Pick the two tokens for the pool.") },
{ title: qsTr("Deposit amounts"), subtitle: qsTr("Set the initial liquidity.") }
]

signal stepClicked(int index)

implicitWidth: 240
implicitHeight: column.implicitHeight

ColumnLayout {
id: column
anchors.fill: parent
spacing: 0

Repeater {
model: root.steps

delegate: Item {
id: stepItem

readonly property bool active: index === root.currentStep
readonly property bool done: index < root.currentStep
readonly property bool last: index === root.steps.length - 1
// Only steps already reached can be clicked (no jumping ahead).
readonly property bool reachable: index <= root.currentStep

Layout.fillWidth: true
implicitHeight: stepRow.implicitHeight

RowLayout {
id: stepRow
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: Theme.spacing.medium

// Indicator: numbered dot + connector line down to the next dot.
Item {
Layout.preferredWidth: 28
Layout.fillHeight: true

Rectangle {
id: dot
width: 28
height: 28
radius: 14
color: (stepItem.active || stepItem.done) ? Theme.palette.primary : Theme.palette.backgroundSecondary
border.width: 1
border.color: (stepItem.active || stepItem.done) ? Theme.palette.primary : Theme.palette.border

LogosText {
anchors.centerIn: parent
text: stepItem.done ? "✓" : (index + 1)
font.pixelSize: Theme.typography.secondaryText
font.bold: true
color: (stepItem.active || stepItem.done) ? Theme.palette.background : Theme.palette.textSecondary
}
}
Rectangle {
visible: !stepItem.last
width: 2
anchors.top: dot.bottom
anchors.bottom: parent.bottom
anchors.horizontalCenter: dot.horizontalCenter
color: stepItem.done ? Theme.palette.primary : Theme.palette.border
}
}

// Step text.
ColumnLayout {
Layout.fillWidth: true
Layout.bottomMargin: stepItem.last ? 0 : Theme.spacing.xlarge
spacing: 2

LogosText {
text: modelData.title
font.pixelSize: Theme.typography.primaryText
font.bold: stepItem.active
color: (stepItem.active || stepItem.done) ? Theme.palette.text : Theme.palette.textSecondary
}
LogosText {
Layout.fillWidth: true
text: modelData.subtitle
wrapMode: Text.WordWrap
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.textSecondary
}
}
}

MouseArea {
anchors.fill: parent
enabled: stepItem.reachable
cursorShape: stepItem.reachable ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: root.stepClicked(index)
}
}
}
}
}
21 changes: 18 additions & 3 deletions apps/amm/qml/components/wallet/AccountControl.qml
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,29 @@ Item {
Layout.fillWidth: true
height: 40
text: qsTr("Save")
onClicked: {
// The new endpoint only goes live after an app restart (the
// module can't re-open an already-open wallet), so confirm
// the user understands that before persisting.
onClicked: restartDialog.open()
}

// Persist the change; the running wallet keeps the old endpoint
// until the user restarts (we can't reliably quit this host).
RestartRequiredDialog {
id: restartDialog
title: qsTr("Restart to apply")
confirmLabel: qsTr("Save")
message: qsTr("Changing the network endpoint only takes effect after restarting the app. "
+ "Save now, then quit and reopen the app to apply it.")
onConfirmed: {
if (!root.backend) return
seqStatus.text = ""
logos.watch(root.backend.changeSequencerAddr(seqField.text),
function(ok) {
seqStatus.ok = ok
seqStatus.text = ok ? qsTr("Network updated.")
: qsTr("Failed to update network.")
seqStatus.text = ok
? qsTr("Saved — quit and reopen the app to apply.")
: qsTr("Invalid network URL.")
},
function(error) {
seqStatus.ok = false
Expand Down
73 changes: 73 additions & 0 deletions apps/amm/qml/components/wallet/RestartRequiredDialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

import Logos.Theme
import Logos.Controls

// Modal shown before applying a setting that only takes effect after a restart.
// The caller handles `confirmed` (persist the change, then close the app).
Popup {
id: root

property string title: qsTr("Restart required")
property string message: ""
property string confirmLabel: qsTr("Save & close")

signal confirmed()

modal: true
dim: true
padding: Theme.spacing.large
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

// Center on the full-window overlay rather than the small control this is
// declared inside.
parent: Overlay.overlay
anchors.centerIn: parent
width: 360

background: Rectangle {
color: Theme.palette.backgroundSecondary
radius: Theme.spacing.radiusXlarge
border.color: Theme.palette.backgroundElevated
}

contentItem: ColumnLayout {
width: root.availableWidth
spacing: Theme.spacing.large

LogosText {
text: root.title
font.pixelSize: Theme.typography.titleText
font.weight: Theme.typography.weightBold
color: Theme.palette.text
}
LogosText {
Layout.fillWidth: true
text: root.message
wrapMode: Text.WordWrap
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.textSecondary
}
RowLayout {
Layout.topMargin: Theme.spacing.medium
Layout.fillWidth: true
spacing: Theme.spacing.medium

LogosButton {
text: qsTr("Cancel")
Layout.fillWidth: true
onClicked: root.close()
}
LogosButton {
text: root.confirmLabel
Layout.fillWidth: true
onClicked: {
root.confirmed()
root.close()
}
}
}
}
}
Loading
Loading