Skip to content

feat(perps): add TradingView candle chart#6513

Open
SeniorZhai wants to merge 8 commits into
masterfrom
feat/tradingview-candle-chart
Open

feat(perps): add TradingView candle chart#6513
SeniorZhai wants to merge 8 commits into
masterfrom
feat/tradingview-candle-chart

Conversation

@SeniorZhai

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings July 22, 2026 04:25
@SeniorZhai SeniorZhai added the testing Now testing, but you can review label Jul 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in TradingView candlestick chart and localized market descriptions to perps market details.

Changes:

  • Adds TradingView chart rendering, attribution, and a debug preference toggle.
  • Persists and displays localized perps market descriptions.
  • Adds the Room migration and migration test for descriptions.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
build.gradle.kts Defines the chart library version.
app/build.gradle.kts Adds the TradingView dependency.
Constants.kt Defines the chart preference key.
TradingViewCandleChart.kt Implements the TradingView chart.
CandleChart.kt Selects the configured chart implementation.
PerpsMarketDetailPage.kt Displays localized market information.
PerpsMarket.kt Adds market descriptions.
PerpsDatabase.kt Adds database migration 5→6.
PerpsMigrationTest.kt Tests the migration.
6.json Records Room schema version 6.
LogAndDebugFragment.kt Manages the chart toggle.
fragment_log_debug.xml Adds the toggle UI.
AboutPage.kt Adds Compose attribution.
AboutFragment.kt Adds legacy attribution behavior.
fragment_about.xml Adds legacy attribution UI.
values/strings.xml Adds English labels.
values-zh-rCN/strings.xml Adds Simplified Chinese labels.
values-zh-rTW/strings.xml Adds Traditional Chinese labels.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +181 to +189
CandlestickSeriesOptions(
upColor = upColor.toArgb().toIntColor(),
downColor = downColor.toArgb().toIntColor(),
wickUpColor = upColor.toArgb().toIntColor(),
wickDownColor = downColor.toArgb().toIntColor(),
borderVisible = false,
lastValueVisible = false,
priceLineVisible = false,
),
Comment on lines +214 to +219
object : GestureDetector.SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
longPressActive = true
targetView?.requestDisallowInterceptTouchEvent(true)
}
},
Copilot AI review requested due to automatic review settings July 22, 2026 05:06
@SeniorZhai
SeniorZhai force-pushed the feat/tradingview-candle-chart branch from 5029c67 to 72497c2 Compare July 22, 2026 05:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.

Comment thread app/src/main/res/values/strings.xml Outdated
<string name="a_video">a video</string>
<string name="About">About</string>
<string name="Use_TradingView_Candlestick_Chart">Use TradingView candlestick chart</string>
<string name="Charts_by_TradingView">Charts by TradingView</string>
Comment on lines +100 to +108
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:text="@string/Use_TradingView_Candlestick_Chart"
android:textColor="@color/colorBlue"
android:textSize="16sp"
tools:ignore="RelativeOverlap" />
Keep the existing renderer as default and expose TradingView through Log & Debug for comparison.
Copilot AI review requested due to automatic review settings July 22, 2026 05:33
@SeniorZhai
SeniorZhai force-pushed the feat/tradingview-candle-chart branch from 72497c2 to ddacb27 Compare July 22, 2026 05:33
@SeniorZhai SeniorZhai changed the title feat(perps): add market about and TradingView chart feat(perps): add TradingView candle chart Jul 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Comment on lines +113 to +124
time = Time.Utc(item.timestamp),
open = open,
high = high,
low = low,
close = close,
)
}
}
val candlesByTimestamp =
remember(candles) {
candles.firstOrNull()?.items.orEmpty().associateBy(CandleItem::timestamp)
}
),
)
subscribeOnChartStateChange { state ->
errorMessage = (state as? ChartsView.State.Error)?.exception?.localizedMessage
Comment on lines +110 to +117
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/trading_view_chart_sc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
tools:ignore="RelativeOverlap" />
Copilot AI review requested due to automatic review settings July 22, 2026 09:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

app/src/main/java/one/mixin/android/ui/home/web3/trade/TradingViewCandleChart.kt:113

  • The candle API timestamps are milliseconds (the iOS client consuming the same endpoint converts item.timestamp / 1000), but lightweight-charts v4 Time.Utc expects epoch seconds. Passing the raw value places every candle tens of thousands of years in the future. Convert to seconds here and key the crosshair lookup by that converted value as well.
                        time = Time.Utc(item.timestamp),

Copilot AI review requested due to automatic review settings July 22, 2026 09:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

app/src/main/java/one/mixin/android/ui/home/web3/trade/TradingViewCandleChart.kt:113

  • CandleItem.timestamp is epoch milliseconds, but TradingView v4's Time.Utc expects epoch seconds. Passing the raw value makes chart dates and candle intervals 1,000× too large. Normalize both the series data and the crosshair lookup keys to seconds so tooltip selection still resolves the corresponding candle.
                        time = Time.Utc(item.timestamp),

timeFrame: String,
): String {
val millis = if (timestamp < MILLIS_TIMESTAMP_THRESHOLD) timestamp * 1000 else timestamp
val zoneId = ZoneId.systemDefault()
pinch = true
}
}
chartApi = api
Copilot AI review requested due to automatic review settings July 22, 2026 09:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

