mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 06:55:41 +00:00
Add KDoc to six small library API modules
Cover the remaining interfaces of libraries/troubleshoot, libraries/matrixmedia, libraries/dateformatter, libraries/featureflag, libraries/workmanager and libraries/mediaviewer, along with their members and parameters. Behaviours worth recording: NotificationTroubleshootTest reports its outcome through its state flow rather than by returning, and its quickFix throws unless the test offers one; DateFormatter.format turns a null timestamp into an empty string so callers need no null check; ImageLoaderHolder keeps one loader per session because decrypting room media needs that session's client. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+10
@@ -8,7 +8,17 @@
|
|||||||
|
|
||||||
package io.element.android.libraries.dateformatter.api
|
package io.element.android.libraries.dateformatter.api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats timestamps for display, in the user's locale and time zone.
|
||||||
|
*/
|
||||||
interface DateFormatter {
|
interface DateFormatter {
|
||||||
|
/**
|
||||||
|
* Formats a timestamp according to [mode].
|
||||||
|
*
|
||||||
|
* @param timestamp milliseconds since the epoch; a `null` value yields an empty string, so callers need no null check of their own.
|
||||||
|
* @param mode how much of the date and time to include; see [DateFormatterMode] for examples of each.
|
||||||
|
* @param useRelative true to prefer wording relative to today, such as "Today" or "This month", where the mode allows it.
|
||||||
|
*/
|
||||||
fun format(
|
fun format(
|
||||||
timestamp: Long?,
|
timestamp: Long?,
|
||||||
mode: DateFormatterMode = DateFormatterMode.Full,
|
mode: DateFormatterMode = DateFormatterMode.Full,
|
||||||
|
|||||||
+5
@@ -21,6 +21,11 @@ import kotlin.time.Duration
|
|||||||
* - 30 seconds → "30 seconds"
|
* - 30 seconds → "30 seconds"
|
||||||
*/
|
*/
|
||||||
interface DurationFormatter {
|
interface DurationFormatter {
|
||||||
|
/**
|
||||||
|
* Formats the duration using its largest appropriate unit, rounding rather than listing several units.
|
||||||
|
*
|
||||||
|
* @param duration the duration to describe.
|
||||||
|
*/
|
||||||
fun format(duration: Duration): String
|
fun format(duration: Duration): String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -10,6 +10,9 @@ package io.element.android.libraries.featureflag.api
|
|||||||
|
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes one feature flag: how it is identified, how it is presented in the developer options, and what it defaults to.
|
||||||
|
*/
|
||||||
interface Feature {
|
interface Feature {
|
||||||
/**
|
/**
|
||||||
* Unique key to identify the feature.
|
* Unique key to identify the feature.
|
||||||
|
|||||||
+3
@@ -11,6 +11,9 @@ package io.element.android.libraries.featureflag.api
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and, where a mutable provider is registered, changes the state of the feature flags.
|
||||||
|
*/
|
||||||
interface FeatureFlagService {
|
interface FeatureFlagService {
|
||||||
/**
|
/**
|
||||||
* @param feature the feature to check for
|
* @param feature the feature to check for
|
||||||
|
|||||||
+16
@@ -11,8 +11,24 @@ import coil3.ImageLoader
|
|||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches one Coil image loader per session, since loading Matrix media requires the session's own client to fetch and decrypt it.
|
||||||
|
*/
|
||||||
interface ImageLoaderHolder {
|
interface ImageLoaderHolder {
|
||||||
|
/** Returns a loader that can only fetch ordinary URLs, for images that do not come from a Matrix room. */
|
||||||
fun get(): ImageLoader
|
fun get(): ImageLoader
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the loader of a session, creating it on first use.
|
||||||
|
*
|
||||||
|
* @param client the session whose media the loader will fetch.
|
||||||
|
*/
|
||||||
fun get(client: MatrixClient): ImageLoader
|
fun get(client: MatrixClient): ImageLoader
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drops the cached loader of a session, to be called when that session goes away.
|
||||||
|
*
|
||||||
|
* @param sessionId the session whose loader is dropped.
|
||||||
|
*/
|
||||||
fun remove(sessionId: SessionId)
|
fun remove(sessionId: SessionId)
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -14,6 +14,15 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
|||||||
* Generates a bitmap for an initials avatar based on the provided [io.element.android.libraries.designsystem.components.avatar.AvatarData].
|
* Generates a bitmap for an initials avatar based on the provided [io.element.android.libraries.designsystem.components.avatar.AvatarData].
|
||||||
*/
|
*/
|
||||||
interface InitialsAvatarBitmapGenerator {
|
interface InitialsAvatarBitmapGenerator {
|
||||||
|
/**
|
||||||
|
* Draws the initials avatar, used where a bitmap is required rather than a Composable, such as in notifications and shortcuts.
|
||||||
|
*
|
||||||
|
* @param size the width and height of the bitmap in pixels.
|
||||||
|
* @param avatarData the name and id the initials and the background colour are derived from.
|
||||||
|
* @param useDarkTheme whether to draw the dark theme variant.
|
||||||
|
* @param fontSizePercentage the text height as a fraction of [size].
|
||||||
|
* @return the bitmap, or `null` when it could not be drawn.
|
||||||
|
*/
|
||||||
fun generateBitmap(
|
fun generateBitmap(
|
||||||
size: Int,
|
size: Int,
|
||||||
avatarData: AvatarData,
|
avatarData: AvatarData,
|
||||||
|
|||||||
+11
@@ -12,9 +12,15 @@ import android.net.Uri
|
|||||||
import io.element.android.libraries.matrix.api.media.MediaFile
|
import io.element.android.libraries.matrix.api.media.MediaFile
|
||||||
import io.element.android.libraries.mediaviewer.api.MediaInfo
|
import io.element.android.libraries.mediaviewer.api.MediaInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the [LocalMedia] the media viewer renders, from either a downloaded Matrix media file or an arbitrary content uri.
|
||||||
|
*/
|
||||||
interface LocalMediaFactory {
|
interface LocalMediaFactory {
|
||||||
/**
|
/**
|
||||||
* This method will create a [LocalMedia] with the given [MediaFile] and [MediaInfo].
|
* This method will create a [LocalMedia] with the given [MediaFile] and [MediaInfo].
|
||||||
|
*
|
||||||
|
* @param mediaFile the file already downloaded from the homeserver.
|
||||||
|
* @param mediaInfo what is known about the media from the event that carried it.
|
||||||
*/
|
*/
|
||||||
fun createFromMediaFile(
|
fun createFromMediaFile(
|
||||||
mediaFile: MediaFile,
|
mediaFile: MediaFile,
|
||||||
@@ -24,6 +30,11 @@ interface LocalMediaFactory {
|
|||||||
/**
|
/**
|
||||||
* This method will create a [LocalMedia] with the given mimeType, name and formattedFileSize
|
* This method will create a [LocalMedia] with the given mimeType, name and formattedFileSize
|
||||||
* If any of those params are null, it'll try to read them from the content.
|
* If any of those params are null, it'll try to read them from the content.
|
||||||
|
*
|
||||||
|
* @param uri the content to display, for instance one just picked by the user.
|
||||||
|
* @param mimeType the MIME type, or `null` to read it from the content.
|
||||||
|
* @param name the file name, or `null` to read it from the content.
|
||||||
|
* @param formattedFileSize the size to display, or `null` to read it from the content.
|
||||||
*/
|
*/
|
||||||
fun createFromUri(
|
fun createFromUri(
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
|
|||||||
+8
@@ -10,7 +10,15 @@ package io.element.android.libraries.mediaviewer.api.local
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a media file held on the device, picking the right player or viewer for its type.
|
||||||
|
*/
|
||||||
interface LocalMediaRenderer {
|
interface LocalMediaRenderer {
|
||||||
|
/**
|
||||||
|
* Draws the media, filling the space it is given.
|
||||||
|
*
|
||||||
|
* @param localMedia the file to display, along with what is known about its type.
|
||||||
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun Render(localMedia: LocalMedia)
|
fun Render(localMedia: LocalMedia)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -8,6 +8,13 @@
|
|||||||
|
|
||||||
package io.element.android.libraries.mediaviewer.api.util
|
package io.element.android.libraries.mediaviewer.api.util
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the extension of a file name, so it can be shown to the user and used to pick an icon.
|
||||||
|
*/
|
||||||
interface FileExtensionExtractor {
|
interface FileExtensionExtractor {
|
||||||
|
/**
|
||||||
|
* @param name the file name to inspect.
|
||||||
|
* @return the extension without its dot, or an empty string when the name has none.
|
||||||
|
*/
|
||||||
fun extractFromName(name: String): String
|
fun extractFromName(name: String): String
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -8,6 +8,10 @@
|
|||||||
|
|
||||||
package io.element.android.libraries.troubleshoot.api.test
|
package io.element.android.libraries.troubleshoot.api.test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets a troubleshooting test's quick fix send the user to another screen, without the test itself knowing about navigation.
|
||||||
|
*/
|
||||||
interface NotificationTroubleshootNavigator {
|
interface NotificationTroubleshootNavigator {
|
||||||
|
/** Opens the blocked users screen, so the user can unblock someone whose messages were being filtered out. */
|
||||||
fun navigateToBlockedUsers()
|
fun navigateToBlockedUsers()
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -20,11 +20,36 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
* the component they're injected into is bound to [SessionScope] and so should these (https://github.com/ZacSweers/metro/issues/1932).
|
* the component they're injected into is bound to [SessionScope] and so should these (https://github.com/ZacSweers/metro/issues/1932).
|
||||||
*/
|
*/
|
||||||
interface NotificationTroubleshootTest {
|
interface NotificationTroubleshootTest {
|
||||||
|
/** Position of this test in the list shown to the user; tests run in ascending order. */
|
||||||
val order: Int
|
val order: Int
|
||||||
|
|
||||||
|
/** The current state of this test, which the UI observes to show it as idle, running, successful or failed. */
|
||||||
val state: StateFlow<NotificationTroubleshootTestState>
|
val state: StateFlow<NotificationTroubleshootTestState>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this test applies to the current setup, so that irrelevant tests are hidden rather than shown as failing.
|
||||||
|
*
|
||||||
|
* @param data the current push provider and distributor, used to decide relevance.
|
||||||
|
*/
|
||||||
fun isRelevant(data: TestFilterData): Boolean = true
|
fun isRelevant(data: TestFilterData): Boolean = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the test, reporting its outcome through [state] rather than by returning or throwing.
|
||||||
|
*
|
||||||
|
* @param coroutineScope the scope to launch any work that must outlive the call itself.
|
||||||
|
*/
|
||||||
suspend fun run(coroutineScope: CoroutineScope)
|
suspend fun run(coroutineScope: CoroutineScope)
|
||||||
|
|
||||||
|
/** Returns the test to its idle state so it can be run again. */
|
||||||
suspend fun reset()
|
suspend fun reset()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to fix what this test detected, for the tests that can offer it. Throws by default, so check the state's quick fix
|
||||||
|
* flag before calling.
|
||||||
|
*
|
||||||
|
* @param coroutineScope the scope to launch any work that must outlive the call itself.
|
||||||
|
* @param navigator used by the fixes that have to send the user to another screen.
|
||||||
|
*/
|
||||||
suspend fun quickFix(
|
suspend fun quickFix(
|
||||||
coroutineScope: CoroutineScope,
|
coroutineScope: CoroutineScope,
|
||||||
navigator: NotificationTroubleshootNavigator,
|
navigator: NotificationTroubleshootNavigator,
|
||||||
|
|||||||
+11
@@ -10,20 +10,31 @@ package io.element.android.libraries.workmanager.api
|
|||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules background work, wrapping `WorkManager` so the rest of the app does not depend on it directly.
|
||||||
|
*/
|
||||||
interface WorkManagerScheduler {
|
interface WorkManagerScheduler {
|
||||||
/**
|
/**
|
||||||
* Submits a new work request built from [workManagerRequestBuilder] to run in `WorkManager`.
|
* Submits a new work request built from [workManagerRequestBuilder] to run in `WorkManager`.
|
||||||
|
*
|
||||||
|
* @param workManagerRequestBuilder describes the work to schedule.
|
||||||
*/
|
*/
|
||||||
suspend fun submit(workManagerRequestBuilder: WorkManagerRequestBuilder)
|
suspend fun submit(workManagerRequestBuilder: WorkManagerRequestBuilder)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if there are any pending requests scheduled for the provided [sessionId] and [requestType].
|
* Checks if there are any pending requests scheduled for the provided [sessionId] and [requestType].
|
||||||
|
*
|
||||||
|
* @param sessionId the session the work belongs to.
|
||||||
|
* @param requestType the kind of work to look for.
|
||||||
*/
|
*/
|
||||||
fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean
|
fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel pending work requests for the session [SessionId].
|
* Cancel pending work requests for the session [SessionId].
|
||||||
* If [requestType] is provided, it will only cancel requests for that type, otherwise it will cancel all requests.
|
* If [requestType] is provided, it will only cancel requests for that type, otherwise it will cancel all requests.
|
||||||
|
*
|
||||||
|
* @param sessionId the session whose work is cancelled.
|
||||||
|
* @param requestType the kind of work to cancel, or `null` to cancel every kind.
|
||||||
*/
|
*/
|
||||||
fun cancel(sessionId: SessionId, requestType: WorkManagerRequestType? = null)
|
fun cancel(sessionId: SessionId, requestType: WorkManagerRequestType? = null)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -28,7 +28,13 @@ class MetroWorkerFactory(
|
|||||||
return workerProviders[Class.forName(workerClassName).kotlin]?.create(workerParameters)
|
return workerProviders[Class.forName(workerClassName).kotlin]?.create(workerParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates one worker type with its dependencies injected, since `WorkManager` instantiates workers itself and cannot use the graph.
|
||||||
|
*/
|
||||||
interface WorkerInstanceFactory<T : ListenableWorker> {
|
interface WorkerInstanceFactory<T : ListenableWorker> {
|
||||||
|
/**
|
||||||
|
* @param params the parameters `WorkManager` built the worker with.
|
||||||
|
*/
|
||||||
fun create(params: WorkerParameters): T
|
fun create(params: WorkerParameters): T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user