feat: brand logos for Bark/ntfy channel marks + icons for email/SMS
- Bark: official logo from Finb/Bark repo (ic_bark_logo.png) - ntfy: official logo from binwiederhier/ntfy repo (ic_ntfy_logo.png) - Meow: Material Pets icon (paw) — no official logo found - Email: Material Email icon - SMS: Material Sms icon - ChannelMark now supports both ImageVector and Painter (PNG logo) - SectionCard gains optional titleIcon parameter - version 1.8.9 -> 1.8.10 (code 26 -> 27) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -68,6 +69,8 @@ fun SectionCard(
|
||||
title: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
subtitle: String? = null,
|
||||
titleIcon: ImageVector? = null,
|
||||
titleIconTint: Color = MaterialTheme.colorScheme.primary,
|
||||
headerAction: (@Composable () -> Unit)? = null,
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
@@ -81,12 +84,18 @@ fun SectionCard(
|
||||
Column(Modifier.padding(16.dp)) {
|
||||
if (title != null) {
|
||||
if (headerAction == null) {
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.padding(bottom = if (subtitle == null) 10.dp else 2.dp),
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (titleIcon != null) {
|
||||
Icon(titleIcon, null, tint = titleIconTint, modifier = Modifier.size(22.dp))
|
||||
Spacer(Modifier.width(8.dp))
|
||||
}
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.padding(bottom = if (subtitle == null) 10.dp else 2.dp),
|
||||
)
|
||||
}
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
subtitle,
|
||||
@@ -103,12 +112,18 @@ fun SectionCard(
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.padding(bottom = if (subtitle == null) 0.dp else 2.dp),
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (titleIcon != null) {
|
||||
Icon(titleIcon, null, tint = titleIconTint, modifier = Modifier.size(22.dp))
|
||||
Spacer(Modifier.width(8.dp))
|
||||
}
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.padding(bottom = if (subtitle == null) 0.dp else 2.dp),
|
||||
)
|
||||
}
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
subtitle,
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.net.Uri
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
@@ -26,11 +27,15 @@ import androidx.compose.material.icons.automirrored.filled.Send
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.filled.Email
|
||||
import androidx.compose.material.icons.filled.History
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||
import androidx.compose.material.icons.filled.Notifications
|
||||
import androidx.compose.material.icons.filled.Pets
|
||||
import androidx.compose.material.icons.filled.RestartAlt
|
||||
import androidx.compose.material.icons.filled.Sms
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.filled.SystemUpdateAlt
|
||||
import androidx.compose.material.icons.filled.Update
|
||||
@@ -57,12 +62,16 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.a2i.forwarder.A2iApp
|
||||
import com.a2i.forwarder.R
|
||||
import com.a2i.forwarder.core.BarkClient
|
||||
import com.a2i.forwarder.core.EmailSender
|
||||
import com.a2i.forwarder.core.IconExporter
|
||||
@@ -167,6 +176,7 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
|
||||
summary = "iPhone / iPad 推送目标",
|
||||
mark = "B",
|
||||
markColor = Color(0xFFFF9800),
|
||||
markLogo = painterResource(R.drawable.ic_bark_logo),
|
||||
platforms = listOf("iOS"),
|
||||
stopFirst = barkStopFirst,
|
||||
onStopFirstChange = { v -> app.appScope.launch { app.settings.setBarkStopOnFirst(v) } },
|
||||
@@ -199,6 +209,7 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
|
||||
summary = "Android / iOS topic 推送",
|
||||
mark = "n",
|
||||
markColor = Color(0xFF43A047),
|
||||
markLogo = painterResource(R.drawable.ic_ntfy_logo),
|
||||
platforms = listOf("Android", "iOS"),
|
||||
stopFirst = ntfyStopFirst,
|
||||
onStopFirstChange = { v -> app.appScope.launch { app.settings.setNtfyStopOnFirst(v) } },
|
||||
@@ -234,6 +245,7 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
|
||||
summary = "鸿蒙手机推送目标",
|
||||
mark = "M",
|
||||
markColor = Color(0xFF7E57C2),
|
||||
markIcon = Icons.Filled.Pets,
|
||||
platforms = listOf("HarmonyOS"),
|
||||
stopFirst = meowStopFirst,
|
||||
onStopFirstChange = { v -> app.appScope.launch { app.settings.setMeowStopOnFirst(v) } },
|
||||
@@ -269,6 +281,7 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
|
||||
summary = "SMTP 邮箱推送目标",
|
||||
mark = "@",
|
||||
markColor = Color(0xFF1976D2),
|
||||
markIcon = Icons.Filled.Email,
|
||||
platforms = listOf("Email"),
|
||||
stopFirst = emailStopFirst,
|
||||
onStopFirstChange = { v -> app.appScope.launch { app.settings.setEmailStopOnFirst(v) } },
|
||||
@@ -302,6 +315,7 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
|
||||
summary = "无网络时发送关键通知",
|
||||
mark = "S",
|
||||
markColor = Color(0xFF00897B),
|
||||
markIcon = Icons.Filled.Sms,
|
||||
platforms = listOf("SMS"),
|
||||
stopFirst = smsStopFirst,
|
||||
onStopFirstChange = { v -> app.appScope.launch { app.settings.setSmsStopOnFirst(v) } },
|
||||
@@ -421,6 +435,8 @@ private fun ChannelSectionHeader(
|
||||
summary: String,
|
||||
mark: String,
|
||||
markColor: Color,
|
||||
markIcon: ImageVector? = null,
|
||||
markLogo: Painter? = null,
|
||||
platforms: List<String>,
|
||||
stopFirst: Boolean,
|
||||
onStopFirstChange: (Boolean) -> Unit,
|
||||
@@ -435,7 +451,7 @@ private fun ChannelSectionHeader(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
ChannelMark(mark = mark, tint = markColor)
|
||||
ChannelMark(mark = mark, tint = markColor, icon = markIcon, logoPainter = markLogo)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -492,7 +508,7 @@ private fun ChannelSectionHeader(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChannelMark(mark: String, tint: Color) {
|
||||
private fun ChannelMark(mark: String, tint: Color, icon: ImageVector? = null, logoPainter: Painter? = null) {
|
||||
Surface(
|
||||
modifier = Modifier.size(36.dp),
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
@@ -504,13 +520,13 @@ private fun ChannelMark(mark: String, tint: Color) {
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
mark,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = tint,
|
||||
maxLines = 1,
|
||||
)
|
||||
if (logoPainter != null) {
|
||||
Image(logoPainter, null, modifier = Modifier.size(24.dp))
|
||||
} else if (icon != null) {
|
||||
Icon(icon, null, tint = tint, modifier = Modifier.size(20.dp))
|
||||
} else {
|
||||
Text(mark, style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.Bold, color = tint, maxLines = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Reference in New Issue
Block a user