app/src/main/java/one/mixin/android/ui/home/web3/trade/TradingViewCandleChart.kt:113

  • Time.Utc in lightweight-charts v4 expects epoch seconds, while perps candle timestamps are epoch milliseconds. Passing milliseconds places every bar far in the future; normalize both the series time and lookup-map key so crosshair selections still resolve.
                        time = Time.Utc(item.timestamp),

Copilot AI review requested due to automatic review settings July 22, 2026 10:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment on lines +472 to +474
val utcTimestamp = normalizeTradingViewTimestamp(timestamp)
val offsetSeconds = Instant.ofEpochSecond(utcTimestamp).atZone(zoneId).offset.totalSeconds
return utcTimestamp + offsetSeconds
Copilot AI review requested due to automatic review settings July 22, 2026 10:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

app/src/main/java/one/mixin/android/ui/home/web3/trade/TradingViewCandleChart.kt:476

  • This offset-based conversion collapses distinct candles during the daylight-saving fall-back hour (for example, 05:30Z at UTC-4 and 06:30Z at UTC-5 both become 01:30). That produces duplicate Time.Utc values for setData, and candlesByTimestamp.associateBy also overwrites one candle. Keep normalized UTC epoch seconds as the chart/key identity and apply the local zone only when formatting labels.
    val utcTimestamp = normalizeTradingViewTimestamp(timestamp)
    val offsetSeconds = Instant.ofEpochSecond(utcTimestamp).atZone(zoneId).offset.totalSeconds
    return utcTimestamp + offsetSeconds

app/src/main/res/layout/fragment_log_debug.xml:110

  • The new switch has no accessible name: its sibling TextView is not associated with it via labelFor, so TalkBack announces only an unlabeled switch state. Give the switch this string as its content description (or explicitly associate the label) so users know what it controls.
                <androidx.appcompat.widget.SwitchCompat

Comment on lines +37 to +40
assertEquals(
utcTimestamp + 8 * 60 * 60,
tradingViewLocalTimestamp(utcTimestamp, ZoneOffset.ofHours(8)),
)
Comment on lines +47 to +50
assertEquals(
1_721_600_000L + 8 * 60 * 60,
tradingViewLocalTimestamp(utcTimestampMillis, ZoneOffset.ofHours(8)),
)
Copilot AI review requested due to automatic review settings July 22, 2026 11:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

app/src/main/java/one/mixin/android/ui/home/web3/trade/TradingViewCandleChart.kt:475

  • Adding each instant's zone offset makes timestamps collide during a daylight-saving fall-back. For example, consecutive 01:00 EDT and 01:00 EST candles both map to the same shifted epoch value; setData requires strictly ascending candle times, and associateBy also drops one of them. Preserve unique UTC timestamps and localize labels separately (or use another monotonic timezone strategy), with a DST-boundary test.
    val utcTimestamp = normalizeTradingViewTimestamp(timestamp)
    val offsetSeconds = Instant.ofEpochSecond(utcTimestamp).atZone(zoneId).offset.totalSeconds
    return utcTimestamp + offsetSeconds

app/src/main/res/layout/fragment_log_debug.xml:117

  • The switch has no accessible label, so a screen reader announces only an unlabeled on/off control. Associate the visible text with this switch or provide an equivalent content description.
                <androidx.appcompat.widget.SwitchCompat
                        android:id="@+id/trading_view_chart_sc"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_centerVertical="true"
                        android:layout_marginEnd="@dimen/activity_horizontal_margin"
                        tools:ignore="RelativeOverlap" />

Comment on lines +489 to +492
internal fun tradingViewTouchCoordinate(
touchX: Float,
density: Float,
): Float = if (density > 0f) touchX / density else touchX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Now testing, but you can review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants