diff --git a/.github/assets/manager-preview.png b/.github/assets/manager-preview.png deleted file mode 100644 index 3597c20..0000000 Binary files a/.github/assets/manager-preview.png and /dev/null differ diff --git a/.github/assets/manager-preview.psd b/.github/assets/manager-preview.psd deleted file mode 100644 index 23d0946..0000000 Binary files a/.github/assets/manager-preview.psd and /dev/null differ diff --git a/.github/assets/wt-manager-preview.png b/.github/assets/wt-manager-preview.png deleted file mode 100644 index f8523b3..0000000 Binary files a/.github/assets/wt-manager-preview.png and /dev/null differ diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt index d57c43b..77f6a08 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt @@ -23,55 +23,124 @@ import dev.shiggy.manager.R @Composable fun ContributorCommitsItem( - user: Contributor, - modifier: Modifier = Modifier, + user: Contributor, + modifier: Modifier = Modifier, ) { val uriHandler = LocalUriHandler.current Row( - horizontalArrangement = Arrangement.spacedBy(16.dp), - modifier = modifier - .clickable { uriHandler.openUri("https://github.com/${user.username}") } - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp), + modifier = + modifier + .clickable { uriHandler.openUri("https://github.com/${user.username}") } + .padding(horizontal = 16.dp, vertical = 8.dp) + .fillMaxWidth(), ) { SubcomposeAsyncImage( - model = user.avatarUrl, - contentDescription = user.username, - error = { - Surface( - content = {}, - tonalElevation = 2.dp, - modifier = Modifier - .fillMaxSize() - .shimmer(), - ) - }, - modifier = Modifier - .padding(top = 6.dp) - .size(45.dp) - .clip(CircleShape) + model = user.avatarUrl, + contentDescription = user.username, + error = { + Surface( + content = {}, + tonalElevation = 2.dp, + modifier = Modifier.fillMaxSize().shimmer(), + ) + }, + modifier = Modifier.padding(top = 6.dp).size(45.dp).clip(CircleShape) ) Column { - Text( - text = user.username, - style = MaterialTheme.typography.bodyLarge - ) - Text( - text = stringResource(R.string.contributors_contributions, user.commits), - style = MaterialTheme.typography.bodyMedium.copy( - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) - ) - ) + Text(text = user.username, style = MaterialTheme.typography.bodyLarge) - Text( - text = user.repositories.joinToString { it.name }, - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodySmall - .copy(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)), - modifier = Modifier.padding(top = 4.dp), - ) + // Local role overrides for selected contributors to mimic LeadContributor two-line + // style + val roleOverrides = + mapOf( + "maisymoe" to "Creator - Vendetta", + "rushiiMachine" to "Manager - Creator" + ) + val role = roleOverrides[user.username] + + if (role != null) { + val roleParts = role.split(Regex("\\s*-\\s*"), limit = 2) + // Primary role line (muted) + Text( + text = roleParts[0], + style = + MaterialTheme.typography.bodyMedium.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ) + ) + // Secondary affiliation/role line (smaller, muted) if present + if (roleParts.size == 2) { + Text( + text = roleParts[1], + style = + MaterialTheme.typography.bodySmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ), + modifier = Modifier.padding(top = 2.dp) + ) + } + + // Keep contribution count below the role lines + Text( + text = stringResource(R.string.contributors_contributions, user.commits), + style = + MaterialTheme.typography.bodySmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ), + modifier = Modifier.padding(top = 6.dp) + ) + + // Show repositories (italic) as before + Text( + text = user.repositories.joinToString { it.name }, + fontStyle = FontStyle.Italic, + style = + MaterialTheme.typography.bodySmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ), + modifier = Modifier.padding(top = 4.dp), + ) + } else { + // Fallback: original layout (contributions + repos) + Text( + text = stringResource(R.string.contributors_contributions, user.commits), + style = + MaterialTheme.typography.bodyMedium.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ) + ) + + Text( + text = user.repositories.joinToString { it.name }, + fontStyle = FontStyle.Italic, + style = + MaterialTheme.typography.bodySmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ), + modifier = Modifier.padding(top = 4.dp), + ) + } } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/CustomDiscordAppIcon.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/CustomDiscordAppIcon.kt index 29477bd..4ce5886 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/CustomDiscordAppIcon.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/CustomDiscordAppIcon.kt @@ -21,45 +21,44 @@ import androidx.core.graphics.drawable.toDrawable import com.aliucord.manager.ui.screens.patchopts.PatchOptions.IconReplacement import dev.shiggy.manager.R -// Sizing information is obtained from here: https://medium.com/google-design/designing-adaptive-icons-515af294c783 +// Sizing information is obtained from here: +// https://medium.com/google-design/designing-adaptive-icons-515af294c783 @Composable fun discordIconDrawable( - backgroundColor: Color, - oldLogo: Boolean = false, - size: Dp = 24.dp, + backgroundColor: Color, + oldLogo: Boolean = false, + size: Dp = 24.dp, ): Drawable { val density = LocalDensity.current val context = LocalContext.current - val size = with(density) { size.roundToPx() } + val sizePx = with(density) { size.roundToPx() } - val drawable = remember(context, oldLogo) { - val drawableId = when (oldLogo) { - false -> R.drawable.ic_discord - true -> R.drawable.ic_discord_old - } + val drawable = + remember(context, oldLogo) { + val drawableId = + when (oldLogo) { + false -> R.drawable.ic_discord + true -> R.drawable.ic_discord_old + } - InsetDrawable( - /* drawable = */ ContextCompat.getDrawable(context, drawableId)!!, - /* inset = */ (size * .17f).toInt(), - ).apply { - setTint(Color.White.toArgb()) - } - } + InsetDrawable( + /* drawable = */ ContextCompat.getDrawable(context, drawableId)!!, + /* inset = */ (sizePx * .17f).toInt(), + ) + .apply { setTint(Color.White.toArgb()) } + } - val bitmap = remember(size) { createBitmap(size, size) } - DisposableEffect(size) { - onDispose { - bitmap.recycle() - } - } + val bitmap = remember(sizePx) { createBitmap(sizePx, sizePx) } + DisposableEffect(sizePx) { onDispose { bitmap.recycle() } } DisposableEffect(backgroundColor, bitmap, drawable) { bitmap.applyCanvas { - val paint = Paint().apply { - style = Paint.Style.FILL - setColor(backgroundColor.toArgb()) - } + val paint = + Paint().apply { + style = Paint.Style.FILL + setColor(backgroundColor.toArgb()) + } drawRect(Rect(0, 0, width, height), paint) drawable.setBounds(0, 0, width, height) @@ -69,43 +68,36 @@ fun discordIconDrawable( onDispose {} } - return remember(context, bitmap) { - bitmap.toDrawable(context.resources) - } + return remember(context, bitmap) { bitmap.toDrawable(context.resources) } } @RequiresApi(Build.VERSION_CODES.O) @Composable fun customIconDrawable( - foregroundIcon: ByteArray, - backgroundColor: Color = IconReplacement.BlurpleColor, + foregroundIcon: ByteArray, + backgroundColor: Color = IconReplacement.BlurpleColor, ): Drawable { val context = LocalContext.current return remember(context, foregroundIcon) { - val foregroundIconBitmap = BitmapFactory.decodeByteArray(foregroundIcon, 0, foregroundIcon.size) + val foregroundIconBitmap = + BitmapFactory.decodeByteArray(foregroundIcon, 0, foregroundIcon.size) AdaptiveIconDrawable( - /* backgroundDrawable = */ backgroundColor.toArgb().toDrawable(), - /* foregroundDrawable = */ foregroundIconBitmap.toDrawable(context.resources), + /* backgroundDrawable = */ backgroundColor.toArgb().toDrawable(), + /* foregroundDrawable = */ foregroundIconBitmap.toDrawable(context.resources), ) } } @Composable fun Drawable( - drawable: Drawable, - modifier: Modifier = Modifier, + drawable: Drawable, + modifier: Modifier = Modifier, ) { AndroidView( - factory = { context -> - ImageView(context).apply { - setImageDrawable(drawable) - } - }, - update = { imageView -> - imageView.setImageDrawable(drawable) - }, - modifier = modifier, + factory = { context -> ImageView(context).apply { setImageDrawable(drawable) } }, + update = { imageView -> imageView.setImageDrawable(drawable) }, + modifier = modifier, ) } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/ProjectHeader.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/ProjectHeader.kt index f839e6c..aa7bd39 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/ProjectHeader.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/ProjectHeader.kt @@ -12,61 +12,67 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.shiggy.manager.BuildConfig import dev.shiggy.manager.R @Composable fun ProjectHeader( - aliucord: Boolean = false, - modifier: Modifier = Modifier, + aliucord: Boolean = false, + modifier: Modifier = Modifier, ) { val uriHandler = LocalUriHandler.current Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(6.dp), - modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(6.dp), + modifier = modifier, ) { Image( - painter = painterResource(if (aliucord) R.drawable.ic_aliucord_logo else R.drawable.ic_rounded_shiggy), - contentDescription = null, - modifier = Modifier - .padding(bottom = 6.dp) - .size(88.dp), + painter = + painterResource( + if (aliucord) R.drawable.ic_aliucord_logo + else R.drawable.ic_rounded_shiggy + ), + contentDescription = null, + modifier = Modifier.padding(bottom = 6.dp).size(88.dp), ) Text( - text = stringResource(if (aliucord) R.string.aliucord else R.string.shiggy), - style = MaterialTheme.typography.titleMedium.copy(fontSize = 26.sp) + text = stringResource(if (aliucord) R.string.aliucord else R.string.shiggy), + style = MaterialTheme.typography.titleMedium.copy(fontSize = 26.sp) ) Text( - text = stringResource(if (aliucord) R.string.aliucord_description else R.string.app_description), - style = MaterialTheme.typography.titleSmall.copy( - color = MaterialTheme.colorScheme.onSurface.copy(alpha = .6f) - ), - textAlign = TextAlign.Center, + text = + stringResource( + if (aliucord) R.string.aliucord_description + else R.string.app_description + ), + style = + MaterialTheme.typography.titleSmall.copy( + color = MaterialTheme.colorScheme.onSurface.copy(alpha = .6f) + ), + textAlign = TextAlign.Center, ) Row( - horizontalArrangement = Arrangement.Center, + horizontalArrangement = Arrangement.Center, ) { - TextButton(onClick = { uriHandler.openUri("https://github.com/${if (aliucord) "Aliucord" else BuildConfig.GITHUB_ORG}") }) { + TextButton( + onClick = { uriHandler.openUri("https://github.com/kmmiio99o/ShiggyCord") } + ) { Icon( - painter = painterResource(R.drawable.ic_account_github_white_24dp), - contentDescription = null, - modifier = Modifier.padding(end = ButtonDefaults.IconSpacing), + painter = painterResource(R.drawable.ic_account_github_white_24dp), + contentDescription = null, + modifier = Modifier.padding(end = ButtonDefaults.IconSpacing), ) Text(text = stringResource(R.string.github)) } - TextButton(onClick = { uriHandler.openUri("https://discord.gg/${if (aliucord) "EsNDvBaHVU" else BuildConfig.SUPPORT_SERVER}") }) { + TextButton(onClick = { uriHandler.openUri("https://discord.gg/nQykFF9Ud6") }) { Icon( - painter = painterResource(R.drawable.ic_discord), - contentDescription = stringResource(R.string.support_server), - modifier = Modifier - .padding(end = ButtonDefaults.IconSpacing) - .size(22.dp), + painter = painterResource(R.drawable.ic_discord), + contentDescription = stringResource(R.string.support_server), + modifier = Modifier.padding(end = ButtonDefaults.IconSpacing).size(22.dp), ) Text(text = stringResource(R.string.discord)) } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt index 8330614..5cf84e8 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -89,7 +88,7 @@ fun AboutScreenContent(state: State) { } } - item(key = "PROJECT_HEADER") { ProjectHeader(aliucord = true) } + item(key = "PROJECT_HEADER") { ProjectHeader() } item(key = "HEADER_DIVIDER") { TextDivider( @@ -104,9 +103,9 @@ fun AboutScreenContent(state: State) { verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth(), ) { - LeadContributor("C0C0B01", "Creator of Kettu") - LeadContributor("kmmiio99o", "Creator of ShiggyCord") - LeadContributor("pylixonly", "Creator of Bunny") + LeadContributor("C0C0B01", stringResource(R.string.lead_role_kettu)) + LeadContributor("kmmiio99o", stringResource(R.string.lead_role_shiggycord)) + LeadContributor("pylixonly", stringResource(R.string.lead_role_bunny)) } } @@ -131,8 +130,16 @@ fun AboutScreenContent(state: State) { LoadFailure(modifier = Modifier.fillMaxSize().padding(vertical = 38.dp)) } is AboutScreenState.Loaded -> { - items(state.contributors, key = { it.username }) { user -> - ContributorCommitsItem(user) + // Render the two requested contributors as LeadContributor entries + item(key = "SELECTED_CONTRIBUTORS") { + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + LeadContributor("maisymoe", "Creator - Vendetta") + LeadContributor("rushiiMachine", "Manager - Creator") + } } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/components/LeadContributor.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/components/LeadContributor.kt index 1bf9807..4bc7ce9 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/components/LeadContributor.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/components/LeadContributor.kt @@ -18,57 +18,77 @@ import com.valentinilk.shimmer.shimmer @Composable fun LeadContributor( - name: String, - roles: String, - username: String = name, - modifier: Modifier = Modifier, + name: String, + roles: String, + username: String = name, + modifier: Modifier = Modifier, ) { val uriHandler = LocalUriHandler.current Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(16.dp), - modifier = modifier - .clickable( - onClick = { uriHandler.openUri("https://github.com/$username") }, - indication = ripple(bounded = false, radius = 90.dp), - interactionSource = remember(::MutableInteractionSource) - ) - .widthIn(min = 100.dp) + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = + modifier.clickable( + onClick = { + uriHandler.openUri("https://github.com/$username") + }, + indication = ripple(bounded = false, radius = 90.dp), + interactionSource = remember(::MutableInteractionSource) + ) + .widthIn(min = 100.dp) ) { SubcomposeAsyncImage( - model = "https://github.com/$username.png", - contentDescription = username, - error = { - Surface( - content = {}, - tonalElevation = 2.dp, - modifier = Modifier - .fillMaxSize() - .shimmer(), - ) - }, - modifier = Modifier - .size(80.dp) - .clip(CircleShape), + model = "https://github.com/$username.png", + contentDescription = username, + error = { + Surface( + content = {}, + tonalElevation = 2.dp, + modifier = Modifier.fillMaxSize().shimmer(), + ) + }, + modifier = Modifier.size(80.dp).clip(CircleShape), ) - Column( - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = name, - style = MaterialTheme.typography.titleMedium.copy( - fontSize = 18.sp - ) - ) + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text(text = name, style = MaterialTheme.typography.titleMedium.copy(fontSize = 18.sp)) - Text( - text = roles, - style = MaterialTheme.typography.titleSmall.copy( - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) + val roleParts = roles.split(Regex("\\s*-\\s*"), limit = 2) + if (roleParts.size == 2) { + // Render left and right parts on two separate lines, removing the dash + Text( + text = roleParts[0], + style = + MaterialTheme.typography.titleSmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ) ) - ) + Text( + text = roleParts[1], + style = + MaterialTheme.typography.bodySmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ) + ) + } else { + Text( + text = roles, + style = + MaterialTheme.typography.titleSmall.copy( + color = + MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.6f + ) + ) + ) + } } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/patching/PatchingScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/patching/PatchingScreen.kt index 92e0d23..d93cd8a 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/patching/PatchingScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/patching/PatchingScreen.kt @@ -40,7 +40,6 @@ import com.aliucord.manager.ui.util.spacedByLastAtBottom import com.aliucord.manager.ui.util.thenIf import com.aliucord.manager.util.back import com.aliucord.manager.util.isIgnoringBatteryOptimizations -import dev.shiggy.manager.BuildConfig import dev.shiggy.manager.R import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.filter @@ -52,8 +51,7 @@ val VERTICAL_PADDING: Dp = 18.dp @Parcelize class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { - @IgnoredOnParcel - override val key = "Patching" + @IgnoredOnParcel override val key = "Patching" @Composable override fun Content() { @@ -66,7 +64,8 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { val showMinimizationWarning = rememberSaveable { !context.isIgnoringBatteryOptimizations() } // Exit warning dialog (dismiss itself if install process state changes, esp. for Success) - var showAbortWarning by rememberSaveable(model.state.collectAsState().value) { mutableStateOf(false) } + var showAbortWarning by + rememberSaveable(model.state.collectAsState().value) { mutableStateOf(false) } // The currently expanded step group on this screen var expandedGroup by rememberSaveable { mutableStateOf(StepGroup.Prepare) } @@ -94,14 +93,14 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { LaunchedEffect(state) { when (state) { - // Go home directly if screen model mandates so (usually caused by cancelled PackageInstaller dialog) + // Go home directly if screen model mandates so (usually caused by cancelled + // PackageInstaller dialog) PatchingScreenState.CloseScreen -> navigator.popUntilRoot() // Close all groups when successfully finished everything PatchingScreenState.Success -> { expandedGroup = null } - else -> {} } @@ -110,58 +109,55 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { if (showAbortWarning) { InstallerAbortDialog( - onDismiss = { showAbortWarning = false }, - onConfirm = { - navigator.back(currentActivity = null) - model.cancelInstall() - }, + onDismiss = { showAbortWarning = false }, + onConfirm = { + navigator.back(currentActivity = null) + model.cancelInstall() + }, ) } else { BackHandler(onBack = onTryExit) } Scaffold( - topBar = { PatchingAppBar(onTryExit) }, + topBar = { PatchingAppBar(onTryExit) }, ) { paddingValues -> Column( - verticalArrangement = Arrangement.spacedBy(VERTICAL_PADDING), - modifier = Modifier - .padding(paddingValues.exclude(PaddingValuesSides.Bottom)), + verticalArrangement = Arrangement.spacedBy(VERTICAL_PADDING), + modifier = Modifier.padding(paddingValues.exclude(PaddingValuesSides.Bottom)), ) { if (state == PatchingScreenState.Working) { - LinearProgressIndicator( - modifier = Modifier - .height(4.dp) - .fillMaxWidth() - ) + LinearProgressIndicator(modifier = Modifier.height(4.dp).fillMaxWidth()) } else { HorizontalDivider( - thickness = 2.dp, - modifier = Modifier.fillMaxWidth(), + thickness = 2.dp, + modifier = Modifier.fillMaxWidth(), ) } LazyColumn( - state = listState, - verticalArrangement = Arrangement.spacedByLastAtBottom(0.dp), - contentPadding = paddingValues - .exclude(PaddingValuesSides.Horizontal + PaddingValuesSides.Top) - .add(PaddingValues(bottom = 25.dp)), - modifier = Modifier - .padding(horizontal = 16.dp) - .fillMaxSize(), + state = listState, + verticalArrangement = Arrangement.spacedByLastAtBottom(0.dp), + contentPadding = + paddingValues + .exclude( + PaddingValuesSides.Horizontal + + PaddingValuesSides.Top + ) + .add(PaddingValues(bottom = 25.dp)), + modifier = Modifier.padding(horizontal = 16.dp).fillMaxSize(), ) { item(key = "MINIMIZATION_WARNING") { BannerSection(visible = showMinimizationWarning && !state.isFinished) { TextBanner( - text = stringResource(R.string.installer_banner_minimization), - icon = painterResource(R.drawable.ic_warning), - iconColor = MaterialTheme.customColors.onWarningContainer, - outlineColor = MaterialTheme.customColors.warning, - containerColor = MaterialTheme.customColors.warningContainer, - modifier = Modifier - .padding(bottom = VERTICAL_PADDING) - .fillMaxWidth(), + text = stringResource(R.string.installer_banner_minimization), + icon = painterResource(R.drawable.ic_warning), + iconColor = MaterialTheme.customColors.onWarningContainer, + outlineColor = MaterialTheme.customColors.warning, + containerColor = MaterialTheme.customColors.warningContainer, + modifier = + Modifier.padding(bottom = VERTICAL_PADDING) + .fillMaxWidth(), ) } } @@ -171,15 +167,15 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { val handler = LocalUriHandler.current TextBanner( - text = stringResource(R.string.installer_banner_failure), - icon = painterResource(R.drawable.ic_warning), - iconColor = MaterialTheme.colorScheme.error, - outlineColor = null, - containerColor = MaterialTheme.colorScheme.errorContainer, - onClick = { handler.openUri("https://discord.gg/${BuildConfig.SUPPORT_SERVER}") }, - modifier = Modifier - .padding(bottom = VERTICAL_PADDING) - .fillMaxWidth(), + text = stringResource(R.string.installer_banner_failure), + icon = painterResource(R.drawable.ic_warning), + iconColor = MaterialTheme.colorScheme.error, + outlineColor = null, + containerColor = MaterialTheme.colorScheme.errorContainer, + onClick = { handler.openUri("https://discord.gg/nQykFF9Ud6") }, + modifier = + Modifier.padding(bottom = VERTICAL_PADDING) + .fillMaxWidth(), ) } } @@ -187,14 +183,14 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { item(key = "INSTALLED_BANNER") { BannerSection(visible = state is PatchingScreenState.Success) { TextBanner( - text = stringResource(R.string.installer_banner_success), - icon = painterResource(R.drawable.ic_check_circle), - iconColor = Color(0xFF59B463), - outlineColor = MaterialTheme.colorScheme.surfaceVariant, - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .padding(bottom = VERTICAL_PADDING) - .fillMaxWidth(), + text = stringResource(R.string.installer_banner_success), + icon = painterResource(R.drawable.ic_check_circle), + iconColor = Color(0xFF59B463), + outlineColor = MaterialTheme.colorScheme.surfaceVariant, + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, + modifier = + Modifier.padding(bottom = VERTICAL_PADDING) + .fillMaxWidth(), ) } } @@ -202,75 +198,91 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { for ((group, steps) in model.steps?.entries ?: persistentListOf()) { item(key = System.identityHashCode(group)) { StepGroupCard( - name = stringResource(group.localizedName), - subSteps = steps, - isExpanded = expandedGroup == group, - onExpand = { expandedGroup = group }, - modifier = Modifier - .padding(bottom = VERTICAL_PADDING) - .fillMaxWidth() - .thenIf(state is PatchingScreenState.Success) { alpha(.5f) } + name = stringResource(group.localizedName), + subSteps = steps, + isExpanded = expandedGroup == group, + onExpand = { expandedGroup = group }, + modifier = + Modifier.padding(bottom = VERTICAL_PADDING) + .fillMaxWidth() + .thenIf(state is PatchingScreenState.Success) { + alpha(.5f) + } ) } } item(key = "BUTTONS") { var cacheCleared by rememberSaveable { mutableStateOf(false) } - val filteredState by remember { model.state.filter { it.isProgressChange } } - .collectAsState(initial = PatchingScreenState.Working) + val filteredState by + remember { model.state.filter { it.isProgressChange } } + .collectAsState(initial = PatchingScreenState.Working) AnimatedVisibility( - visible = filteredState != PatchingScreenState.Working, - enter = fadeIn() + slideInVertically(), - exit = fadeOut() + slideOutVertically { it * -2 }, + visible = filteredState != PatchingScreenState.Working, + enter = fadeIn() + slideInVertically(), + exit = fadeOut() + slideOutVertically { it * -2 }, ) { Column( - verticalArrangement = Arrangement.spacedBy(VERTICAL_PADDING / 2), + verticalArrangement = + Arrangement.spacedBy(VERTICAL_PADDING / 2), ) { HorizontalDivider( - thickness = 1.dp, - modifier = Modifier - .padding(bottom = VERTICAL_PADDING / 2) + thickness = 1.dp, + modifier = Modifier.padding(bottom = VERTICAL_PADDING / 2) ) when (filteredState) { PatchingScreenState.Working -> {} PatchingScreenState.CloseScreen -> error("unreachable") - PatchingScreenState.Success -> { MainActionButton( - text = stringResource(R.string.action_launch), - icon = painterResource(R.drawable.ic_launch), - onClick = model::launchApp, + text = stringResource(R.string.action_launch), + icon = painterResource(R.drawable.ic_launch), + onClick = model::launchApp, ) } - is PatchingScreenState.Failed -> { MainActionButton( - text = stringResource(R.string.action_retry_install), - icon = painterResource(R.drawable.ic_refresh), - onClick = model::install, + text = + stringResource( + R.string.action_retry_install + ), + icon = painterResource(R.drawable.ic_refresh), + onClick = model::install, ) MainActionButton( - text = stringResource(R.string.action_open_error_log), - icon = painterResource(R.drawable.ic_launch), - onClick = { navigator.push(LogScreen(installId = model.getCurrentInstallId()!!)) }, + text = + stringResource( + R.string.action_open_error_log + ), + icon = painterResource(R.drawable.ic_launch), + onClick = { + navigator.push( + LogScreen( + installId = + model.getCurrentInstallId()!! + ) + ) + }, ) } } MainActionButton( - text = stringResource(R.string.settings_clear_cache), - icon = painterResource(R.drawable.ic_delete_forever), - enabled = !cacheCleared, - colors = IconButtonDefaults.filledTonalIconButtonColors( - containerColor = MaterialTheme.colorScheme.error, - ), - onClick = { - cacheCleared = true - model.clearCache() - }, + text = stringResource(R.string.settings_clear_cache), + icon = painterResource(R.drawable.ic_delete_forever), + enabled = !cacheCleared, + colors = + IconButtonDefaults.filledTonalIconButtonColors( + containerColor = + MaterialTheme.colorScheme.error, + ), + onClick = { + cacheCleared = true + model.clearCache() + }, ) } } @@ -278,8 +290,8 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { item(key = "FUN_FACT") { FunFact( - text = stringResource(model.funFact), - state = state, + text = stringResource(model.funFact), + state = state, ) } } @@ -290,23 +302,22 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable { @Composable private fun BannerSection( - visible: Boolean, - modifier: Modifier = Modifier, - content: @Composable () -> Unit, + visible: Boolean, + modifier: Modifier = Modifier, + content: @Composable () -> Unit, ) { AnimatedVisibility( - visible = visible, - enter = fadeIn() + slideInVertically(), - exit = fadeOut() + slideOutVertically(), - modifier = modifier - .padding(bottom = VERTICAL_PADDING), + visible = visible, + enter = fadeIn() + slideInVertically(), + exit = fadeOut() + slideOutVertically(), + modifier = modifier.padding(bottom = VERTICAL_PADDING), ) { Column { content() HorizontalDivider( - thickness = 1.dp, - modifier = Modifier.padding(vertical = 4.dp), + thickness = 1.dp, + modifier = Modifier.padding(vertical = 4.dp), ) } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/patchopts/PatchOptions.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/patchopts/PatchOptions.kt index 1fd456b..c531922 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/patchopts/PatchOptions.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/patchopts/PatchOptions.kt @@ -14,50 +14,38 @@ enum class VersionPreference { Stable, Beta, Alpha, - Custom; + Custom } @Immutable @Parcelize @Serializable data class PatchOptions( - /** - * The app name that's user-facing in launchers. - */ - val appName: String, + /** The app name that's user-facing in launchers. */ + val appName: String, - /** - * Changes the installation package name. - */ - val packageName: String, + /** Changes the installation package name. */ + val packageName: String, - /** - * Adding the debuggable APK flag. - */ - val debuggable: Boolean, + /** Adding the debuggable APK flag. */ + val debuggable: Boolean, - /** - * Replacement of the user-facing launcher icon. - */ - val iconReplacement: IconReplacement, + /** Replacement of the user-facing launcher icon. */ + val iconReplacement: IconReplacement, - /** - * Version preference to fetch and install - */ - val versionPreference: VersionPreference, + /** Version preference to fetch and install */ + val versionPreference: VersionPreference, - /** - * Version to fetch and install when versionPreference is set to VersionPreference.Custom. - */ - val customVersionCode: String, + /** + * Version to fetch and install when versionPreference is set to VersionPreference.Custom. + */ + val customVersionCode: String, ) : Parcelable { @Immutable @Parcelize @Serializable sealed interface IconReplacement : Parcelable { - /** - * Keeps the original icons that are present in the APK. - */ + /** Keeps the original icons that are present in the APK. */ @Immutable @Parcelize @Serializable @@ -65,8 +53,8 @@ data class PatchOptions( data object Original : IconReplacement /** - * Changes the foreground logo to Discord's old logo and the - * background color to old blurple, like prior to early 2021. + * Changes the foreground logo to Discord's old logo and the background color to old + * blurple, like prior to early 2021. */ @Immutable @Parcelize @@ -75,22 +63,22 @@ data class PatchOptions( data object OldDiscord : IconReplacement /** - * Changes the background of the icon to a specific color without - * altering the foreground or monochrome variants. + * Changes the background of the icon to a specific color without altering the foreground or + * monochrome variants. */ @Immutable @Parcelize @Serializable @SerialName("color") data class CustomColor( - @TypeParceler - @Serializable(ColorSerializer::class) - val color: Color, + @TypeParceler + @Serializable(ColorSerializer::class) + val color: Color, ) : IconReplacement /** - * Replaces the foreground image of the icon entirely and sets the background to transparent. - * This does not affect the monochrome icon. + * Replaces the foreground image of the icon entirely and sets the background to + * transparent. This does not affect the monochrome icon. */ @Immutable @Parcelize @@ -98,41 +86,39 @@ data class PatchOptions( @SerialName("image") data class CustomImage(val imageBytes: ByteArray) : IconReplacement { override fun hashCode() = imageBytes.contentHashCode() - override fun equals(other: Any?) = this === other - || (javaClass == other?.javaClass && imageBytes.contentEquals((other as CustomImage).imageBytes)) + override fun equals(other: Any?) = + this === other || + (javaClass == other?.javaClass && + imageBytes.contentEquals((other as CustomImage).imageBytes)) } companion object { - /** - * The default Aliucord background color. - */ + /** The default Aliucord background color. */ val AliucordColor = Color(0xFF00C853) /** - * The default Shiggy background color. + * The default Shiggy background color. Updated to the requested hex #ffcb82 (ARGB + * 0xFFFFCB82). */ - val ShiggyColor = Color(0xFF133E87) + val ShiggyColor = Color(0xFFFFCB82) - /** - * The new Discord blurple used in icons. - */ + /** The new Discord blurple used in icons. */ val BlurpleColor = Color(0xFF5865F2) - /** - * The old Discord icon color (before the accessibility redesign). - */ + /** The old Discord icon color (before the accessibility redesign). */ val OldBlurpleColor = Color(0xFF7289DA) } } companion object { - val Default = PatchOptions( - appName = "Shiggy", - packageName = "dev.shiggy.app", - debuggable = false, - iconReplacement = IconReplacement.CustomColor(IconReplacement.ShiggyColor), - versionPreference = VersionPreference.Stable, - customVersionCode = "", - ) + val Default = + PatchOptions( + appName = "ShiggyCord", + packageName = "dev.shiggy.cord", + debuggable = false, + iconReplacement = IconReplacement.CustomColor(IconReplacement.ShiggyColor), + versionPreference = VersionPreference.Stable, + customVersionCode = "", + ) } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/util/InstallNotifications.kt b/app/src/main/kotlin/com/aliucord/manager/ui/util/InstallNotifications.kt index e3d478f..c15cc15 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/util/InstallNotifications.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/util/InstallNotifications.kt @@ -19,48 +19,52 @@ object InstallNotifications { private const val CHANNEL_ID = "installation" /** - * Creates or replaces a notification with id [id] that brings - * up the existing [MainActivity] when clicked upon. + * Creates or replaces a notification with id [id] that brings up the existing [MainActivity] + * when clicked upon. * * @param id A unique notification ID for different notifications * @param title Main notification title * @param description Notification description */ fun createNotification( - context: Context, - id: Int, - @StringRes title: Int, - @StringRes description: Int, + context: Context, + id: Int, + @StringRes title: Int, + @StringRes description: Int, ) { val manager = NotificationManagerCompat.from(context) // Create the target notification channel if (Build.VERSION.SDK_INT >= 26 && manager.getNotificationChannel(CHANNEL_ID) == null) { - val channel = NotificationChannelCompat.Builder(CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH) - .setName(context.getString(R.string.notif_group_install_title)) - .setDescription(context.getString(R.string.notif_group_install_desc)) - .build() + val channel = + NotificationChannelCompat.Builder( + CHANNEL_ID, + NotificationManager.IMPORTANCE_HIGH + ) + .setName(context.getString(R.string.notif_group_install_title)) + .setDescription(context.getString(R.string.notif_group_install_desc)) + .build() manager.createNotificationChannel(channel) } - val notification = NotificationCompat.Builder(context, CHANNEL_ID) - .setDefaults(Notification.DEFAULT_LIGHTS or Notification.DEFAULT_SOUND) - .setAutoCancel(true) - .setSmallIcon(R.drawable.ic_aliucord_logo) - .setContentTitle(context.getString(title)) - .setContentText(context.getString(description)) - .setContentIntent( - PendingIntent.getActivity( - /* context = */ context, - /* requestCode = */ 0, - /* intent = */ - Intent(context, MainActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT), - /* flags = */ PendingIntent.FLAG_IMMUTABLE, - ) - ) - .build() + val notification = + NotificationCompat.Builder(context, CHANNEL_ID) + .setDefaults(Notification.DEFAULT_LIGHTS or Notification.DEFAULT_SOUND) + .setAutoCancel(true) + .setSmallIcon(R.drawable.ic_rounded_shiggy) + .setContentTitle(context.getString(title)) + .setContentText(context.getString(description)) + .setContentIntent( + PendingIntent.getActivity( + /* context = */ context, + /* requestCode = */ 0, + /* intent = */ Intent(context, MainActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT), + /* flags = */ PendingIntent.FLAG_IMMUTABLE, + ) + ) + .build() try { manager.notify(id, notification) @@ -69,20 +73,19 @@ object InstallNotifications { } } - /** - * Request the `POST_NOTIFICATIONS` permission if needed. - */ + /** Request the `POST_NOTIFICATIONS` permission if needed. */ fun requestPermissions(context: Context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return - val granted = ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) + val granted = + ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) val activity = context.findActivity() ?: return if (granted != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( - activity, - arrayOf(Manifest.permission.POST_NOTIFICATIONS), - 0, + activity, + arrayOf(Manifest.permission.POST_NOTIFICATIONS), + 0, ) } } diff --git a/app/src/main/res/drawable/ic_aliucord_logo.xml b/app/src/main/res/drawable/ic_aliucord_logo.xml index ce5b8ad..9d62342 100644 --- a/app/src/main/res/drawable/ic_aliucord_logo.xml +++ b/app/src/main/res/drawable/ic_aliucord_logo.xml @@ -1,16 +1,5 @@ - - - - - + + + + diff --git a/app/src/main/res/drawable/ic_discord_shiggy.xml b/app/src/main/res/drawable/ic_discord_shiggy.xml new file mode 100644 index 0000000..4c75f41 --- /dev/null +++ b/app/src/main/res/drawable/ic_discord_shiggy.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000..9e729f3 Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 4be5b6f..5c910e4 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,27 +1,10 @@ - - - - - - - - - - + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index daed3b5..b91bbc1 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,10 +1 @@ - - - + diff --git a/app/src/main/res/drawable/ic_rounded_shiggy.xml b/app/src/main/res/drawable/ic_rounded_shiggy.xml new file mode 100644 index 0000000..aeb2c89 --- /dev/null +++ b/app/src/main/res/drawable/ic_rounded_shiggy.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_rounded_wintry.xml b/app/src/main/res/drawable/ic_rounded_wintry.xml deleted file mode 100644 index 8186459..0000000 --- a/app/src/main/res/drawable/ic_rounded_wintry.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6645ffb..93ae6be 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,4 +1,5 @@ - + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index fbf44be..21739ab 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,4 +1,4 @@ - + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index 426f6f0..9e729f3 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 512cb0a..9e729f3 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 f5f0dcf..9e729f3 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 9c578ca..9e729f3 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 a5b7f6a..9e729f3 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 b6c752c..9e729f3 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 d6f0c21..9e729f3 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 41d74fe..9e729f3 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 c5c22b1..9e729f3 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 7fae848..9e729f3 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 893de54..d893495 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,13 +2,13 @@ Shiggy Manager A Discord mod built with simplicity and a seamless experience in mind. - Aliucord + ShiggyCord Discord GitHub Support Server Installer - Shiggy + Shiggy Manager A mod for the Discord Android App Cancel @@ -65,7 +65,7 @@ This manager is a fork of the original Aliucord Manager project, adapted for use with Shiggy. All credit goes to the Aliucord team for their foundational work. + >This manager is a fork of the original Aliucord Manager project, Which was a forked by wintry, and now rebranded as Shiggy Manager. Credit to the original project\'s maintainers for the foundational work; continued development and branding are by the Shiggy team. System Dark @@ -85,8 +85,13 @@ Open logs Settings - Lead - Contributors + Lead Developers + Kettu - Creator + ShiggyCord - Creator + Bunny - Creator + Creator of Vendetta + Original Manager Creator + Other Developers %s contributions Failed to load @@ -105,7 +110,6 @@ Failed to retrieve version Invalid version code format - Saved to %s Failed to save %s Successfully installed Shiggy @@ -142,14 +146,14 @@ Restoring from cache Downloading Discord APK Downloading Kotlin library - Downloading Aliucord Injector - Downloading Aliuhook library + Downloading ShiggyCord Injector + Downloading ShiggyHook library Downloading smali patches Copying dependencies Patching APK manifest Patching app icon - Adding Aliucord injector - Adding Aliuhook library + Adding ShiggyCord injector + Adding ShiggyHook library Applying smali patches Adding .dex files to APK Store metadata @@ -211,7 +215,7 @@ Advanced The selected icon options are invalid! Version channel - Select the release channel to install from, or choose \'Custom\' to enter a specific version code. + Select the release channel to install from, or choose Custom to enter a specific version code. Custom Version Code Manually enter a Discord version code to fetch and install. @@ -221,8 +225,8 @@ Custom Color Custom Image Does not alter the original icon, instead only adding the missing monochrome icon to the APK. - Changes the original icon color to Aliucord\'s branding. - Changes the original icon color to Shiggy\'s branding. + Changes the original icon color to Shiggy\'s branding. + Changes the original icon color to Shiggy\'s branding. Select a custom icon background color. Image size exceeds maximum of 256KiB Select Image Example image + No image selected + A full, uncropped preview of the selected image. + Preview Icon Preview A preview of the selected options, cropped and scaled to show how the icon will appear on your device - Preview - A full, uncropped preview of the selected image. - No image selected Log Installation Info @@ -264,14 +268,14 @@ Active installation Progress notifications sent during a minimized installation Shiggy installation ready! - Click to install… + Click to install... Shiggy failed to install - Click to view more info… + Click to view more info... Play Protect Google Play Protect appears to be enabled on your device. It may attempt to interfere with a new installation due to the usage of a unique signing key. You can disable it in Play Protect\'s settings.\n\nIf it does show a warning dialog, press\n\"More Details\" -> \"Install anyway\" + >Google Play Protect appears to be enabled on your device. It may attempt to interfere with a new installation due to the usage of a unique signing key. You can disable it in Play Protect\'s settings. If it does show a warning dialog, press "More Details" -> "Install anyway" Continue Open Play Protect Don\'t show this again @@ -280,17 +284,17 @@ A custom local version for a patching component (%s) has been found. Would you like to use it? Fun Fact: %s - Did you know that Google Play Protect is useless? - Did you know Aliucord with 150+ plugins somehow runs better than Discord\'s new app? - Did you know Aliucord has over 200 available plugins? - i am in your walls - Did you know AliucordRN spawned Enmity and Vendetta? - Having issues? Visit the #support channel in our Discord! - The IWillCrashYourDiscord plugin crashes your discord. - \"@Vendicated my bad.\" - Aliucord can run on WearOS - Aliucord uses the *real* old UI, from mid-2022! - There was an attempt to make Aliucord run on iOS… - veeeee 😭 + ShiggyCord on first release was meant to be custom Kettu build! + The refreshed UI inside the settings was made from developer boredom + ShiggyCord as first vendetta like client used to show users the built in plugins and even add extra ones! + You love boys, don\'t you? + Aliucord is the best client with old discord UI + We love you cocobo and pylix! + The Vendetta react native part was a total dogshit + Vencord and Equicord are not the same. + This client can be run on a android TV! + The Main Developer one and half a year ago didn\'t even know how to code + This client does not support iOS! + Boom!