diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt index 7eb58a3..28c6064 100644 --- a/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt @@ -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 { diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt index 220f592..8ff854e 100644 --- a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt @@ -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" } } } diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt index d8d9e5b..56e763a 100644 --- a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt @@ -35,13 +35,16 @@ private data class AppMenuEntry( // Состав меню — по дизайну выдвижного меню (Почта/Конференции/Задачи/Поддержка — только // в нижней панели; Уведомления/Настройки добавлены как нативные пункты, см. appMenuItems). -// iconPath — базовое имя плоской menu-иконки (assets/menu/menu-.svg) +// iconPath — базовое имя плоской menu-иконки (assets/menu/menu-.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"), diff --git a/core/designsystem/src/main/assets/menu/menu-lk.svg b/core/designsystem/src/main/assets/menu/menu-lk.svg new file mode 100644 index 0000000..9188d04 --- /dev/null +++ b/core/designsystem/src/main/assets/menu/menu-lk.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/core/designsystem/src/main/assets/menu/menu-support.svg b/core/designsystem/src/main/assets/menu/menu-support.svg new file mode 100644 index 0000000..69bd2fc --- /dev/null +++ b/core/designsystem/src/main/assets/menu/menu-support.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +