### ViewModel for App Installation and Uninstallation (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Demonstrates the usage of the Installer interface within a ViewModel to handle the download, installation, and uninstallation of applications. It manages download progress and stages, and interacts with repositories for installed app tracking. ```kotlin class DetailsViewModel( private val downloader: Downloader, private val installer: Installer, private val installedAppsRepository: InstalledAppsRepository, ) : ViewModel() { fun installPrimary() { val asset = _state.value.primaryAsset ?: return val release = _state.value.selectedRelease ?: return currentDownloadJob = viewModelScope.launch { _state.update { it.copy(downloadStage = DownloadStage.DOWNLOADING) } // Download the asset downloader.download(asset.downloadUrl, asset.name).collect { progress -> _state.update { it.copy(downloadProgressPercent = progress.percent) } } val filePath = downloader.getDownloadedFilePath(asset.name) ?: throw IllegalStateException("Downloaded file not found") _state.update { it.copy(downloadStage = DownloadStage.INSTALLING) } // Verify permissions and install val ext = asset.name.substringAfterLast('.').lowercase() installer.ensurePermissionsOrThrow(ext) // Save to database before install (for tracking) if (platform == Platform.ANDROID) { saveInstalledAppToDatabase(asset.name, asset.downloadUrl, asset.size, release.tagName) } installer.install(filePath, ext) _state.update { it.copy(downloadStage = DownloadStage.IDLE) } } } fun uninstallApp() { val installedApp = _state.value.installedApp ?: return installer.uninstall(installedApp.packageName) } } ``` -------------------------------- ### Koin Dependency Injection Initialization and Module Definition (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Demonstrates the setup and usage of Koin for dependency injection in the application. It shows the main initialization function `initKoin` which aggregates feature modules, and an example of a feature module (`homeModule`) defining its singletons. It also includes ViewModel module definitions and how ViewModels are injected into Composables. ```kotlin // Main Koin initialization fun initKoin(config: KoinAppDeclaration? = null) { startKoin { config?.invoke(this) modules( mainModule, corePlatformModule, coreModule, networkModule, databaseModule, viewModelsModule, appsModule, authModule, detailsModule, devProfileModule, homeModule, searchModule, settingsModule ) } } // Feature module example (homeModule) val homeModule = module { single { HomeRepositoryImpl( httpClient = get(), platform = get(), cachedDataSource = get(), logger = get(), cacheManager = get() ) } single { CachedRepositoriesDataSourceImpl(httpClient = get(), logger = get()) } } // ViewModel module with parameterized injection val viewModelsModule = module { viewModel { HomeViewModel(get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { SearchViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { params -> DetailsViewModel( repositoryId = params.get(), ownerParam = params.get(), repoParam = params.get(), detailsRepository = get(), downloader = get(), installer = get(), // ... other dependencies ) } } // ViewModel injection in Composables @Composable fun HomeScreen() { val viewModel: HomeViewModel = koinViewModel() // Use viewModel... } ``` -------------------------------- ### GET /installed-apps Source: https://context7.com/openhub-store/github-store/llms.txt Retrieves the list of all locally installed applications or those with pending updates. ```APIDOC ## GET /installed-apps ### Description Retrieves a list of all installed applications or applications that have available updates. ### Method GET ### Endpoint /installed-apps ### Response #### Success Response (200) - **apps** (List) - A list of installed application objects. #### Response Example { "apps": [ { "packageName": "com.example.app", "appName": "Example App", "installedVersion": "1.0.0", "isUpdateAvailable": false } ] } ``` -------------------------------- ### Installer Interface Definition (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Defines the core interface for platform installation operations, including checking support, ensuring permissions, installing, uninstalling, and managing app-related information. It abstracts away the underlying platform specifics. ```kotlin interface Installer { suspend fun isSupported(extOrMime: String): Boolean suspend fun ensurePermissionsOrThrow(extOrMime: String) suspend fun install(filePath: String, extOrMime: String) fun uninstall(packageName: String) fun isAssetInstallable(assetName: String): Boolean fun choosePrimaryAsset(assets: List): GithubAsset? fun detectSystemArchitecture(): SystemArchitecture fun isObtainiumInstalled(): Boolean fun openInObtainium(repoOwner: String, repoName: String, onOpenInstaller: () -> Unit) fun isAppManagerInstalled(): Boolean fun openInAppManager(filePath: String, onOpenInstaller: () -> Unit) fun getApkInfoExtractor(): InstallerInfoExtractor fun openApp(packageName: String): Boolean fun openWithExternalInstaller(filePath: String) } // System architecture for APK matching enum class SystemArchitecture { ARM64, ARM32, X86_64, X86, UNIVERSAL } ``` -------------------------------- ### Observe Installed Apps in ViewModel Source: https://context7.com/openhub-store/github-store/llms.txt Demonstrates how to consume the InstalledAppsRepository within a ViewModel to maintain application state. It uses StateFlow to reactively update the UI based on repository changes. ```kotlin class AppsViewModel( private val installedAppsRepository: InstalledAppsRepository, ) : ViewModel() { private val _state = MutableStateFlow(AppsState()) val state = _state.onStart { observeInstalledApps() observeUpdateCount() }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), AppsState()) private fun observeInstalledApps() { viewModelScope.launch { installedAppsRepository.getAllInstalledApps().collect { apps -> _state.update { it.copy(installedApps = apps) } } } } private fun observeUpdateCount() { viewModelScope.launch { installedAppsRepository.getUpdateCount().collect { count -> _state.update { it.copy(updateCount = count) } } } } fun checkForUpdates() { viewModelScope.launch { _state.update { it.copy(isCheckingUpdates = true) } installedAppsRepository.checkAllForUpdates() _state.update { it.copy(isCheckingUpdates = false) } } } } ``` -------------------------------- ### Implement Repository Details Loading Logic (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Demonstrates the usage of `DetailsRepository` within a `DetailsViewModel` to load repository information. It fetches repository details, all releases, README content, and statistics, then processes them to determine the selected release and installable assets. ```kotlin // Usage in DetailsViewModel class DetailsViewModel( private val repositoryId: Long, private val ownerParam: String, private val repoParam: String, private val detailsRepository: DetailsRepository, private val installer: Installer, ) : ViewModel() { private fun loadInitial() { viewModelScope.launch { val repo = if (ownerParam.isNotEmpty() && repoParam.isNotEmpty()) { detailsRepository.getRepositoryByOwnerAndName(ownerParam, repoParam) } else { detailsRepository.getRepositoryById(repositoryId) } val allReleases = detailsRepository.getAllReleases(repo.owner.login, repo.name, repo.defaultBranch) val readme = detailsRepository.getReadme(repo.owner.login, repo.name, repo.defaultBranch) val stats = detailsRepository.getRepoStats(repo.owner.login, repo.name) val selectedRelease = allReleases.firstOrNull { !it.isPrerelease } ?: allReleases.firstOrNull() val installableAssets = selectedRelease?.assets?.filter { installer.isAssetInstallable(it.name) } val primaryAsset = installer.choosePrimaryAsset(installableAssets.orEmpty()) _state.update { it.copy( repository = repo, allReleases = allReleases, selectedRelease = selectedRelease, installableAssets = installableAssets.orEmpty(), primaryAsset = primaryAsset, readmeMarkdown = readme?.first, stats = stats )} } } } ``` -------------------------------- ### PUT /installed-apps/{packageName} Source: https://context7.com/openhub-store/github-store/llms.txt Updates the metadata or version information for an existing installed application. ```APIDOC ## PUT /installed-apps/{packageName} ### Description Updates the version details or installation status of a specific application. ### Method PUT ### Endpoint /installed-apps/{packageName} ### Parameters #### Path Parameters - **packageName** (String) - Required - The unique identifier of the app. #### Request Body - **newVersionName** (String) - Required - The new version string. - **newVersionCode** (Long) - Required - The new version code. ### Response #### Success Response (200) - **message** (String) - Confirmation of the update. #### Response Example { "message": "App updated successfully" } ``` -------------------------------- ### Manage Installed Applications with InstalledAppsRepository Source: https://context7.com/openhub-store/github-store/llms.txt Defines the repository interface for CRUD operations on installed applications and the data model representing an installed app. It utilizes Kotlin Coroutines and Flow for reactive updates and asynchronous data handling. ```kotlin interface InstalledAppsRepository { fun getAllInstalledApps(): Flow> fun getAppsWithUpdates(): Flow> fun getUpdateCount(): Flow suspend fun getAppByPackage(packageName: String): InstalledApp? suspend fun getAppByRepoId(repoId: Long): InstalledApp? fun getAppByRepoIdAsFlow(repoId: Long): Flow suspend fun isAppInstalled(repoId: Long): Boolean suspend fun saveInstalledApp(app: InstalledApp) suspend fun deleteInstalledApp(packageName: String) suspend fun checkForUpdates(packageName: String): Boolean suspend fun checkAllForUpdates() suspend fun updateAppVersion(packageName: String, newTag: String, newAssetName: String, newAssetUrl: String, newVersionName: String, newVersionCode: Long) suspend fun updateApp(app: InstalledApp) suspend fun updatePendingStatus(packageName: String, isPending: Boolean) } data class InstalledApp( val packageName: String, val repoId: Long, val repoName: String, val repoOwner: String, val repoOwnerAvatarUrl: String, val repoDescription: String?, val primaryLanguage: String?, val repoUrl: String, val installedVersion: String, val installedAssetName: String?, val latestVersion: String?, val latestAssetName: String?, val latestAssetUrl: String?, val latestAssetSize: Long?, val appName: String, val installSource: InstallSource, val installedAt: Long, val lastCheckedAt: Long, val isUpdateAvailable: Boolean, val updateCheckEnabled: Boolean = true, val systemArchitecture: String, val fileExtension: String, val isPendingInstall: Boolean = false ) ``` -------------------------------- ### Repository Discovery and State Management in Kotlin Source: https://context7.com/openhub-store/github-store/llms.txt Defines the HomeRepository domain interface for fetching repository data and demonstrates its usage within a HomeViewModel to manage UI state, pagination, and installation status tracking. ```kotlin interface HomeRepository { fun getTrendingRepositories(page: Int): Flow fun getHotReleaseRepositories(page: Int): Flow fun getMostPopular(page: Int): Flow } class HomeViewModel( private val homeRepository: HomeRepository, private val installedAppsRepository: InstalledAppsRepository, ) : ViewModel() { private val _state = MutableStateFlow(HomeState()) val state = _state.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), HomeState()) private fun loadRepos(isInitial: Boolean = false, category: HomeCategory? = null) { viewModelScope.launch { _state.update { it.copy(isLoading = isInitial, isLoadingMore = !isInitial) } val flow = when (category ?: _state.value.currentCategory) { HomeCategory.TRENDING -> homeRepository.getTrendingRepositories(nextPageIndex) HomeCategory.HOT_RELEASE -> homeRepository.getHotReleaseRepositories(nextPageIndex) HomeCategory.MOST_POPULAR -> homeRepository.getMostPopular(nextPageIndex) } flow.collect { paginatedRepos -> val reposWithStatus = paginatedRepos.repos.map { repo -> DiscoveryRepository( isInstalled = installedAppsMap.containsKey(repo.id), isUpdateAvailable = installedAppsMap[repo.id]?.isUpdateAvailable ?: false, repository = repo ) } _state.update { it.copy(repos = it.repos + reposWithStatus, hasMorePages = paginatedRepos.hasMore) } } } } } enum class HomeCategory { TRENDING, HOT_RELEASE, MOST_POPULAR } ``` -------------------------------- ### Manage Favorite Repositories with FavouritesRepository Source: https://context7.com/openhub-store/github-store/llms.txt Defines the interface and data model for tracking favorite repositories locally. It includes methods for toggling status and updating installation states, demonstrated via a ViewModel implementation. ```kotlin interface FavouritesRepository { fun getAllFavorites(): Flow> fun isFavorite(repoId: Long): Flow suspend fun isFavoriteSync(repoId: Long): Boolean suspend fun toggleFavorite(repo: FavoriteRepo) suspend fun updateFavoriteInstallStatus(repoId: Long, installed: Boolean, packageName: String?) } data class FavoriteRepo( val repoId: Long, val repoName: String, val repoOwner: String, val repoOwnerAvatarUrl: String, val repoDescription: String?, val primaryLanguage: String?, val repoUrl: String, val latestVersion: String?, val latestReleaseUrl: String?, val addedAt: Long, val lastSyncedAt: Long, val isInstalled: Boolean = false, val packageName: String? = null ) class DetailsViewModel( private val favouritesRepository: FavouritesRepository, ) : ViewModel() { fun toggleFavorite() { viewModelScope.launch { val repo = _state.value.repository ?: return@launch val selectedRelease = _state.value.selectedRelease val favoriteRepo = FavoriteRepo( repoId = repo.id, repoName = repo.name, repoOwner = repo.owner.login, repoOwnerAvatarUrl = repo.owner.avatarUrl, repoDescription = repo.description, primaryLanguage = repo.language, repoUrl = repo.htmlUrl, latestVersion = selectedRelease?.tagName, latestReleaseUrl = selectedRelease?.htmlUrl, addedAt = Clock.System.now().toEpochMilliseconds(), lastSyncedAt = Clock.System.now().toEpochMilliseconds() ) favouritesRepository.toggleFavorite(favoriteRepo) val newFavoriteState = favouritesRepository.isFavoriteSync(repo.id) _state.update { it.copy(isFavourite = newFavoriteState) } } } } ``` -------------------------------- ### Implement GitHub OAuth Device Flow with AuthenticationRepository Source: https://context7.com/openhub-store/github-store/llms.txt Handles GitHub authentication using the OAuth Device Flow. It provides an interface for requesting device codes and polling for access tokens, with a ViewModel example for managing the authentication state. ```kotlin interface AuthenticationRepository { val accessTokenFlow: Flow suspend fun startDeviceFlow(): GithubDeviceStart suspend fun awaitDeviceToken(start: GithubDeviceStart): GithubDeviceTokenSuccess } data class GithubDeviceStart( val deviceCode: String, val userCode: String, val verificationUri: String, val expiresInSec: Int, val intervalSec: Int ) class AuthenticationViewModel( private val authRepository: AuthenticationRepository, private val browserHelper: BrowserHelper, ) : ViewModel() { fun startAuthentication() { authJob = viewModelScope.launch { try { _state.update { it.copy(isLoading = true, error = null) } val deviceStart = authRepository.startDeviceFlow() _state.update { it.copy( userCode = deviceStart.userCode, verificationUrl = deviceStart.verificationUri, isLoading = false )} browserHelper.openUrl(deviceStart.verificationUri) val token = authRepository.awaitDeviceToken(deviceStart) _state.update { it.copy(isAuthenticated = true) } _events.send(AuthEvent.AuthenticationSuccess) } catch (e: Exception) { _state.update { it.copy(isLoading = false, error = e.message) } } } } } ``` -------------------------------- ### AppsRepository Interface Definition Source: https://github.com/openhub-store/github-store/blob/main/feature/apps/CLAUDE.md Defines the core contract for managing installed applications. It provides methods to retrieve the list of apps, launch a specific application, and fetch the latest release information from GitHub. ```kotlin interface AppsRepository { suspend fun getApps(): Flow> suspend fun openApp(installedApp: InstalledApp, onCantLaunchApp: () -> Unit = {}) suspend fun getLatestRelease(owner: String, repo: String): GithubRelease? } ``` -------------------------------- ### Define Profile State Model Source: https://github.com/openhub-store/github-store/blob/main/feature/profile/CLAUDE.md Represents the UI state for the profile screen, aggregating user data, theme preferences, proxy configurations, and installation status. This data class is used by the ViewModel to drive the UI components. ```kotlin data class ProfileState( val userProfile: UserProfile?, val selectedThemeColor: AppTheme, val selectedFontTheme: FontTheme, val isLogoutDialogVisible: Boolean, val isUserLoggedIn: Boolean, val isAmoledThemeEnabled: Boolean, val isDarkTheme: Boolean?, val versionName: String, val proxyType: ProxyType, val proxyHost: String, val proxyPort: String, val proxyUsername: String, val proxyPassword: String, val isProxyPasswordVisible: Boolean, val autoDetectClipboardLinks: Boolean, val cacheSize: String, val installerType: InstallerType, val shizukuAvailability: ShizukuAvailability ) ``` -------------------------------- ### Build and Run Commands for GitHub Store Source: https://github.com/openhub-store/github-store/blob/main/CLAUDE.md Provides Gradle commands for building, running, and packaging the GitHub Store application for Android and Desktop platforms. Requires JDK 21+ and Android SDK. ```bash # Android ./gradlew :composeApp:assembleDebug ./gradlew :composeApp:assembleRelease # Desktop (run in dev mode) ./gradlew :composeApp:run # Desktop installers ./gradlew :composeApp:packageExe :composeApp:packageMsi # Windows ./gradlew :composeApp:packageDmg :composeApp:packagePkg # macOS ./gradlew :composeApp:packageDeb :composeApp:packageRpm # Linux # Full build check ./gradlew build ``` -------------------------------- ### Configure and Execute GitHub API Requests with Ktor Source: https://context7.com/openhub-store/github-store/llms.txt This snippet provides a factory function to initialize a Ktor HttpClient with GitHub-specific headers, retry policies, and rate limit interception. It also includes an extension function for executing requests and handling responses safely using Kotlin Result types. ```kotlin fun createGitHubHttpClient( tokenStore: TokenStore, rateLimitRepository: RateLimitRepository, authenticationState: AuthenticationState? = null, scope: CoroutineScope? = null, proxyConfig: ProxyConfig = ProxyConfig.None ): HttpClient { val json = Json { ignoreUnknownKeys = true isLenient = true } return createPlatformHttpClient(proxyConfig).config { install(RateLimitInterceptor) { this.rateLimitRepository = rateLimitRepository } install(ContentNegotiation) { json(json) } install(HttpTimeout) { connectTimeoutMillis = 30_000 socketTimeoutMillis = HttpTimeoutConfig.INFINITE_TIMEOUT_MS } install(HttpRequestRetry) { maxRetries = 3 retryIf { _, response -> response.status.value in 500..<600 } exponentialDelay() } defaultRequest { url("https://api.github.com") header(HttpHeaders.Accept, "application/vnd.github+json") header("X-GitHub-Api-Version", "2022-11-28") header(HttpHeaders.UserAgent, "GithubStore/1.0 (KMP)") val token = tokenStore.blockingCurrentToken()?.accessToken?.trim().orEmpty() if (token.isNotEmpty()) { header(HttpHeaders.Authorization, "Bearer $token") } } } } suspend inline fun HttpClient.executeRequest( crossinline block: suspend HttpClient.() -> HttpResponse ): Result = try { val response = block() if (response.status.isSuccess()) { Result.success(response.body()) } else { Result.failure(Exception("HTTP ${response.status.value}: ${response.status.description}")) } } catch (e: RateLimitException) { throw e } catch (e: Exception) { Result.failure(e) } ``` -------------------------------- ### SearchRepository Interface and ViewModel for GitHub Repository Search (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Defines the SearchRepository interface for searching GitHub repositories with filters like platform, language, and sort options. Includes a Kotlin ViewModel demonstrating usage with debounced search, state management, and paginated results. Dependencies include Kotlin coroutines (Flow, ViewModel, StateFlow, launch, delay) and the application's domain models. ```kotlin interface SearchRepository { fun searchRepositories( query: String, searchPlatform: SearchPlatform, language: ProgrammingLanguage, sortBy: SortBy, sortOrder: SortOrder, page: Int, ): Flow } enum class SearchPlatform { All, Android, Windows, Macos, Linux } enum class SortBy { BestMatch, Stars, Forks, Updated } enum class SortOrder { Ascending, Descending } class SearchViewModel( private val searchRepository: SearchRepository, ) : ViewModel() { private val _state = MutableStateFlow(SearchState()) val state = _state.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), SearchState()) private fun performSearch(isInitial: Boolean = false) { val query = _state.value.query.trim() if (query.length < 3) return // Minimum query length currentSearchJob = viewModelScope.launch { _state.update { it.copy(isLoading = isInitial, repositories = if (isInitial) emptyList() else it.repositories) } searchRepository.searchRepositories( query = query, searchPlatform = _state.value.selectedSearchPlatform, language = _state.value.selectedLanguage, sortBy = _state.value.selectedSortBy, sortOrder = _state.value.selectedSortOrder, page = currentPage ).collect { paginatedRepos -> currentPage = paginatedRepos.nextPageIndex _state.update { it.copy( repositories = it.repositories + paginatedRepos.repos.map { DiscoveryRepository(repository = repo) }, hasMorePages = paginatedRepos.hasMore ) } } } } fun onAction(action: SearchAction) { when (action) { is SearchAction.OnSearchChange -> { _state.update { it.copy(query = action.query) } searchDebounceJob?.cancel() searchDebounceJob = viewModelScope.launch { delay(800) // Debounce performSearch(isInitial = true) } } SearchAction.LoadMore -> if (_state.value.hasMorePages) performSearch(isInitial = false) } } } ``` -------------------------------- ### Define Repository Details Interface and Models (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Defines the `DetailsRepository` interface for fetching repository details and related data. Includes core domain models like `GithubRepoSummary`, `GithubRelease`, and `GithubAsset` for data representation. These models are annotated with `@Serializable` for JSON serialization. ```kotlin // Domain interface for repository details interface DetailsRepository { suspend fun getRepositoryById(id: Long): GithubRepoSummary suspend fun getRepositoryByOwnerAndName(owner: String, name: String): GithubRepoSummary suspend fun getLatestPublishedRelease(owner: String, repo: String, defaultBranch: String): GithubRelease? suspend fun getAllReleases(owner: String, repo: String, defaultBranch: String): List suspend fun getReadme(owner: String, repo: String, defaultBranch: String): Triple? suspend fun getRepoStats(owner: String, repo: String): RepoStats suspend fun getUserProfile(username: String): GithubUserProfile } // Core domain models @Serializable data class GithubRepoSummary( val id: Long, val name: String, val fullName: String, val owner: GithubUser, val description: String?, val defaultBranch: String, val htmlUrl: String, val stargazersCount: Int, val forksCount: Int, val language: String?, val topics: List?, val availablePlatforms: List = emptyList() ) @Serializable data class GithubRelease( val id: Long, val tagName: String, val name: String?, val author: GithubUser, val publishedAt: String, val description: String?, val assets: List, val isPrerelease: Boolean = false ) @Serializable data class GithubAsset( val id: Long, val name: String, val contentType: String, val size: Long, val downloadUrl: String, val uploader: GithubUser ) ``` -------------------------------- ### POST /installed-apps/update-check Source: https://context7.com/openhub-store/github-store/llms.txt Triggers an update check for a specific application or the entire library. ```APIDOC ## POST /installed-apps/update-check ### Description Triggers a background check to see if new versions are available for installed applications. ### Method POST ### Endpoint /installed-apps/update-check ### Parameters #### Query Parameters - **packageName** (String) - Optional - If provided, checks only this specific app. ### Response #### Success Response (200) - **status** (Boolean) - Returns true if the check was initiated successfully. #### Response Example { "status": true } ``` -------------------------------- ### MVVM State Management Pattern in Kotlin Source: https://github.com/openhub-store/github-store/blob/main/CLAUDE.md Demonstrates the State/Action/Event pattern for state management in ViewModels using Kotlin Coroutines. It utilizes MutableStateFlow for state and Channel for events. ```kotlin class XViewModel : ViewModel() { private val _state = MutableStateFlow(XState()) val state = _state.asStateFlow() // or .stateIn() with WhileSubscribed private val _events = Channel() val events = _events.receiveAsFlow() fun onAction(action: XAction) { ... } } ``` -------------------------------- ### Define Home Repository Interface Source: https://github.com/openhub-store/github-store/blob/main/feature/home/CLAUDE.md The HomeRepository interface defines the contract for fetching paginated repository data across different categories. It returns Kotlin Flows to support reactive updates and asynchronous data streaming. ```kotlin interface HomeRepository { fun getTrendingRepositories(page: Int): Flow fun getHotReleaseRepositories(page: Int): Flow fun getMostPopular(page: Int): Flow } ``` -------------------------------- ### Type-Safe Navigation Routes with Sealed Interfaces (Kotlin) Source: https://context7.com/openhub-store/github-store/llms.txt Defines type-safe navigation routes using serializable sealed interfaces in Kotlin. This approach ensures that navigation arguments are strongly typed, preventing runtime errors. It supports various screen types, including those with parameters like repository details and developer profiles. ```kotlin // Type-safe navigation routes @Serializable sealed interface GithubStoreGraph { @Serializable data object HomeScreen : GithubStoreGraph @Serializable data object SearchScreen : GithubStoreGraph @Serializable data object AuthenticationScreen : GithubStoreGraph @Serializable data object ProfileScreen : GithubStoreGraph @Serializable data object FavouritesScreen : GithubStoreGraph @Serializable data object StarredReposScreen : GithubStoreGraph @Serializable data object AppsScreen : GithubStoreGraph @Serializable data object SponsorScreen : GithubStoreGraph @Serializable data class DetailsScreen( val repositoryId: Long = -1L, val owner: String = "", val repo: String = "", val isComingFromUpdate: Boolean = false ) : GithubStoreGraph @Serializable data class DeveloperProfileScreen( val username: String ) : GithubStoreGraph } // Navigation usage in Composables @Composable fun AppNavigation(navController: NavHostController) { NavHost(navController = navController, startDestination = GithubStoreGraph.HomeScreen) { composable { val viewModel: HomeViewModel = koinViewModel() HomeRoot( state = viewModel.state.collectAsState().value, onAction = viewModel::onAction, onNavigateToDetails = { repo -> navController.navigate(GithubStoreGraph.DetailsScreen(repositoryId = repo.id)) }, onNavigateToSearch = { navController.navigate(GithubStoreGraph.SearchScreen) } ) } composable { backStackEntry -> val args = backStackEntry.toRoute() val viewModel: DetailsViewModel = koinViewModel { parametersOf(args.repositoryId, args.owner, args.repo, args.isComingFromUpdate) } DetailsRoot( state = viewModel.state.collectAsState().value, onAction = viewModel::onAction, onNavigateBack = { navController.popBackStack() } ) } } } // Deep link handling: githubstore://repo or https://github-store.org/app?repo=owner/name ``` -------------------------------- ### Define Proxy Configuration for Network Routing Source: https://context7.com/openhub-store/github-store/llms.txt A sealed class hierarchy used to define various proxy routing strategies, including direct connections, system defaults, HTTP proxies, and SOCKS proxies. ```kotlin sealed class ProxyConfig { data object None : ProxyConfig() data object System : ProxyConfig() data class Http(val host: String, val port: Int, val username: String? = null, val password: String? = null) : ProxyConfig() data class Socks(val host: String, val port: Int, val username: String? = null, val password: String? = null) : ProxyConfig() } ``` -------------------------------- ### Define Repository Data Interfaces Source: https://github.com/openhub-store/github-store/blob/main/feature/details/CLAUDE.md Core interfaces for fetching repository metadata, releases, readme content, and translation services. These interfaces define the contract for data retrieval and external translation API integration. ```kotlin interface DetailsRepository { suspend fun getRepositoryById(id: Long): GithubRepoSummary suspend fun getRepositoryByOwnerAndName(owner: String, name: String): GithubRepoSummary suspend fun getLatestPublishedRelease(owner: String, repo: String, defaultBranch: String): GithubRelease? suspend fun getAllReleases(owner: String, repo: String, defaultBranch: String): List suspend fun getReadme(owner: String, repo: String, defaultBranch: String): Triple? suspend fun getRepoStats(owner: String, repo: String): RepoStats suspend fun getUserProfile(username: String): GithubUserProfile } interface TranslationRepository { suspend fun translate(text: String, targetLanguage: SupportedLanguage): TranslationResult } ``` -------------------------------- ### SearchRepository Interface Definition Source: https://github.com/openhub-store/github-store/blob/main/feature/search/CLAUDE.md Defines the contract for searching GitHub repositories. It accepts filter parameters including platform, language, and sort order, returning a paginated flow of results. ```kotlin interface SearchRepository { fun searchRepositories( query: String, searchPlatform: SearchPlatform, language: ProgrammingLanguage, sortBy: SortBy, page: Int ): Flow } ``` -------------------------------- ### Define Profile Repository Interface Source: https://github.com/openhub-store/github-store/blob/main/feature/profile/CLAUDE.md Defines the contract for profile-related data operations, including authentication state, user profile retrieval, and cache management. This interface is implemented to bridge the domain layer with data sources. ```kotlin interface ProfileRepository { val isUserLoggedIn: Flow fun getUser(): Flow fun getVersionName(): String suspend fun logout() fun observeCacheSize(): Flow suspend fun clearCache() } ``` -------------------------------- ### Developer Profile Repository Interface (Kotlin) Source: https://github.com/openhub-store/github-store/blob/main/feature/dev-profile/CLAUDE.md Defines the contract for fetching a developer's profile information and their repositories. It uses Kotlin coroutines and returns results wrapped in a `Result` type for error handling. Dependencies include the `DeveloperProfile` and `DeveloperRepository` data models. ```kotlin interface DeveloperProfileRepository { suspend fun getDeveloperProfile(username: String): Result suspend fun getDeveloperRepositories(username: String): Result> } ``` -------------------------------- ### AuthenticationRepository Interface for GitHub Device Flow Source: https://github.com/openhub-store/github-store/blob/main/feature/auth/CLAUDE.md Defines the contract for the authentication repository, providing a flow for access tokens and methods to initiate and poll for device authorization. This interface abstracts the complexity of the GitHub OAuth device flow from the presentation layer. ```kotlin interface AuthenticationRepository { val accessTokenFlow: Flow suspend fun startDeviceFlow(): GithubDeviceStart suspend fun awaitDeviceToken(start: GithubDeviceStart): GithubDeviceTokenSuccess } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.