### Run Synapse with virtualenv Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Sets up a virtual environment, installs Synapse, and starts a demo Synapse server. This is required for running integration tests. ```bash virtualenv -p python3 env source env/bin/activate pip install -e . demo/start.sh --no-rate-limit ``` -------------------------------- ### Rust SDK OAuth Client Example Source: https://github.com/element-hq/element-x-android/blob/develop/docs/oauth.md Example demonstrating the usage of OAuth client functionalities within the matrix-rust-sdk. This snippet is part of a larger CLI example. ```rust use matrix_sdk::Client; use url::Url; #[tokio::main] async fn main() -> Result<(), Box> { // Replace with your actual client configuration let homeserver_url = Url::parse("https://your.homeserver.url")?; let client_id = "your_client_id"; let client_secret = "your_client_secret"; // If applicable let redirect_uri = Url::parse("your_redirect_uri")?; let scopes = vec!["openid", "profile", "email"]; // Example scopes // Initialize the client with OAuth configuration let client = Client::builder() .homeserver_url(homeserver_url) .build() .await?; // Perform OAuth flow (simplified) let token_response = client .oidc_login( client_id, client_secret, // Pass None if no client secret redirect_uri, scopes, ) .await?; println!("Access Token: {}", token_response.access_token); // Handle token response, e.g., store it and use it for authentication Ok(()) } ``` -------------------------------- ### Install virtualenv Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Installs the virtualenv package using pip. This is a prerequisite for setting up the Synapse environment. ```bash python3 -m pip install virtualenv ``` -------------------------------- ### Install Danger Plugin Source: https://github.com/element-hq/element-x-android/blob/develop/docs/danger.md Install the danger-plugin-lint-report for integrating linting and quality checks into Danger. ```shell yarn add danger-plugin-lint-report --dev ``` -------------------------------- ### Install Synapse Release Package Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Installs the latest stable release of the Matrix Synapse homeserver package. This is an alternative to cloning the repository. ```bash pip install matrix-synapse ``` -------------------------------- ### Install gnu-getopt on macOS Source: https://github.com/element-hq/element-x-android/blob/develop/docs/_developer_onboarding.md Ensure gnu-getopt is installed on macOS, as it may be a dependency for certain build scripts. ```bash brew install gnu-getopt ``` -------------------------------- ### Install bundletool on macOS Source: https://github.com/element-hq/element-x-android/blob/develop/docs/install_from_github_release.md Install the bundletool command-line tool using Homebrew. This tool is necessary for building and managing Android App Bundles. ```bash brew install bundletool ``` -------------------------------- ### Example App Link Verification Output Source: https://github.com/element-hq/element-x-android/blob/develop/docs/deeplink.md An example output showing the link verification status for the Element X debug package, including its unique ID, signatures, and domain verification states. ```text io.element.android.x.debug: ID: e2ece472-c266-4bf0-829c-be79959a6270 Signatures: [B0:B0:51:DC:56:5C:81:2F:E1:7F:6F:3E:94:5B:4D:79:04:71:23:AB:0D:A6:12:86:76:9E:B2:94:91:97:13:0E] Domain verification state: *.element.io: 1024 ``` -------------------------------- ### OAuth Authorization URL Example Source: https://github.com/element-hq/element-x-android/blob/develop/docs/oauth.md An example of a complete OAuth authorization URL, including all necessary parameters for initiating the authentication flow. ```url https://auth-oidc.lab.element.dev/authorize?response_type=code&client_id=01GYCAGG3PA70CJ97ZVP0WFJY3&redirect_uri=io.element%3A%2Fcallback&scope=openid+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Aapi%3A*+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Adevice%3AYAgcPW4mcG&state=ex6mNJVFZ5jn9wL8&nonce=NZ93DOyIGQd9exPQ&code_challenge_method=S256&code_challenge=FFRcPALNSPCh-ZgpyTRFu_h8NZJVncfvihbfT9CyX8U&prompt=consent ``` -------------------------------- ### Install Generated APKs on Device Source: https://github.com/element-hq/element-x-android/blob/develop/docs/install_from_github_release.md Install the generated APKs (previously built using bundletool) onto a connected Android device or emulator. This command takes the path to the .apks file as input. ```bash bundletool install-apks --apks=./tmp/elementx.apks ``` -------------------------------- ### Install cargo-ndk Source: https://github.com/element-hq/element-x-android/blob/develop/docs/_developer_onboarding.md Install the cargo-ndk tool, which is required for building Rust code for Android. ```bash cargo install cargo-ndk ``` -------------------------------- ### Install Git LFS Hooks Source: https://github.com/element-hq/element-x-android/blob/develop/docs/screenshot_testing.md Installs Git LFS hooks locally for the project. This ensures that Git LFS content is handled correctly during push and pull operations. ```shell git lfs install --local ``` -------------------------------- ### Implement MVI Presenter Pattern with State and Events Source: https://context7.com/element-hq/element-x-android/llms.txt Shows the definition of state and events for a feature screen using the MVI Presenter pattern. Includes an example implementation of a presenter and how to consume its state in a Composable View. ```kotlin // Define state and events data class ChangeServerState( val homeserver: String, val submitEnabled: Boolean, val asyncAction: AsyncAction, val eventSink: (ChangeServerEvent) -> Unit, ) sealed interface ChangeServerEvent { data class SetHomeserver(val homeserver: String) : ChangeServerEvent data object Submit : ChangeServerEvent data object ClearError : ChangeServerEvent } // Implement presenter (Metro @AssistedInject for room-scoped deps) class ChangeServerPresenter @Inject constructor( private val authService: MatrixAuthenticationService, ) : Presenter { @Composable override fun present(): ChangeServerState { var homeserver by rememberSaveable { mutableStateOf("https://matrix.org") } var asyncAction by remember { mutableStateOf>(AsyncAction.Uninitialized) } val coroutineScope = rememberCoroutineScope() fun handleEvent(event: ChangeServerEvent) { when (event) { is ChangeServerEvent.SetHomeserver -> homeserver = event.homeserver ChangeServerEvent.Submit -> coroutineScope.launch { asyncAction.runCatchingUpdatingState { authService.setHomeserver(homeserver).getOrThrow() } } ChangeServerEvent.ClearError -> asyncAction = AsyncAction.Uninitialized } } return ChangeServerState( homeserver = homeserver, submitEnabled = homeserver.isNotBlank() && !asyncAction.isLoading(), asyncAction = asyncAction, eventSink = ::handleEvent, ) } } // Consume in a Composable View @Composable fun ChangeServerView(state: ChangeServerState) { Column { TextField( value = state.homeserver, onValueChange = { state.eventSink(ChangeServerEvent.SetHomeserver(it)) }, ) Button( onClick = { state.eventSink(ChangeServerEvent.Submit) }, enabled = state.submitEnabled, ) { Text("Connect") } when { state.asyncAction.isLoading() -> CircularProgressIndicator() state.asyncAction.isFailure() -> { Text("Error: ${state.asyncAction.errorOrNull()?.message}") TextButton(onClick = { state.eventSink(ChangeServerEvent.ClearError) }) { Text("Dismiss") } } } } } ``` -------------------------------- ### Stop Synapse Demo Server Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Stops the Synapse demo server started with 'demo/start.sh'. ```bash ./demo/stop.sh ``` -------------------------------- ### Access All Rooms Directly Source: https://context7.com/element-hq/element-x-android/llms.txt Access all rooms directly through the client. Observe the loading state to know when rooms are loaded and get the total count. ```kotlin client.roomListService.allRooms.loadingState.collect { state -> if (state is RoomList.LoadingState.Loaded) { println("${state.numberOfRooms} rooms loaded") } } ``` -------------------------------- ### Initialize Danger Source: https://github.com/element-hq/element-x-android/blob/develop/docs/danger.md Initialize Danger in your project. This operation might not be necessary if Danger is already configured. ```shell bundle exec danger init ``` -------------------------------- ### Download All Translations with Localazy CLI Source: https://github.com/element-hq/element-x-android/blob/develop/tools/localazy/README.md Run this script to update all localazy.xml resource files. Include translations by adding the --all argument. ```shell ./tools/localazy/downloadStrings.sh ``` ```shell ./tools/localazy/downloadStrings.sh --all ``` -------------------------------- ### Create virtual environment with virtualenv Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Alternative command to create a Python virtual environment using the 'virtualenv' package. ```bash python3 -m virtualenv env ``` -------------------------------- ### Run Danger Locally with Specific PR Source: https://github.com/element-hq/element-x-android/blob/develop/docs/danger.md An example of running Danger locally with a specific Pull Request URL. ```shell bundle exec danger pr https://github.com/element-hq/element-android/pull/6637 --dangerfile=./tools/danger/dangerfile.js ``` -------------------------------- ### Mermaid Flowchart Syntax Source: https://github.com/element-hq/element-x-android/blob/develop/docs/_developer_onboarding.md This is an example of Mermaid syntax used for generating flowcharts. It's not executable code but a definition for diagram generation. ```mermaid flowchart TD subgraph Application app([:app])--implementation-->appnav([:appnav]) end subgraph Features featureapi([:features:*:api]) featureimpl([:features:*:impl]) end subgraph Libraries subgraph Matrix matrixapi([:matrix:api]) matriximpl([:matrix:impl]) end libraryarch([:libraries:architecture]) libraryapi([:libraries:*:api]) libraryimpl([:libraries:*:impl]) end subgraph Matrix RustSdk RustSdk([Rust Sdk]) end app--implementation-->featureimpl app--implementation-->libraryimpl appnav--implementation-->featureapi appnav--implementation-->libraryarch featureimpl--api-->featureapi featureimpl--implementation-->matrixapi featureimpl--implementation-->libraryapi featureimpl--implementation-->libraryarch matriximpl--implementation-->matrixapi matrixapi--api-->RustSdk matriximpl--api-->RustSdk featureapi--implementation-->libraryarch libraryimpl--api-->libraryapi ``` -------------------------------- ### Run Unit Tests Source: https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md Execute all unit tests in the project. Ensure these commands run without errors before submitting changes. ```bash ./gradlew test ``` -------------------------------- ### Android OAuth Client Metadata Source: https://github.com/element-hq/element-x-android/blob/develop/docs/oauth.md Metadata required for OAuth client configuration on Android. Ensure these values match your application's setup. ```kotlin clientName = "Element", redirectUri = "io.element.android:/", clientUri = "https://element.io", tosUri = "https://element.io/user-terms-of-service", policyUri = "https://element.io/privacy" ``` -------------------------------- ### iOS OAuth Client Metadata Source: https://github.com/element-hq/element-x-android/blob/develop/docs/oauth.md Metadata required for OAuth client configuration on iOS. Ensure these values match your application's setup. ```swift clientName: InfoPlistReader.main.bundleDisplayName, redirectUri: "io.element.android:/", clientUri: "https://element.io", tosUri: "https://element.io/user-terms-of-service", policyUri: "https://element.io/privacy" ``` -------------------------------- ### Create virtual environment with venv Source: https://github.com/element-hq/element-x-android/blob/develop/docs/integration_tests.md Alternative command to create a Python virtual environment using the 'venv' module. ```bash python3 -m venv env ``` -------------------------------- ### Generate Documentation Table of Contents Source: https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md Run this Gradle task to update the table of contents in markdown files. Commit the changes after running. ```bash ./gradlew generateDocsToc ``` -------------------------------- ### Manage Live Location Sharing Source: https://context7.com/element-hq/element-x-android/llms.txt Start, send updates for, and stop live location sharing in a room. Requires specifying duration and geo URI for sharing. ```kotlin // Live location sharing room.startLiveLocationShare(durationMillis = 30 * 60 * 1000L).getOrThrow() room.sendLiveLocation(geoUri = "geo:51.5074,-0.1278").getOrThrow() room.stopLiveLocationShare().getOrThrow() ``` -------------------------------- ### SyncService Source: https://context7.com/element-hq/element-x-android/llms.txt Controls background Matrix sync, exposes online status, and sync state flows. ```APIDOC ## SyncService ### Description Controls background Matrix sync. Starts and stops the sliding sync connection. Exposes online status and sync state flows. ### Methods - `startSync()`: Start the background sync. - `syncState`: Flow of the current sync state. - `isOnline`: Flow indicating online connectivity. - `stopSync()`: Stop the background sync. ### Request Example (Start Sync) ```kotlin syncService.startSync().getOrThrow() ``` ### Request Example (Stop Sync) ```kotlin syncService.stopSync().getOrThrow() ``` ### Response Example (Sync State Observation) ```kotlin syncService.syncState.collect { state -> when (state) { SyncState.Running -> println("Online and syncing") SyncState.Terminated -> println("Sync stopped") else -> Unit } } ``` ``` -------------------------------- ### Control Background Matrix Sync Source: https://context7.com/element-hq/element-x-android/llms.txt Manage the sliding sync connection using SyncService. It allows starting and stopping sync, and observing the sync state and online connectivity. ```kotlin val syncService: SyncService = client.syncService // Start syncing (idempotent — safe to call when already syncing) syncService.startSync().getOrThrow() // Observe sync state syncService.syncState.collect { state -> when (state) { SyncState.Running -> println("Online and syncing") SyncState.Terminated -> println("Sync stopped") else -> Unit } } // Observe connectivity syncService.isOnline.collect { isOnline -> if (!isOnline) showOfflineBanner() } // Stop sync (e.g. when app goes to background) syncService.stopSync().getOrThrow() ``` -------------------------------- ### Run Detekt Linting Source: https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md Use the Gradle wrapper to run the Detekt static analysis tool for Kotlin code quality. ```shell ./gradlew detekt ``` -------------------------------- ### Obtain and Observe Joined Room Info Source: https://context7.com/element-hq/element-x-android/llms.txt Obtain a JoinedRoom instance and observe its info flow for details like name, topic, and encryption status. Ensure the room is joined before attempting to retrieve it. ```kotlin // Obtain a joined room val room: JoinedRoom = client.getJoinedRoom(RoomId("!abc123:matrix.org")) ?: error("Room not found or not joined") // Observe room info (name, topic, avatar, encryption, etc.) room.roomInfoFlow.collect { info -> println("${info.name} — encrypted: ${info.isEncrypted}") } ``` -------------------------------- ### Run Ktlint Check and Format Source: https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md Check Kotlin code style with Ktlint and optionally format the code to fix detected style issues. ```shell ./gradlew ktlintCheck --continue ``` ```shell ./gradlew ktlintFormat ``` -------------------------------- ### Generate Kover HTML Code Coverage Report Source: https://github.com/element-hq/element-x-android/blob/develop/docs/_developer_onboarding.md Run this command to generate an HTML report for code coverage. Open the generated HTML file to view the report. ```bash ./gradlew :app:koverHtmlReport ``` -------------------------------- ### Build Optimized APKs from App Bundle Source: https://github.com/element-hq/element-x-android/blob/develop/docs/install_from_github_release.md Use bundletool to generate device-specific APKs from a signed Android App Bundle. This command requires the path to the App Bundle, keystore information, and an output path for the generated APKs. ```bash bundletool build-apks --bundle= --output=./tmp/elementx.apks \ --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ --overwrite ``` ```bash bundletool build-apks --bundle=./tmp/Element/0.1.5/app-release-signed.aab --output=./tmp/elementx.apks \ --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ --overwrite ``` -------------------------------- ### MatrixClient: Central entry point for a logged-in session Source: https://context7.com/element-hq/element-x-android/llms.txt The primary interface for all session-level operations: room management, user profile, media, sync, encryption, and more. Obtain it via `MatrixAuthenticationService.restoreSession` or `MatrixClientProvider`. ```kotlin val client: MatrixClient = // obtained after login // Observe the current user profile client.userProfile.collect { user -> println("${user.displayName} — ${user.avatarUrl}") } // Sync client.syncService.startSync() // Create a room val roomId: RoomId = client.createRoom( CreateRoomParameters( name = "My Room", topic = "Discussion", isEncrypted = true, visibility = RoomVisibility.Private, preset = RoomPreset.PrivateChat, invite = listOf(UserId("@bob:matrix.org")), ) ).getOrThrow() // Create a DM val dmRoomId: RoomId = client.createDM(UserId("@bob:matrix.org")).getOrThrow() // Join a room by alias val roomInfo = client.joinRoomByIdOrAlias( roomIdOrAlias = RoomIdOrAlias.Alias(RoomAlias("#general:matrix.org")), serverNames = listOf("matrix.org"), ).getOrThrow() // Search users val results: MatrixSearchUserResults = client .searchUsers("alice", limit = 10L) .getOrThrow() // Update profile client.setDisplayName("Alice").getOrThrow() client.uploadAvatar(mimeType = "image/png", data = pngBytes).getOrThrow() // Get recent emojis val recentEmojis: List = client.getRecentEmojis().getOrThrow() client.addRecentEmoji("👍").getOrThrow() // Resolve a room alias val resolved = client.resolveRoomAlias(RoomAlias("#general:matrix.org")).getOrThrow() // Control send queue client.setAllSendQueuesEnabled(true) client.sendQueueDisabledFlow().collect { roomId -> println("Send queue disabled for $roomId") } // Logout client.logout(userInitiated = true, ignoreSdkError = false) ``` -------------------------------- ### Run All Quality Checks Source: https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md Execute all project quality checks to ensure code standards are met before committing. ```shell ./tools/quality/check.sh ``` -------------------------------- ### MatrixMediaLoader Source: https://context7.com/element-hq/element-x-android/llms.txt Provides methods to load raw media bytes, generate thumbnails, and download media files to disk. ```APIDOC ## MatrixMediaLoader ### Description Provides methods to load raw media bytes, generate thumbnails, and download media files to disk. ### Methods - `loadMediaContent(source: MediaSource)`: Load raw media bytes. - `loadMediaThumbnail(source: MediaSource, width: Long, height: Long)`: Load a media thumbnail. - `downloadMediaFile(source: MediaSource, mimeType: String, filename: String, useCache: Boolean)`: Download media to a file. ### Request Example (Load Media Content) ```kotlin val bytes: ByteArray = mediaLoader .loadMediaContent(MediaSource(url = "mxc://matrix.org/abc123")) .getOrThrow() ``` ### Request Example (Download Media File) ```kotlin val mediaFile: MediaFile = mediaLoader .downloadMediaFile( source = MediaSource(url = "mxc://matrix.org/abc123"), mimeType = "image/jpeg", filename = "photo.jpg", useCache = true, ) .getOrThrow() ``` ### Response Example (Downloaded Media File) ```kotlin // Share or open mediaFile.file openFile(mediaFile.file) ``` ```