diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7b70f8bf..2c67a627 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,7 @@ "jdkDistro": "oracle" } }, - "postCreateCommand": "chmod +x gradlew && deno run -A scripts/download_deps.ts --yes && cp revoltbuild.properties.example revoltbuild.properties && cp sentry.properties.example sentry.properties && cp app/google-services.json.example app/google-services.json && git submodule update --init --recursive", + "postCreateCommand": "chmod +x gradlew && deno run -A scripts/download_deps.ts --yes && cp revoltbuild.properties.example revoltbuild.properties && cp sentry.properties.example sentry.properties && cp app/google-services.json.example app/google-services.json && git submodule update --init --recursive && sudo apt-get -y install magic-wormhole", "customizations": { "vscode": { "extensions": [ diff --git a/.gitignore b/.gitignore index 8033a71f..b13f1d4e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ app/src/main/assets/embedded /app/src/main/jniLibs/armeabi-v7a/ /app/src/main/jniLibs/x86/ /app/src/main/jniLibs/x86_64/ +app/release-key.keystore diff --git a/README.md b/README.md index 6929b8ec..9914fdd9 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,51 @@ +# Revolt for Android (Forked Version!) +
-

Revolt for Android

-

Official Revolt Android app.

+

Revolt for Android (Forked Version!)

+

Forked Version of the Revolt Android app.



- Get it on Google Play + image
- Google Play is a trademark of Google LLC.


+ + + ## Description +NOTE: This is a forked version of the Android app for the [Revolt](https://revolt.chat) chat platform. I made for some QOL changes that aren't present in the current version at the time of writing. + +Feel free to use this for whatever, but note that this is NOT the official Revolt android app. :) + +You can download the latest APK [here](https://github.com/alexjyong/android/releases/download/1.3.6ba-forked/app-release.apk). + +Or the latest debug APK [here](https://github.com/alexjyong/android/releases/download/1.3.6ba-forked/app-debug.apk). + +## Features Added + + + + + + + + +
+ Emojis next to channel names
+ Channel Emojis +
+ Jump to replied message
+ Jump to Reply +
+ Server context menu on long press
+ Server Context Menu +
+ + + The codebase includes the app itself, as well as an internal library for interacting with the Revolt API. The app is written in Kotlin, and wholly uses [Jetpack Compose](https://developer.android.com/jetpack/compose). @@ -43,6 +77,51 @@ uses [Jetpack Compose](https://developer.android.com/jetpack/compose). - [Revolt Server](https://app.revolt.chat/invite/Testers) - [General Revolt Contribution Guide](https://developers.revolt.chat/contrib.html) +## Quick Build + +If you don't want to download the apks in the releases section and rather build yourself, follow these steps: + +Fire up a Github Codespaces instance at this link [here](https://github.com/codespaces/new?hide_repo_select=true&ref=combined-pr&repo=1020437871&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json&geo=UsEast) + +The URL should have it selected for you automatically, but be sure to use this branch for your instance! + +Note that this url will have an 8-core instance selected by default. Feel free to use a smaller instance, but I've ran into build errors with that. +At the time of writing, Github offers a number of free hours for personal accounts, but note that this bigger instance will use more of your free hours than a smaller one. **For just building the apk and downloading it to whatever device, this should be fine though**. Be sure to delete the instance when you are done. **It won't cost you $$ if you don't have payment set up with Github or have budget limits.** [See the billing page for more details.](https://docs.github.com/en/billing/concepts/product-billing/github-codespaces#pricing-for-paid-usage) + +After the instance fires up run + +```sh +./gradlew assembledebug --no-daemon +``` +To generate a debug version of the application. + +If you wanted a signed copy that isn't in debug mode, set up a release-key.keystore file, update revoltbuild.properties to have your passwords and run: + +```sh +./gradlew assembleRelease -x app:uploadSentryProguardMappingsRelease +``` + +It will be located in `app/build/outputs/apk/debug/` under the name `app-debug.apk` + +Download it to your system by right clicking on the file like so: + +image + +Send it to your phone, and install and run it! + +Alternatively, you can send it to your phone right from Codespaces using magic wormhole (installed on this codespace instance by default) + +`wormhole send app/build/outputs/apk/debug/app-debug.apk` + +It will give you a code that you can punch into your phone. + +Either use the [Wormhole William app from the Google Playstore](https://play.google.com/store/apps/details?id=io.sanford.wormhole_william&hl=en_US) + +Or get the apk [directly from here](https://github.com/psanford/wormhole-william-mobile/releases/tag/v1.0.13) + +Or install [Termux](https://termux.dev/en/), then install `wormhole-rs` on Termux with `pkg install magic-wormhole-rs` and fetch the apk with +`wormhole-rs receive YOUR_CODE_HERE` + ## Quick Start Open the project in Android Studio. You can then run the app on an emulator or a physical device by diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a807dbcf..c5daa312 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -76,11 +76,11 @@ android { compileSdk = 36 defaultConfig { - applicationId = "chat.revolt" + applicationId = "chat.revolt.forked" minSdk = 24 targetSdk = 36 versionCode = Integer.parseInt("001_003_206".replace("_", ""), 10) - versionName = "1.3.6b" + versionName = "1.3.6ba-forked" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -95,6 +95,15 @@ android { } } + signingConfigs { + create("release") { + storeFile = file(buildproperty("signing.store_file", "SIGNING_STORE_FILE") ?: "release-key.keystore") + storePassword = buildproperty("signing.store_password", "SIGNING_STORE_PASSWORD") + keyAlias = buildproperty("signing.key_alias", "SIGNING_KEY_ALIAS") + keyPassword = buildproperty("signing.key_password", "SIGNING_KEY_PASSWORD") + } + } + buildTypes { release { isMinifyEnabled = true @@ -113,6 +122,7 @@ android { "FLAVOUR_ID", "\"${buildproperty("build.flavour_id", "RVX_BUILD_FLAVOUR_ID")}\"" ) + signingConfig = signingConfigs.getByName("release") } debug { diff --git a/app/google-services.json.example b/app/google-services.json.example index 997e884c..d512b007 100644 --- a/app/google-services.json.example +++ b/app/google-services.json.example @@ -9,7 +9,7 @@ "client_info": { "mobilesdk_app_id": "1:123456789012:android:abcdef1234567890", "android_client_info": { - "package_name": "chat.revolt" + "package_name": "chat.revolt.forked" } }, "oauth_client": [ @@ -38,7 +38,7 @@ "client_info": { "mobilesdk_app_id": "1:123456789012:android:abcdef1234567891", "android_client_info": { - "package_name": "chat.revolt.debug" + "package_name": "chat.revolt.forked.debug" } }, "oauth_client": [ @@ -65,4 +65,4 @@ } ], "configuration_version": "1" -} \ No newline at end of file +} diff --git a/app/src/main/java/chat/revolt/composables/chat/Message.kt b/app/src/main/java/chat/revolt/composables/chat/Message.kt index 4e68651d..0e5bf881 100644 --- a/app/src/main/java/chat/revolt/composables/chat/Message.kt +++ b/app/src/main/java/chat/revolt/composables/chat/Message.kt @@ -196,6 +196,8 @@ fun Message( onAddReaction: () -> Unit = {}, fromWebhook: Boolean = false, webhookName: String? = null, + jumpToMessage: (String) -> Unit = {}, + highlightedMessageId: String? = null, modifier: Modifier = Modifier ) { val author = RevoltAPI.userCache[message.author] ?: return CircularProgressIndicator() @@ -281,16 +283,21 @@ fun Message( } else { Column( modifier = Modifier.then( - if ((message.mentions?.contains(RevoltAPI.selfId) == true) - || mentionsSelfRole - || message.flags has MessageFlag.MentionsOnline - || message.flags has MessageFlag.MentionsEveryone - ) { - Modifier.background( - MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) - ) - } else { - Modifier + when { + highlightedMessageId == message.id -> { + Modifier.background( + MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f) + ) + } + (message.mentions?.contains(RevoltAPI.selfId) == true) + || mentionsSelfRole + || message.flags has MessageFlag.MentionsOnline + || message.flags has MessageFlag.MentionsEveryone -> { + Modifier.background( + MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) + ) + } + else -> Modifier } ) ) { @@ -306,11 +313,8 @@ fun Message( replyMessage.author ) } == true), - ) { - // TODO Add jump to message - if (replyMessage == null) { - Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show() - } + ) { messageId -> + jumpToMessage(messageId) } } } diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/ChannelHeader.kt b/app/src/main/java/chat/revolt/composables/screens/chat/ChannelHeader.kt index a841cd63..fad9385e 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/ChannelHeader.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/ChannelHeader.kt @@ -64,10 +64,20 @@ fun ChannelHeader( } channel.channelType?.let { - ChannelIcon( - channelType = it, - modifier = Modifier.alpha(0.6f) - ) + when (it) { + ChannelType.TextChannel, ChannelType.VoiceChannel -> { + ChannelIcon( + channel = channel, + modifier = Modifier.alpha(0.6f) + ) + } + else -> { + ChannelIcon( + channelType = it, + modifier = Modifier.alpha(0.6f) + ) + } + } } Spacer(modifier = Modifier.width(8.dp)) diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/ChannelIcon.kt b/app/src/main/java/chat/revolt/composables/screens/chat/ChannelIcon.kt index 59e00931..105cdacf 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/ChannelIcon.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/ChannelIcon.kt @@ -1,15 +1,21 @@ package chat.revolt.composables.screens.chat +import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp import chat.revolt.R +import chat.revolt.api.REVOLT_FILES +import chat.revolt.api.schemas.Channel import chat.revolt.api.schemas.ChannelType +import chat.revolt.composables.generic.RemoteImage @Composable fun ChannelIcon(channelType: ChannelType, modifier: Modifier = Modifier) { @@ -56,6 +62,29 @@ fun ChannelIcon(channelType: ChannelType, modifier: Modifier = Modifier) { } } +@Composable +fun ChannelIcon( + channel: Channel, + modifier: Modifier = Modifier, + size: androidx.compose.ui.unit.Dp = 24.dp +) { + val channelType = channel.channelType ?: ChannelType.TextChannel + + if (channel.icon?.id != null) { + RemoteImage( + url = "$REVOLT_FILES/icons/${channel.icon.id}", + description = channel.name ?: stringResource(R.string.unknown), + contentScale = ContentScale.Crop, + height = size.value.toInt(), + width = size.value.toInt(), + allowAnimation = false, + modifier = modifier.size(size) + ) + } else { + ChannelIcon(channelType = channelType, modifier = modifier) + } +} + class ChannelTypeProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt b/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt index 3ba2a7e4..234fb3a3 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt @@ -70,6 +70,8 @@ fun RegularMessage( showReactBottomSheet: () -> Unit, putTextAtCursorPosition: (String) -> Unit, replyToMessage: suspend (String) -> Unit, + jumpToMessage: (String) -> Unit = {}, + highlightedMessageId: String? = null, scope: CoroutineScope = rememberCoroutineScope() ) { val haptic = LocalHapticFeedback.current @@ -182,6 +184,8 @@ fun RegularMessage( }, fromWebhook = message.webhook != null, webhookName = message.webhook?.name, + jumpToMessage = jumpToMessage, + highlightedMessageId = highlightedMessageId, modifier = Modifier .offset( x = with(LocalDensity.current) { animOffsetX.toDp() } diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt b/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt index c78fb7c4..202f71c9 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt @@ -98,7 +98,9 @@ import chat.revolt.composables.generic.presenceFromStatus import chat.revolt.composables.screens.chat.ChannelIcon import chat.revolt.screens.chat.ChatRouterDestination import chat.revolt.screens.chat.LocalIsConnected +import chat.revolt.screens.chat.dialogs.safety.ReportServerDialog import chat.revolt.sheets.ChannelContextSheet +import chat.revolt.sheets.ServerContextSheet import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @@ -183,6 +185,10 @@ fun ChannelSideDrawer( }.sortedBy { it.id })) var channelContextSheetTarget by remember { mutableStateOf(null) } + var serverContextSheetTarget by remember { mutableStateOf(null) } + + var showReportServer by remember { mutableStateOf(false) } + var reportServerTarget by remember { mutableStateOf("") } if (channelContextSheetTarget != null) { val channelContextSheetState = rememberModalBottomSheetState() @@ -203,6 +209,29 @@ fun ChannelSideDrawer( } } + if (serverContextSheetTarget != null) { + val serverContextSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + + ModalBottomSheet( + sheetState = serverContextSheetState, + onDismissRequest = { + serverContextSheetTarget = null + } + ) { + ServerContextSheet( + serverId = serverContextSheetTarget!!, + onReportServer = { + reportServerTarget = serverContextSheetTarget!! + showReportServer = true + }, + onHideSheet = { + serverContextSheetState.hide() + serverContextSheetTarget = null + } + ) + } + } + val scope = rememberCoroutineScope() Row(modifier.fillMaxSize()) { @@ -355,12 +384,19 @@ fun ChannelSideDrawer( Modifier .padding(8.dp) .clip(CircleShape) - .clickable { - serverInList.id?.let { srvId -> navigateToServer(srvId) } - scope.launch { - drawerState?.close() + .combinedClickable( + onClick = { + serverInList.id?.let { srvId -> navigateToServer(srvId) } + scope.launch { + drawerState?.close() + } + }, + onLongClick = { + serverInList.id?.let { srvId -> + serverContextSheetTarget = srvId + } } - }) { + )) { val icon = serverInList.icon?.id?.let { iconId -> "$REVOLT_FILES/icons/$iconId" } @@ -594,6 +630,15 @@ fun ChannelSideDrawer( } } } + + if (showReportServer) { + ReportServerDialog( + onDismiss = { + showReportServer = false + }, + serverId = reportServerTarget + ) + } } @Composable @@ -924,7 +969,7 @@ fun ChannelItem( ) } - else -> ChannelIcon(iconType.type) + else -> ChannelIcon(channel = channel, size = 24.dp) } } @@ -1085,4 +1130,4 @@ fun DMOrGroupItem( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt index 08e3b1f7..75e55389 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt @@ -551,6 +551,14 @@ fun ChannelScreen( ) } + ChannelType.TextChannel, ChannelType.VoiceChannel -> { + ChannelIcon( + channel = it, + size = 24.dp, + modifier = Modifier.alpha(0.8f) + ) + } + else -> { ChannelIcon( channelType = it.channelType ?: ChannelType.TextChannel, @@ -677,6 +685,16 @@ fun ChannelScreen( modifier = Modifier.weight(1f), contentAlignment = Alignment.BottomCenter ) { + val jumpToMessage: (String) -> Unit = { messageId -> + viewModel.setHighlightedMessage(messageId) + val messageIndex = viewModel.findMessageIndex(messageId) + if (messageIndex >= 0) { + scope.launch { + lazyListState.animateScrollToItem(messageIndex) + } + } + } + LazyColumn( state = lazyListState, userScrollEnabled = !disableScroll, @@ -748,6 +766,8 @@ fun ChannelScreen( }, putTextAtCursorPosition = viewModel::putAtCursorPosition, replyToMessage = viewModel::addReplyTo, + jumpToMessage = jumpToMessage, + highlightedMessageId = viewModel.highlightedMessageId, scope = scope ) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt index 1402e278..dbb0e058 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt @@ -106,6 +106,8 @@ class ChannelScreenViewModel @Inject constructor( var ageGateUnlocked by mutableStateOf(null) var showGeoGate by mutableStateOf(false) + var highlightedMessageId by mutableStateOf(null) + init { viewModelScope.launch { keyboardHeight = kvStorage.getInt("keyboardHeight") ?: 900 // reasonable default for now @@ -311,6 +313,27 @@ class ChannelScreenViewModel @Inject constructor( keyboardHeight = height } + fun setHighlightedMessage(messageId: String) { + highlightedMessageId = messageId + + viewModelScope.launch { + delay(3000) // 3 second highlight + if (highlightedMessageId == messageId) { + highlightedMessageId = null + } + } + } + + fun findMessageIndex(messageId: String): Int { + return items.indexOfFirst { item -> + when (item) { + is ChannelScreenItem.RegularMessage -> item.message.id == messageId + is ChannelScreenItem.SystemMessage -> item.message.id == messageId + else -> false + } + } + } + private suspend fun applyMessageEdit() { try { editMessage( diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 6a29b828..ee6a72ec 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -6,4 +6,11 @@ + + diff --git a/app/src/main/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml index 6a29b828..1fb94380 100644 --- a/app/src/main/res/drawable/ic_launcher_monochrome.xml +++ b/app/src/main/res/drawable/ic_launcher_monochrome.xml @@ -5,5 +5,12 @@ android:viewportHeight="108"> + android:fillColor="#000000"/> + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index fe170f68..0fa2720a 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 7b2c74f4..0fa2720a 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index ee98a72a..e6079fcb 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 62f042b2..e6079fcb 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index b9044ea5..4f005df3 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 4223efd3..4f005df3 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 4bc233c3..4d2b4569 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index a7d0a9cc..4d2b4569 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index b67bea85..ffa2d260 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index c4c69dc7..ffa2d260 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4aff6a52..78d7e200 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Revolt + Revolt Forked ← Back Next → @@ -476,6 +476,16 @@ An error occurred while creating your server. Please try again later. Create + Add Server + Join by invite code or link + Invite code or link + Enter a link like rvlt.gg/Testers or an invite code like Testers + Invite code or link + Join + Create a new server + Create a new server + This feature is currently under construction. + Discover Revolt Report diff --git a/generate_icon_pngs.sh b/generate_icon_pngs.sh new file mode 100755 index 00000000..5c048bc3 --- /dev/null +++ b/generate_icon_pngs.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# script to generate PNG icons from vector drawable +# this converts the vector drawable to PNGs for all required densities + +VECTOR_FILE="app/src/main/res/drawable/ic_launcher_foreground.xml" +OUTPUT_BASE="app/src/main/res" + +declare -A SIZES=( + ["mdpi"]=48 + ["hdpi"]=72 + ["xhdpi"]=96 + ["xxhdpi"]=144 + ["xxxhdpi"]=192 +) + +echo "Generating PNG icons from vector drawable..." + +TEMP_SVG="/tmp/temp_icon.svg" + +cat > "$TEMP_SVG" << 'EOF' + + + + + + + +EOF + +echo "Created temporary SVG file" + +for density in "${!SIZES[@]}"; do + size=${SIZES[$density]} + output_dir="$OUTPUT_BASE/mipmap-$density" + + echo "Generating ${density} (${size}x${size})..." + + rsvg-convert -w $size -h $size "$TEMP_SVG" -o "$output_dir/ic_launcher.png" + + # Generate round icon (same image, Android will clip it) + rsvg-convert -w $size -h $size "$TEMP_SVG" -o "$output_dir/ic_launcher_round.png" +done + +rm "$TEMP_SVG" + +echo "Done! Generated PNG icons for all densities." +echo "Icons generated in: $OUTPUT_BASE/mipmap-*/" diff --git a/revoltbuild.properties.example b/revoltbuild.properties.example index ea6a101c..648c0c28 100644 --- a/revoltbuild.properties.example +++ b/revoltbuild.properties.example @@ -1,4 +1,10 @@ sentry.dsn= sentry.upload_mappings=true -build.debug.app_name= -build.flavour_id=ZZUU \ No newline at end of file +build.debug.app_name=Revolt Forked +build.flavour_id=ZZUU + +# Release signing configuration +signing.store_file=release-key.keystore +signing.store_password= +signing.key_alias=revolt-release +signing.key_password=