fix(menu): состав шторки 1:1 (Поддержка + Личный кабинет) + иконки внешних сайтов
По разметке сайта (layout.user.php):
- Добавлены пункты «Поддержка» (AppTab.Support, icon-header-f7support)
после Заметок и «Личный кабинет» (открывает нативную ProfileSheet,
lk-header-icon) перед Уведомлениями — их не хватало.
- Иконки внешних сайтов (Bitrix/1C) строились из имени файла как есть →
битая ссылка → глобус. Теперь путь /index.php/apps/external/img/{icon},
как на сайте.
- Coil: добавлен Basic-auth интерсептор для хоста сервера — серверные
картинки (иконки external и пр.) требуют логина, без него был 401.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,7 +77,31 @@ class F7MobileApp : F7cloudTalkApplication(), ImageLoaderFactory {
|
||||
}
|
||||
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
// OkHttp с Basic-auth для хоста сервера: серверные картинки (иконки внешних сайтов
|
||||
// /apps/external/img, превью и т.п.) требуют логина — без заголовка coil ловит 401.
|
||||
val authedClient = okhttp3.OkHttpClient.Builder()
|
||||
.addInterceptor { chain ->
|
||||
val request = chain.request()
|
||||
val session = runCatching { AuthStore(this).load() }.getOrNull()
|
||||
val serverHost = session?.serverUrl?.let {
|
||||
runCatching { android.net.Uri.parse(it).host }.getOrNull()
|
||||
}
|
||||
val patched = if (session != null && serverHost != null && request.url.host == serverHost) {
|
||||
request.newBuilder()
|
||||
.header(
|
||||
"Authorization",
|
||||
okhttp3.Credentials.basic(session.username, session.appPassword),
|
||||
)
|
||||
.header("OCS-APIRequest", "true")
|
||||
.build()
|
||||
} else {
|
||||
request
|
||||
}
|
||||
chain.proceed(patched)
|
||||
}
|
||||
.build()
|
||||
return ImageLoader.Builder(this)
|
||||
.okHttpClient(authedClient)
|
||||
.components { add(SvgDecoder.Factory()) }
|
||||
.crossfade(false)
|
||||
.memoryCache {
|
||||
|
||||
@@ -48,7 +48,7 @@ object AppMenuRepository {
|
||||
}
|
||||
AppMenuExternalSite(
|
||||
name = name,
|
||||
iconUrl = icon ?: defaultExternalIcon(session.serverUrl, name),
|
||||
iconUrl = resolveExternalIcon(session.serverUrl, icon, name),
|
||||
openUrl = openUrl,
|
||||
)
|
||||
}
|
||||
@@ -56,12 +56,18 @@ object AppMenuRepository {
|
||||
}.getOrDefault(emptyList())
|
||||
}
|
||||
|
||||
private fun defaultExternalIcon(serverUrl: String, name: String): String {
|
||||
/**
|
||||
* Иконка внешнего сайта. API external отдаёт `icon` как ИМЯ ФАЙЛА (напр. «bitrix24.png»),
|
||||
* а не URL — сайт грузит его с `/apps/external/img/{icon}` (см. layout.user.php). Раньше
|
||||
* имя файла бралось как есть → битая ссылка → глобус-заглушка у Bitrix/1C.
|
||||
*/
|
||||
private fun resolveExternalIcon(serverUrl: String, icon: String?, name: String): String {
|
||||
val base = serverUrl.trimEnd('/')
|
||||
return when {
|
||||
name.contains("bitrix", ignoreCase = true) -> "$base/themes/forbion/images/header/bitrix-glass.svg"
|
||||
name.contains("1c", ignoreCase = true) -> "$base/themes/forbion/images/header/1c-glass.svg"
|
||||
else -> "$base/index.php/apps/external/img/external.svg"
|
||||
icon.isNullOrBlank() -> "$base/index.php/apps/external/img/external.svg"
|
||||
icon.startsWith("http") -> icon
|
||||
icon.startsWith("/") -> "$base$icon"
|
||||
else -> "$base/index.php/apps/external/img/$icon"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,13 +35,16 @@ private data class AppMenuEntry(
|
||||
|
||||
// Состав меню — по дизайну выдвижного меню (Почта/Конференции/Задачи/Поддержка — только
|
||||
// в нижней панели; Уведомления/Настройки добавлены как нативные пункты, см. appMenuItems).
|
||||
// iconPath — базовое имя плоской menu-иконки (assets/menu/menu-<name>.svg)
|
||||
// iconPath — базовое имя плоской menu-иконки (assets/menu/menu-<name>.svg).
|
||||
// Состав/порядок 1:1 со шторкой сайта: Файлы·Календарь·Контакты·Карточки·Заметки·Поддержка
|
||||
// (Почта/Задачи/Конференции не тут — они в нижней панели).
|
||||
private val coreAppMenuEntries = listOf(
|
||||
AppMenuEntry(AppTab.Files, "Файлы", "files"),
|
||||
AppMenuEntry(AppTab.Calendar, "Календарь", "calendar"),
|
||||
AppMenuEntry(AppTab.Contacts, "Контакты", "contacts"),
|
||||
AppMenuEntry(AppTab.Deck, "Карточки", "cards"),
|
||||
AppMenuEntry(null, "Заметки", "notes", webPath = "/apps/notes/"),
|
||||
AppMenuEntry(AppTab.Support, "Поддержка", "support"),
|
||||
)
|
||||
|
||||
data class AppMenuExternalSite(
|
||||
@@ -74,8 +77,14 @@ fun appMenuItems(
|
||||
externalUrl = site.openUrl,
|
||||
)
|
||||
}
|
||||
// Нативные пункты — плоские menu-иконки темы, действия по label в AppScaffold
|
||||
// Нативные пункты — плоские menu-иконки темы, действия по label в AppScaffold.
|
||||
// Порядок как на сайте: после внешних сайтов — Личный кабинет, затем Уведомления, Настройки.
|
||||
val native = listOf(
|
||||
F7AppMenuItem(
|
||||
label = "Личный кабинет",
|
||||
iconUrl = menuIcon("lk"),
|
||||
selected = false,
|
||||
),
|
||||
F7AppMenuItem(
|
||||
label = "Уведомления",
|
||||
iconUrl = menuIcon("notifications"),
|
||||
|
||||
Reference in New Issue
Block a user