Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update layout Send page and send modal for mobile version #347

Merged
merged 12 commits into from
Dec 29, 2023
1 change: 0 additions & 1 deletion ui/cryptomaterial/collapsible.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ type Collapsible struct {
}

type CollapsibleWithOption struct {
isExpanded bool
button *widget.Clickable
BackgroundColor color.NRGBA
card Card
Expand Down
12 changes: 10 additions & 2 deletions ui/cryptomaterial/dropdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type DropDown struct {
dropdownIcon *widget.Icon
navigationIcon *widget.Icon
clickable *Clickable
maxTextLeng int

group uint
closeAllDropdown func(group uint)
Expand Down Expand Up @@ -223,8 +224,15 @@ func (d *DropDown) Reversed() bool {
return d.revs
}

func (d *DropDown) SetMaxTextLeng(leng int) {
d.maxTextLeng = leng
}

func (d *DropDown) Layout(gtx C) D {
d.handleEvents()
if d.maxTextLeng == 0 {
d.maxTextLeng = maxDropdownItemTextLen
}

if d.MakeCollapsedLayoutVisibleWhenExpanded {
return d.collapsedAndExpandedLayout(gtx)
Expand Down Expand Up @@ -351,8 +359,8 @@ func (d *DropDown) itemLayout(gtx C, index int, clickable *Clickable, item *Drop

return bodyLayout.Layout2(gtx, func(gtx C) D {
lbl := d.theme.Body2(item.Text)
if !d.expanded && len(item.Text) > maxDropdownItemTextLen {
lbl.Text = item.Text[:maxDropdownItemTextLen-3 /* subtract space for the ellipsis */] + "..."
if !d.expanded && len(item.Text) > d.maxTextLeng {
lbl.Text = item.Text[:d.maxTextLeng-3 /* subtract space for the ellipsis */] + "..."
}
lbl.Font.Weight = d.FontWeight
lbl.TextSize = d.getTextSize(values.TextSize14)
Expand Down
13 changes: 5 additions & 8 deletions ui/cryptomaterial/segmented_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ func (sc *SegmentedControl) Layout(gtx C, body func(gtx C) D, isMobileView ...bo
if sc.disableUniformPadding {
return widget(gtx)
}

return UniformPadding(gtx, widget, sc.isMobileView)
}

Expand All @@ -147,13 +146,10 @@ func (sc *SegmentedControl) GroupTileLayout(gtx C) D {
return sc.slideActionTitle.DragLayout(gtx, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
textSize := values.TextSize16
if sc.isMobileView {
textSize = values.TextSize12
}
textSize16 := values.TextSizeTransform(sc.isMobileView, values.TextSize16)
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.SurfaceHighlight
txt := sc.theme.DecoratedText(textSize, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
txt := sc.theme.DecoratedText(textSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
border := Border{Radius: Radius(0)}
if isSelectedSegment {
bg = sc.theme.Color.Surface
Expand Down Expand Up @@ -247,12 +243,13 @@ func (sc *SegmentedControl) groupTileMaxLayout(gtx C) D {
Border: Border{Radius: Radius(8)},
}.Layout(gtx,
layout.Rigid(func(gtx C) D {
textSize16 := values.TextSizeTransform(sc.isMobileView, values.TextSize16)
return sc.slideActionTitle.DragLayout(gtx, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.SurfaceHighlight
txt := sc.theme.DecoratedText(values.TextSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
txt := sc.theme.DecoratedText(textSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
border := Border{Radius: Radius(0)}
if isSelectedSegment {
bg = sc.theme.Color.Surface
Expand Down Expand Up @@ -286,7 +283,7 @@ func (sc *SegmentedControl) dynamicSplitTileLayout(gtx C) D {
isSelectedSegment := sc.SelectedIndex() == i
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.Surface
txt := sc.theme.DecoratedText(values.TextSize14, sc.segmentTitles[i], sc.theme.Color.GrayText2, font.SemiBold)
txt := sc.theme.DecoratedText(values.TextSizeTransform(sc.isMobileView, values.TextSize14), sc.segmentTitles[i], sc.theme.Color.GrayText2, font.SemiBold)
border := Border{Radius: Radius(12), Color: sc.theme.Color.Gray10}
if isSelectedSegment {
bg = sc.theme.Color.Gray2
Expand Down
15 changes: 7 additions & 8 deletions ui/page/components/fee_rate_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func NewFeeRateSelector(l *load.Load, callback walletTypeCallbackFunc) *FeeRateS
Top: values.MarginPadding4,
}

fs.SaveRate.TextSize = values.TextSize16
fs.SaveRate.TextSize = values.TextSizeTransform(fs.IsMobileView(), values.TextSize16)
fs.SaveRate.Inset = layout.Inset{
Top: values.MarginPadding12,
Right: values.MarginPadding16,
Expand Down Expand Up @@ -117,6 +117,7 @@ func (fs *FeeRateSelector) Layout(gtx C) D {
}.Layout(gtx,
layout.Rigid(func(gtx C) D {
title := fs.Theme.Body1(values.String(values.StrFeeRates))
title.TextSize = values.TextSizeTransform(fs.IsMobileView(), values.TextSize16)
title.Font.Weight = font.SemiBold
return layout.Inset{Bottom: values.MarginPadding4}.Layout(gtx, title.Layout)
}),
Expand All @@ -137,10 +138,7 @@ func (fs *FeeRateSelector) Layout(gtx C) D {
},
}
return border.Layout(gtx, func(gtx C) D {
return layout.Inset{
Top: values.MarginPadding4,
Bottom: values.MarginPadding4,
}.Layout(gtx, fs.ratesEditor.Layout)
return VerticalInset(values.MarginPadding4).Layout(gtx, fs.ratesEditor.Layout)
})
}),
layout.Rigid(func(gtx C) D {
Expand All @@ -157,11 +155,11 @@ func (fs *FeeRateSelector) Layout(gtx C) D {
}

if fs.feeRateSwitch.SelectedSegment() == values.String(values.StrFetched) {
fs.fetchedRatesDropDown.Width = values.MarginPadding510
fs.fetchedRatesDropDown.Width = gtx.Metric.PxToDp(gtx.Constraints.Max.X)
layoutBody = fs.fetchedRatesDropDown.Layout
}

return fs.feeRateSwitch.Layout(gtx, layoutBody)
return fs.feeRateSwitch.Layout(gtx, layoutBody, fs.IsMobileView())
}),
layout.Rigid(func(gtx C) D {
col := fs.Theme.Color.GrayText2
Expand All @@ -182,7 +180,7 @@ func (fs *FeeRateSelector) Layout(gtx C) D {
col = fs.Theme.Color.Danger
}

lbl := fs.Theme.Label(values.TextSize14, txt)
lbl := fs.Theme.Label(values.TextSizeTransform(fs.IsMobileView(), values.TextSize14), txt)
lbl.Color = col
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return layout.Inset{Top: values.MarginPadding4}.Layout(gtx, func(gtx C) D {
Expand Down Expand Up @@ -231,6 +229,7 @@ func (fs *FeeRateSelector) UpdatedFeeRate(selectedWallet sharedW.Asset) {
fs.fetchedRatesDropDown.ExpandedLayoutInset = layout.Inset{Top: values.MarginPadding35}
fs.fetchedRatesDropDown.MakeCollapsedLayoutVisibleWhenExpanded = true
fs.fetchedRatesDropDown.Background = &fs.Theme.Color.Gray4
fs.fetchedRatesDropDown.SetMaxTextLeng(30)
}

// OnEditRateCliked is called when the edit feerate button is clicked.
Expand Down
4 changes: 4 additions & 0 deletions ui/page/root/home_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ func (hp *HomePage) HandleUserInteractions() {
if strings.ToLower(item.PageID) == values.StrReceive {
hp.ParentWindow().ShowModal(NewReceivePage(hp.Load, nil))
}

if strings.ToLower(item.PageID) == values.StrSend {
hp.ParentWindow().ShowModal(send.NewSendPage(hp.Load, nil))
}
}
}
}
Expand Down
130 changes: 70 additions & 60 deletions ui/page/send/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,22 @@ func (pg *Page) initLayoutWidgets() {
// to be eventually drawn on screen.
// Part of the load.Page interface.
func (pg *Page) Layout(gtx C) D {
if pg.modalLayout != nil {
modalContent := []layout.Widget{pg.layoutDesktop}
return pg.modalLayout.Layout(gtx, modalContent, 450)
if pg.modalLayout == nil {
return pg.contentLayout(gtx)
}
var modalWidth float32 = 450
if pg.IsMobileView() {
modalWidth = 0
}
return pg.layoutDesktop(gtx)
modalContent := []layout.Widget{pg.contentLayout}
return pg.modalLayout.Layout(gtx, modalContent, modalWidth)
}

func (pg *Page) layoutDesktop(gtx C) D {
func (pg *Page) contentLayout(gtx C) D {
pageContent := []func(gtx C) D{
pg.sendLayout,
pg.recipientsLayout,
}

if pg.modalLayout == nil || (pg.modalLayout != nil && pg.selectedWallet.GetAssetType() != libutils.DCRWalletAsset) {
pageContent = append(pageContent, pg.advanceOptionsLayout)
pg.advanceOptionsLayout,
}

cgtx := gtx
Expand All @@ -71,7 +72,7 @@ func (pg *Page) layoutDesktop(gtx C) D {
return layout.Stack{}.Layout(gtx,
layout.Expanded(func(gtx C) D {
return pg.Theme.List(pg.pageContainer).Layout(gtx, len(pageContent), func(gtx C, i int) D {
mp := values.MarginPadding32
mp := values.MarginPaddingTransform(pg.IsMobileView(), values.MarginPadding32)
if i == len(pageContent)-1 {
mp = values.MarginPadding0
}
Expand Down Expand Up @@ -116,7 +117,7 @@ func (pg *Page) sendLayout(gtx C) D {
if pg.selectedWallet.IsSynced() {
return D{}
}
txt := pg.Theme.Label(values.TextSize14, values.String(values.StrFunctionUnavailable))
txt := pg.Theme.Label(values.TextSizeTransform(pg.IsMobileView(), values.TextSize14), values.String(values.StrFunctionUnavailable))
txt.Font.Weight = font.SemiBold
txt.Color = pg.Theme.Color.Danger
return layout.Inset{Top: values.MarginPadding4}.Layout(gtx, txt.Layout)
Expand All @@ -129,7 +130,7 @@ func (pg *Page) titleLayout(gtx C) D {
return layout.Flex{}.Layout(gtx,
layout.Rigid(func(gtx C) D {
return layout.Inset{Right: values.MarginPadding6}.Layout(gtx, func(gtx C) D {
lbl := pg.Theme.Label(values.TextSize20, values.String(values.StrSend))
lbl := pg.Theme.Label(values.TextSizeTransform(pg.IsMobileView(), values.TextSize20), values.String(values.StrSend))
lbl.Font.Weight = font.SemiBold
return lbl.Layout(gtx)
})
Expand All @@ -143,7 +144,7 @@ func (pg *Page) recipientsLayout(gtx C) D {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
recipient := pg.recipient.recipientLayout(1, false, pg.ParentWindow())
return layout.Inset{Bottom: values.MarginPadding24}.Layout(gtx, recipient)
return recipient(gtx)
}),
// TODO: to be implemented in follow up PR.
// layout.Rigid(func(gtx C) D {
Expand All @@ -166,37 +167,41 @@ func (pg *Page) recipientsLayout(gtx C) D {
}

func (pg *Page) advanceOptionsLayout(gtx C) D {
return pg.sectionWrapper(gtx, func(gtx C) D {
collapsibleHeader := func(gtx C) D {
lbl := pg.Theme.Label(values.TextSize16, values.String(values.StrAdvancedOptions))
lbl.Font.Weight = font.SemiBold
return lbl.Layout(gtx)
}

collapsibleBody := func(gtx C) D {
if pg.selectedWallet.GetAssetType() == libutils.DCRWalletAsset {
return layout.Inset{
Top: values.MarginPadding16,
}.Layout(gtx, func(gtx C) D {
return pg.contentWrapper(gtx, values.String(values.StrCoinSelection), true, pg.coinSelectionSection)
})
marginMinus32 := values.MarginPadding0
if pg.modalLayout != nil {
marginMinus32 = values.MarginPaddingMinus32
}
if pg.IsMobileView() {
marginMinus32 = values.MarginPaddingMinus16
}
return layout.Inset{Top: marginMinus32}.Layout(gtx, func(gtx C) D {
return pg.sectionWrapper(gtx, func(gtx C) D {
collapsibleHeader := func(gtx C) D {
lbl := pg.Theme.Label(values.TextSizeTransform(pg.IsMobileView(), values.TextSize16), values.String(values.StrAdvancedOptions))
lbl.Font.Weight = font.SemiBold
return lbl.Layout(gtx)
}

if pg.modalLayout != nil {
// coin selection not allowed on the send modal
return pg.contentWrapper(gtx, "", true, pg.feeRateSelector.Layout)
}
collapsibleBody := func(gtx C) D {
if pg.selectedWallet.GetAssetType() == libutils.DCRWalletAsset {
return layout.Inset{
Top: values.MarginPadding16,
}.Layout(gtx, func(gtx C) D {
return pg.contentWrapper(gtx, values.String(values.StrCoinSelection), true, pg.coinSelectionSection)
})
}

return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
return pg.contentWrapper(gtx, "", false, pg.feeRateSelector.Layout)
}),
layout.Rigid(func(gtx C) D {
return pg.contentWrapper(gtx, values.String(values.StrCoinSelection), true, pg.coinSelectionSection)
}),
)
}
return pg.advanceOptions.Layout(gtx, collapsibleHeader, collapsibleBody)
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
return pg.contentWrapper(gtx, "", false, pg.feeRateSelector.Layout)
}),
layout.Rigid(func(gtx C) D {
return pg.contentWrapper(gtx, values.String(values.StrCoinSelection), true, pg.coinSelectionSection)
}),
)
}
return pg.advanceOptions.Layout(gtx, collapsibleHeader, collapsibleBody)
})
})
}

Expand All @@ -216,22 +221,22 @@ func (pg *Page) coinSelectionSection(gtx C) D {
return pg.Theme.Card().Layout(gtx, func(gtx C) D {
inset := layout.UniformInset(values.MarginPadding15)
return inset.Layout(gtx, func(gtx C) D {
textLabel := pg.Theme.Label(values.TextSize16, selectedOption)
textLabel := pg.Theme.Label(values.TextSizeTransform(pg.IsMobileView(), values.TextSize16), selectedOption)
textLabel.Font.Weight = font.SemiBold
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(textLabel.Layout),
layout.Flexed(1, func(gtx C) D {
return layout.E.Layout(gtx, func(gtx C) D {
return cryptomaterial.LinearLayout{
Width: cryptomaterial.WrapContent,
Height: cryptomaterial.WrapContent,
Orientation: layout.Horizontal,
Alignment: layout.Middle,
Clickable: pg.toCoinSelection,
}.Layout2(gtx, pg.Theme.Icons.ChevronRight.Layout20dp)
})
}),
)
return cryptomaterial.LinearLayout{
Width: cryptomaterial.WrapContent,
Height: cryptomaterial.WrapContent,
Orientation: layout.Horizontal,
Alignment: layout.Middle,
Clickable: pg.toCoinSelection,
}.Layout2(gtx, func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceBetween}.Layout(gtx,
layout.Rigid(textLabel.Layout),
layout.Rigid(pg.Theme.Icons.ChevronRight.Layout20dp),
)
})

})
})
})
Expand Down Expand Up @@ -279,11 +284,15 @@ func (pg *Page) balanceSection(gtx C) D {
}

func (pg *Page) sectionWrapper(gtx C, body layout.Widget) D {
margin16 := values.MarginPadding16
if pg.modalLayout != nil {
margin16 = values.MarginPadding0
}
return cryptomaterial.LinearLayout{
Width: cryptomaterial.MatchParent,
Height: cryptomaterial.WrapContent,
Orientation: layout.Vertical,
Padding: layout.UniformInset(values.MarginPadding16),
Padding: layout.UniformInset(margin16),
Background: pg.Theme.Color.Surface,
Border: cryptomaterial.Border{
Radius: cryptomaterial.Radius(8),
Expand All @@ -304,7 +313,7 @@ func (pg *Page) contentWrapper(gtx C, title string, zeroBottomPadding bool, cont
}.Layout(gtx, func(gtx C) D {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
lbl := pg.Theme.Label(values.TextSize16, title)
lbl := pg.Theme.Label(values.TextSizeTransform(pg.IsMobileView(), values.TextSize16), title)
lbl.Font.Weight = font.SemiBold
return layout.Inset{
Bottom: values.MarginPadding4,
Expand All @@ -316,17 +325,18 @@ func (pg *Page) contentWrapper(gtx C, title string, zeroBottomPadding bool, cont
}

func (pg *Page) contentRow(gtx C, leftValue, rightValue string) D {
textSize := values.TextSizeTransform(pg.IsMobileView(), values.TextSize16)
return layout.Flex{}.Layout(gtx,
layout.Rigid(func(gtx C) D {
lbl := pg.Theme.Label(values.TextSize16, leftValue)
lbl := pg.Theme.Label(textSize, leftValue)
lbl.Color = pg.Theme.Color.GrayText2
return lbl.Layout(gtx)
}),
layout.Flexed(1, func(gtx C) D {
return layout.E.Layout(gtx, func(gtx C) D {
return layout.Flex{}.Layout(gtx,
layout.Rigid(func(gtx C) D {
lbl := pg.Theme.Label(values.TextSize16, rightValue)
lbl := pg.Theme.Label(textSize, rightValue)
lbl.Color = pg.Theme.Color.Text
lbl.Font.Weight = font.SemiBold
return lbl.Layout(gtx)
Expand Down