mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-05-19 07:29:32 +00:00
parent
c50691edec
commit
e75a778f7a
@ -1,6 +1,8 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
import "components"
|
||||||
|
import "state"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@ -164,10 +166,31 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Liquidity view (placeholder — replaced when LP branch merges) ─────
|
// ── Liquidity view ────────────────────────────────────────────────────
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: navbar.currentIndex === 1
|
visible: navbar.currentIndex === 1
|
||||||
|
|
||||||
|
DummyPoolState {
|
||||||
|
id: poolState
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#151515"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
PoolPositionSummary {
|
||||||
|
poolState: poolState
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: implicitHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
amm-ui/qml/components/EstimateInfoButton.qml
Normal file
64
amm-ui/qml/components/EstimateInfoButton.qml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string helpText: qsTr("This value is derived from your LP token balance, total LP supply, and current pool reserves.")
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focusPolicy: Qt.StrongFocus
|
||||||
|
hoverEnabled: true
|
||||||
|
text: qsTr("?")
|
||||||
|
|
||||||
|
Accessible.name: qsTr("Why this value is an estimate")
|
||||||
|
|
||||||
|
onClicked: estimatePopup.opened ? estimatePopup.close() : estimatePopup.open()
|
||||||
|
|
||||||
|
Keys.onEscapePressed: estimatePopup.close()
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
color: root.activeFocus || root.hovered || estimatePopup.opened ? "#F26A21" : "#E7E1D8"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 11
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: qsTr("i")
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: root.activeFocus || estimatePopup.opened ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
color: root.pressed ? "#2A221D" : "#1D1D1D"
|
||||||
|
radius: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: estimatePopup
|
||||||
|
|
||||||
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||||
|
focus: true
|
||||||
|
modal: false
|
||||||
|
padding: 10
|
||||||
|
width: 224
|
||||||
|
x: Math.max(-width + root.width, -196)
|
||||||
|
y: root.height + 4
|
||||||
|
|
||||||
|
onClosed: root.forceActiveFocus()
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: "#343434"
|
||||||
|
border.width: 1
|
||||||
|
color: "#1D1D1D"
|
||||||
|
radius: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
color: "#E7E1D8"
|
||||||
|
font.pixelSize: 12
|
||||||
|
lineHeight: 1.25
|
||||||
|
text: root.helpText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
122
amm-ui/qml/components/PoolPositionSummary.qml
Normal file
122
amm-ui/qml/components/PoolPositionSummary.qml
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import "../state"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property DummyPoolState poolState
|
||||||
|
readonly property string estimateHelp: qsTr("This value is an estimate from the current dummy reserves and your share of total LP supply.")
|
||||||
|
|
||||||
|
color: "#1D1D1D"
|
||||||
|
implicitHeight: content.implicitHeight + 20
|
||||||
|
radius: 8
|
||||||
|
border.color: "#343434"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#E7E1D8"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 16
|
||||||
|
text: qsTr("Pool position")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#F26A21"
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: qsTr("You have no position in this pool")
|
||||||
|
visible: root.poolState.userLpBalance === 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Token A")
|
||||||
|
value: root.poolState.tokenA
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Token B")
|
||||||
|
value: root.poolState.tokenB
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Fee tier")
|
||||||
|
value: root.poolState.feeTier
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Your LP tokens")
|
||||||
|
value: root.poolState.formatInteger(root.poolState.userLpBalance)
|
||||||
|
visible: root.poolState.userLpBalance > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
estimated: true
|
||||||
|
estimateHelp: root.estimateHelp
|
||||||
|
label: qsTr("Pool share")
|
||||||
|
value: root.poolState.formatPoolShare(root.poolState.poolShare)
|
||||||
|
visible: root.poolState.userLpBalance > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
estimated: true
|
||||||
|
estimateHelp: root.estimateHelp
|
||||||
|
label: qsTr("Your Token A")
|
||||||
|
value: "\u2248 " + root.poolState.formatTokenAmount(root.poolState.userOwnedA, root.poolState.tokenA)
|
||||||
|
visible: root.poolState.userLpBalance > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
estimated: true
|
||||||
|
estimateHelp: root.estimateHelp
|
||||||
|
label: qsTr("Your Token B")
|
||||||
|
value: "\u2248 " + root.poolState.formatTokenAmount(root.poolState.userOwnedB, root.poolState.tokenB)
|
||||||
|
visible: root.poolState.userLpBalance > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Total reserve A")
|
||||||
|
value: root.poolState.formatTokenAmount(root.poolState.reserveA, root.poolState.tokenA)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Total reserve B")
|
||||||
|
value: root.poolState.formatTokenAmount(root.poolState.reserveB, root.poolState.tokenB)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Total LP supply")
|
||||||
|
value: root.poolState.formatInteger(root.poolState.totalLpSupply)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
amm-ui/qml/components/SummaryRow.qml
Normal file
60
amm-ui/qml/components/SummaryRow.qml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string label: ""
|
||||||
|
property string value: ""
|
||||||
|
property bool estimated: false
|
||||||
|
property string estimateHelp: qsTr("This value is derived from your LP token balance, total LP supply, and current pool reserves.")
|
||||||
|
|
||||||
|
implicitHeight: Math.max(18, Math.max(labelText.implicitHeight, valueGroup.implicitHeight))
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: labelText
|
||||||
|
|
||||||
|
color: "#A9A098"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: root.label
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: valueGroup
|
||||||
|
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#E7E1D8"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 12
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
text: root.value
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
Layout.maximumWidth: 178
|
||||||
|
}
|
||||||
|
|
||||||
|
EstimateInfoButton {
|
||||||
|
enabled: root.estimated
|
||||||
|
helpText: root.estimateHelp
|
||||||
|
opacity: root.estimated ? 1 : 0
|
||||||
|
visible: root.estimated
|
||||||
|
|
||||||
|
Layout.preferredHeight: 18
|
||||||
|
Layout.preferredWidth: root.estimated ? 18 : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
amm-ui/qml/state/DummyPoolState.qml
Normal file
66
amm-ui/qml/state/DummyPoolState.qml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string tokenA: "USDC"
|
||||||
|
property string tokenB: "ETH"
|
||||||
|
property string feeTier: "0.30%"
|
||||||
|
property real userLpBalance: 1118033
|
||||||
|
property real reserveA: 1000000
|
||||||
|
property real reserveB: 500
|
||||||
|
property real totalLpSupply: 22360679
|
||||||
|
|
||||||
|
readonly property real poolShare: totalLpSupply > 0 ? userLpBalance / totalLpSupply : 0
|
||||||
|
readonly property real userOwnedA: reserveA * poolShare
|
||||||
|
readonly property real userOwnedB: reserveB * poolShare
|
||||||
|
|
||||||
|
function applyAddLiquidity(actualA, actualB, mintedLp) {
|
||||||
|
const safeA = Math.max(0, Number(actualA) || 0);
|
||||||
|
const safeB = Math.max(0, Number(actualB) || 0);
|
||||||
|
const safeLp = Math.max(0, Number(mintedLp) || 0);
|
||||||
|
|
||||||
|
reserveA += safeA;
|
||||||
|
reserveB += safeB;
|
||||||
|
totalLpSupply += safeLp;
|
||||||
|
userLpBalance += safeLp;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyRemoveLiquidity(withdrawA, withdrawB, burnedLp) {
|
||||||
|
const safeA = Math.max(0, Number(withdrawA) || 0);
|
||||||
|
const safeB = Math.max(0, Number(withdrawB) || 0);
|
||||||
|
const safeLp = Math.max(0, Number(burnedLp) || 0);
|
||||||
|
|
||||||
|
reserveA = Math.max(0, reserveA - safeA);
|
||||||
|
reserveB = Math.max(0, reserveB - safeB);
|
||||||
|
totalLpSupply = Math.max(0, totalLpSupply - safeLp);
|
||||||
|
userLpBalance = Math.max(0, userLpBalance - safeLp);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetDummyState() {
|
||||||
|
tokenA = "USDC";
|
||||||
|
tokenB = "ETH";
|
||||||
|
feeTier = "0.30%";
|
||||||
|
userLpBalance = 1118033;
|
||||||
|
reserveA = 1000000;
|
||||||
|
reserveB = 500;
|
||||||
|
totalLpSupply = 22360679;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatInteger(value) {
|
||||||
|
const rounded = Math.round(Number(value) || 0);
|
||||||
|
return rounded.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTokenAmount(value, token) {
|
||||||
|
return formatInteger(value) + " " + token;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatLpAmount(value) {
|
||||||
|
return formatInteger(value) + " LP";
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatPoolShare(value) {
|
||||||
|
return "\u2248 " + (Math.max(0, Number(value) || 0) * 100).toFixed(2) + "%";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user