Skip to content

Commit c1ab51c

Browse files
authored
Merge pull request #77 from usetrmnl/76-fix-user-right-api-for-device-type
[FIXED] Use display API for BYOD and BYOS device/service type
2 parents 5e19f0a + 5a046aa commit c1ab51c

File tree

4 files changed

+246
-86
lines changed

4 files changed

+246
-86
lines changed

app/src/main/java/ink/trmnl/android/data/TrmnlDisplayRepository.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ class TrmnlDisplayRepository
4141
* @return A [TrmnlDisplayInfo] object containing the display data.
4242
*/
4343
suspend fun getNextDisplayData(trmnlDeviceConfig: TrmnlDeviceConfig): TrmnlDisplayInfo {
44+
Timber.i("Fetching next playlist item display data from server for device: ${trmnlDeviceConfig.type}")
45+
4446
if (repositoryConfigProvider.shouldUseFakeData) {
4547
// Avoid using real API in debug mode
4648
return fakeTrmnlDisplayInfo(apiUsed = "next-image")
4749
}
4850

49-
Timber.i("Fetching next playlist item display data from server")
50-
5151
val result =
5252
apiService
5353
.getNextDisplayData(
@@ -90,17 +90,24 @@ class TrmnlDisplayRepository
9090
* Fetches the current display data from the server using the provided access token.
9191
* If the app is in debug mode, it uses mock data instead.
9292
*
93+
* ⚠️ NOTE: This API is not available on BYOS servers.
94+
* See https://discord.com/channels/1281055965508141100/1331360842809348106/1382863253880963124
95+
*
9396
* @param trmnlDeviceConfig Device configuration containing the access token and other settings.
9497
* @return A [TrmnlDisplayInfo] object containing the current display data.
9598
*/
9699
suspend fun getCurrentDisplayData(trmnlDeviceConfig: TrmnlDeviceConfig): TrmnlDisplayInfo {
100+
Timber.i("Fetching current display data from server for device: ${trmnlDeviceConfig.type}")
101+
102+
if (trmnlDeviceConfig.type == TrmnlDeviceType.BYOS) {
103+
Timber.w("Current display image data API is not available for BYOS service.")
104+
}
105+
97106
if (repositoryConfigProvider.shouldUseFakeData) {
98107
// Avoid using real API in debug mode
99108
return fakeTrmnlDisplayInfo(apiUsed = "current-image")
100109
}
101110

102-
Timber.i("Fetching current display data from server")
103-
104111
val result =
105112
apiService
106113
.getCurrentDisplayData(

app/src/main/java/ink/trmnl/android/ui/settings/AppSettingsScreen.kt

Lines changed: 20 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import androidx.compose.material.icons.Icons
2929
import androidx.compose.material.icons.automirrored.filled.ArrowBack
3030
import androidx.compose.material.icons.filled.Clear
3131
import androidx.compose.material.icons.filled.DateRange
32-
import androidx.compose.material.icons.outlined.Info
3332
import androidx.compose.material.icons.outlined.Warning
3433
import androidx.compose.material3.Button
3534
import androidx.compose.material3.ButtonDefaults
@@ -62,22 +61,14 @@ import androidx.compose.ui.Modifier
6261
import androidx.compose.ui.layout.ContentScale
6362
import androidx.compose.ui.platform.LocalContext
6463
import androidx.compose.ui.platform.LocalFocusManager
65-
import androidx.compose.ui.platform.LocalUriHandler
6664
import androidx.compose.ui.res.painterResource
67-
import androidx.compose.ui.text.LinkAnnotation
68-
import androidx.compose.ui.text.SpanStyle
69-
import androidx.compose.ui.text.TextLinkStyles
70-
import androidx.compose.ui.text.buildAnnotatedString
7165
import androidx.compose.ui.text.font.FontStyle
7266
import androidx.compose.ui.text.font.FontWeight
7367
import androidx.compose.ui.text.input.ImeAction
7468
import androidx.compose.ui.text.input.KeyboardType
7569
import androidx.compose.ui.text.input.PasswordVisualTransformation
7670
import androidx.compose.ui.text.input.VisualTransformation
7771
import androidx.compose.ui.text.style.TextAlign
78-
import androidx.compose.ui.text.style.TextDecoration
79-
import androidx.compose.ui.text.withLink
80-
import androidx.compose.ui.text.withStyle
8172
import androidx.compose.ui.tooling.preview.Preview
8273
import androidx.compose.ui.unit.dp
8374
import androidx.work.WorkInfo
@@ -276,19 +267,30 @@ class AppSettingsPresenter
276267
if (deviceType == TrmnlDeviceType.BYOS) {
277268
if (!isValidUrl(serverBaseUrl)) {
278269
isLoading = false
279-
validationResult = InvalidServerUrl("Please enter a valid URL (e.g. https://example.com)")
270+
validationResult = InvalidServerUrl("Please enter a valid HTTPS URL (e.g. https://my-terminus.com)")
280271
return@launch
281272
}
282273
}
283274

284-
val response =
285-
displayRepository.getCurrentDisplayData(
286-
TrmnlDeviceConfig(
287-
type = deviceType,
288-
apiBaseUrl = serverBaseUrl.forDevice(deviceType),
289-
apiAccessToken = accessToken,
290-
),
275+
// Device configuration for API calls
276+
val deviceConfig =
277+
TrmnlDeviceConfig(
278+
type = deviceType,
279+
apiBaseUrl = serverBaseUrl.forDevice(deviceType),
280+
apiAccessToken = accessToken,
291281
)
282+
// For TRMNL mirror device type, use getCurrentDisplayData
283+
// For all other device types, use getNextDisplayData
284+
// See https://discord.com/channels/1281055965508141100/1331360842809348106/1382865608236077086
285+
val response =
286+
when (deviceType) {
287+
TrmnlDeviceType.TRMNL -> {
288+
displayRepository.getCurrentDisplayData(deviceConfig)
289+
}
290+
else -> {
291+
displayRepository.getNextDisplayData(deviceConfig)
292+
}
293+
}
292294

293295
if (response.status.isHttpError()) {
294296
// Handle explicit error response
@@ -528,7 +530,7 @@ fun AppSettingsContent(
528530

529531
Spacer(modifier = Modifier.height(8.dp))
530532

531-
TokenInfoTextView()
533+
SwitchDeviceTypeInfoText(deviceType = state.deviceType)
532534

533535
Spacer(modifier = Modifier.height(16.dp))
534536

@@ -868,61 +870,6 @@ private fun FakeApiInfoBanner(modifier: Modifier = Modifier) {
868870
}
869871
}
870872

871-
@Composable
872-
private fun TokenInfoTextView() {
873-
// Informational text with links using withLink
874-
val uriHandler = LocalUriHandler.current
875-
val linkStyle = SpanStyle(color = MaterialTheme.colorScheme.primary, textDecoration = TextDecoration.Underline)
876-
val annotatedString =
877-
buildAnnotatedString {
878-
append("Your TRMNL device token can be found in settings screen from your ")
879-
880-
withLink(
881-
LinkAnnotation.Url(
882-
url = "https://usetrmnl.com/dashboard",
883-
styles = TextLinkStyles(style = linkStyle),
884-
linkInteractionListener = { uriHandler.openUri("https://usetrmnl.com/dashboard") },
885-
),
886-
) {
887-
withStyle(style = linkStyle) {
888-
append("dashboard")
889-
}
890-
}
891-
892-
append(". ")
893-
894-
withLink(
895-
LinkAnnotation.Url(
896-
url = "https://docs.usetrmnl.com/go/private-api/introduction",
897-
styles = TextLinkStyles(style = linkStyle),
898-
linkInteractionListener = { uriHandler.openUri("https://docs.usetrmnl.com/go/private-api/introduction") },
899-
),
900-
) {
901-
withStyle(style = linkStyle) {
902-
append("Learn more")
903-
}
904-
}
905-
906-
append(".")
907-
}
908-
909-
Row(
910-
modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp),
911-
verticalAlignment = Alignment.CenterVertically,
912-
) {
913-
Icon(
914-
imageVector = Icons.Outlined.Info,
915-
contentDescription = "Information",
916-
tint = MaterialTheme.colorScheme.onSurfaceVariant,
917-
)
918-
Spacer(modifier = Modifier.width(4.dp))
919-
Text(
920-
text = annotatedString,
921-
style = MaterialTheme.typography.bodySmall.copy(color = MaterialTheme.colorScheme.onSurfaceVariant),
922-
)
923-
}
924-
}
925-
926873
@Preview(name = "App Settings Content - Initial State")
927874
@Composable
928875
private fun PreviewAppSettingsContentInitial() {
@@ -1093,11 +1040,3 @@ private fun PreviewFakeApiInfoBanner() {
10931040
FakeApiInfoBanner()
10941041
}
10951042
}
1096-
1097-
@Preview(name = "Info Text View Preview", showBackground = true)
1098-
@Composable
1099-
private fun PreviewInfoTextView() {
1100-
TrmnlDisplayAppTheme {
1101-
TokenInfoTextView()
1102-
}
1103-
}

0 commit comments

Comments
 (0)