feat: rewrite about activity and add contributors table

This commit is contained in:
Akash Yadav
2023-12-27 08:31:20 +05:30
parent e6854001ae
commit 1e14419a58
61 changed files with 2100 additions and 575 deletions
+10
View File
@@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="true" level="INFORMATION" enabled_by_default="true">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>
+2
View File
@@ -69,6 +69,8 @@ dependencies {
implementation(libs.common.glide)
implementation(libs.common.jsoup)
implementation(libs.common.kotlin.coroutines.android)
implementation(libs.common.retrofit)
implementation(libs.common.retrofit.gson)
implementation(libs.google.auto.service.annotations)
implementation(libs.google.gson)
+2 -2
View File
@@ -73,10 +73,10 @@
android:windowSoftInputMode="adjustResize" />
<activity android:name=".activities.PreferencesActivity" />
<activity
android:configChanges="orientation|screenSize"
android:name=".activities.AboutActivity" />
<activity
android:configChanges="orientation|screenSize"
android:name=".activities.ContributorsActivity" />
<activity
android:name=".activities.TerminalActivity"
android:windowSoftInputMode="adjustResize" />
@@ -1,126 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.util.Pair;
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity;
import com.itsaky.androidide.R;
import com.itsaky.androidide.app.IDEActivity;
import com.itsaky.androidide.app.configuration.IDEBuildConfigProvider;
import com.itsaky.androidide.databinding.ActivityAboutBinding;
import com.itsaky.androidide.databinding.LayoutAboutItemsBinding;
import java.util.ArrayList;
import java.util.List;
public class AboutActivity extends IDEActivity {
private ActivityAboutBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding.items.footerText.setText(getFooter());
setupTranslations();
OssLicensesMenuActivity.setActivityTitle(getString(R.string.oss_license_title));
LayoutAboutItemsBinding items = binding.items;
TooltipCompat.setTooltipText(items.discuss, getString(R.string.discussions_on_telegram));
TooltipCompat.setTooltipText(items.github, getString(R.string.title_github));
TooltipCompat.setTooltipText(items.email, getString(R.string.about_option_email));
TooltipCompat.setTooltipText(items.website, getString(R.string.about_option_website));
TooltipCompat.setTooltipText(items.licenses, getString(R.string.oss_license_title));
items.github.setOnClickListener(v -> getApp().openGitHub());
items.discuss.setOnClickListener(v -> getApp().openTelegramGroup());
items.email.setOnClickListener(v -> getApp().emailUs());
items.website.setOnClickListener(v -> getApp().openWebsite());
items.licenses.setOnClickListener(
v -> startActivity(new Intent(this, OssLicensesMenuActivity.class)));
}
@Override
protected View bindLayout() {
binding = ActivityAboutBinding.inflate(getLayoutInflater());
return binding.getRoot();
}
private void setupTranslations() {
final var translations = createTranslationsList();
final var sb = new StringBuilder();
for (var translation : translations) {
final var author = translation.first;
final var language = translation.second;
sb.append(author);
sb.append(" - ");
sb.append(language);
sb.append("\n");
}
binding.items.translations.setText(sb);
}
/**
* Create the list of translations. The list items are pairs. The first item of the pair is the
* name of the language. The second item is the name of the person who made the translations.
*
* <p>If you're adding translations, make sure you add an item to this list. You can choose to
* display the language in a localized version. For example : Language: हिन्दी - < name of author
* >
*
* <p>Prefer using unicode escapes for language names. For example, हिन्दी can be written as :
* Language: \u0939\u093f\u0928\u094d\u0926\u0940 - < name of author >
*
* @return The translations list.
*/
private List<Pair<String, String>> createTranslationsList() {
final var list = new ArrayList<Pair<String, String>>();
list.add(Pair.create("Bahasa Indonesia", "Fitrah Nuno Syahbani"));
list.add(Pair.create("\u4e2d\u6587", "Rosemoe and @mikofe")); // 中文
list.add(Pair.create("Deutsch", "Marvin Stelter"));
list.add(Pair.create("\u0939\u093f\u0928\u094d\u0926\u0940", "Premjit Chowdhury")); // हिन्दी
list.add(Pair.create("Russian", "Smooth-E"));
list.add(Pair.create("French", "Se-Lyan"));
list.add(Pair.create("Portuguese-Brazilian", "Frederick'XS"));
return list;
}
private String getFooter() {
final String arch = IDEBuildConfigProvider.getInstance().getBuildFlavor();
try {
final String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
return getString(R.string.about_footer, version, arch);
} catch (Throwable th) {
return getString(R.string.about_footer_alternate, arch);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
binding = null;
}
}
@@ -0,0 +1,304 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.activities
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.View
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.core.view.updatePaddingRelative
import com.blankj.utilcode.util.ClipboardUtils
import com.blankj.utilcode.util.SizeUtils
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import com.itsaky.androidide.BuildConfig
import com.itsaky.androidide.R
import com.itsaky.androidide.adapters.SimpleIconTitleDescriptionAdapter
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.app.LimitlessIDEActivity
import com.itsaky.androidide.buildinfo.BuildInfo
import com.itsaky.androidide.databinding.ActivityAboutBinding
import com.itsaky.androidide.models.IconTitleDescriptionItem
import com.itsaky.androidide.models.SimpleIconTitleDescriptionItem
import com.itsaky.androidide.utils.BuildInfoUtils
import com.itsaky.androidide.utils.flashSuccess
import com.itsaky.androidide.utils.resolveAttr
class AboutActivity : LimitlessIDEActivity() {
private var _binding: ActivityAboutBinding? = null
private val binding: ActivityAboutBinding
get() = checkNotNull(_binding) {
"Activity has been destroyed"
}
override fun bindLayout(): View {
_binding = ActivityAboutBinding.inflate(layoutInflater)
return _binding!!.root
}
companion object {
private var id = 0
private val ACTION_WEBSITE = id++
private val ACTION_EMAIL = id++
private val ACTION_TG_CHANNEL = id++
private val ACTION_TG_GROUP = id++
private val ACTION_CONTRIBUTE = id++
private val ACTION_CONTRIBUTORS = id++
private val ACTION_OSS_LICENSES = id++
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
OssLicensesMenuActivity.setActivityTitle(getString(R.string.oss_license_title))
binding.apply {
setSupportActionBar(toolbar)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setTitle(R.string.about)
toolbar.setNavigationOnClickListener { finish() }
aboutHeader.apply {
ideVersion.text = createVersionText()
ideVersion.isClickable = true
ideVersion.isFocusable = true
ideVersion.setBackgroundResource(R.drawable.bg_ripple)
ideVersion.setOnClickListener { view ->
ClipboardUtils.copyText((view as TextView).text.toString())
flashSuccess(R.string.copied)
}
}
socials.apply {
sectionTitle.setText(R.string.title_socials)
sectionItems.adapter = AboutSocialItemsAdapter(createSocialItems(), ::handleActionClick)
}
misc.apply {
sectionTitle.setText(R.string.title_misc)
sectionItems.adapter = AboutSocialItemsAdapter(createMiscItems(), ::handleActionClick)
}
}
}
override fun onInsetsUpdated(insets: Rect) {
super.onInsetsUpdated(insets)
binding.toolbar.apply {
setPaddingRelative(
paddingStart + insets.left,
paddingTop,
paddingEnd + insets.right,
paddingBottom
)
}
}
private fun handleActionClick(action: SimpleIconTitleDescriptionItem) {
when (action.id) {
ACTION_WEBSITE -> app.openWebsite()
ACTION_EMAIL -> app.emailUs()
ACTION_TG_GROUP -> app.openTelegramGroup()
ACTION_TG_CHANNEL -> app.openTelegramChannel()
ACTION_OSS_LICENSES -> startActivity(Intent(this, OssLicensesMenuActivity::class.java))
ACTION_CONTRIBUTE -> app.openUrl(BaseApplication.CONTRIBUTOR_GUIDE_URL)
ACTION_CONTRIBUTORS -> startActivity(Intent(this, ContributorsActivity::class.java))
}
}
private fun createSocialItems(): List<IconTitleDescriptionItem> {
return mutableListOf<IconTitleDescriptionItem>().apply {
add(createSimpleIconTextItem(
this@AboutActivity,
ACTION_WEBSITE,
R.drawable.ic_website,
R.string.about_option_website,
BuildInfo.PROJECT_SITE
))
add(createSimpleIconTextItem(
this@AboutActivity,
ACTION_EMAIL,
R.drawable.ic_email,
R.string.about_option_email,
BaseApplication.EMAIL
))
add(createSimpleIconTextItem(
this@AboutActivity,
ACTION_TG_GROUP,
R.drawable.ic_telegram,
R.string.discussions_on_telegram,
BaseApplication.TELEGRAM_GROUP_URL
))
add(createSimpleIconTextItem(
this@AboutActivity,
ACTION_TG_CHANNEL,
R.drawable.ic_telegram,
R.string.official_tg_channel,
BaseApplication.TELEGRAM_CHANNEL_URL
))
}
}
private fun createMiscItems(): List<IconTitleDescriptionItem> {
return mutableListOf<IconTitleDescriptionItem>().apply {
add(SimpleIconTitleDescriptionItem.create(
this@AboutActivity,
ACTION_CONTRIBUTE,
R.drawable.ic_code,
R.string.title_contribute,
R.string.summary_contribute
))
add(SimpleIconTitleDescriptionItem.create(
this@AboutActivity,
ACTION_CONTRIBUTORS,
R.drawable.ic_heart_outline,
R.string.title_contributors,
R.string.summary_contributors
))
add(SimpleIconTitleDescriptionItem.create(
this@AboutActivity,
ACTION_OSS_LICENSES,
R.drawable.ic_licenses,
R.string.title_open_source_licenses,
R.string.summary_open_source_licenses
))
}
}
private fun createSimpleIconTextItem(
context: Context,
id: Int,
@DrawableRes icon: Int,
@StringRes title: Int,
description: CharSequence
): SimpleIconTitleDescriptionItem {
return SimpleIconTitleDescriptionItem(
id,
ContextCompat.getDrawable(context, icon),
ContextCompat.getString(context, title),
description
)
}
/**
* Create the version name string that should be displayed to the user.
*
* Format of the version name string is :
*
* `v[version-name]-[variant] ([build-type]/[[UN]OFFICIAL])`
*/
@Suppress("KDocUnresolvedReference")
private fun createVersionText(): CharSequence {
val builder = SpannableStringBuilder()
builder.append("v")
builder.append(BuildInfo.VERSION_NAME_SIMPLE)
builder.append("-")
builder.append(BuildConfig.FLAVOR)
builder.append(" ")
val colorPositive = ContextCompat.getColor(this, R.color.color_success)
val colorNegative = ContextCompat.getColor(this, R.color.color_error)
appendBuildType(builder, colorPositive, colorNegative)
return builder
}
private fun appendBuildType(
builder: SpannableStringBuilder,
@ColorInt
colorPositive: Int,
@ColorInt
colorNegative: Int
) {
@Suppress("KotlinConstantConditions")
var color = if (BuildConfig.BUILD_TYPE != "release") {
colorNegative
} else {
colorPositive
}
builder.append("(")
appendForegroundSpan(builder, BuildConfig.BUILD_TYPE, color)
val isOfficialBuild = BuildInfoUtils.isOfficialBuild(this)
color = if (isOfficialBuild) {
colorPositive
} else {
colorNegative
}
builder.append("/")
appendForegroundSpan(
builder,
BuildInfoUtils.getBuildType(this).lowercase(),
color)
builder.append(")")
}
private fun appendForegroundSpan(
builder: SpannableStringBuilder,
text: CharSequence,
color: Int
) {
builder.append(text,
ForegroundColorSpan(color),
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
class AboutSocialItemsAdapter(
items: List<IconTitleDescriptionItem>,
private val onClickListener: (SimpleIconTitleDescriptionItem) -> Unit
) : SimpleIconTitleDescriptionAdapter(items) {
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
super.onBindViewHolder(holder, position)
val binding = holder.binding
val item = getItem(position) as SimpleIconTitleDescriptionItem
val dp8 = SizeUtils.dp2px(8f)
binding.icon.updatePaddingRelative(dp8, dp8, dp8, dp8)
binding.title.setTextAppearance(R.style.TextAppearance_Material3_TitleSmall)
binding.description.maxLines = 3
binding.description.setTextAppearance(R.style.TextAppearance_Material3_BodySmall)
binding.description.setTextColor(binding.description.context.resolveAttr(R.attr.colorPrimary))
binding.root.isClickable = true
binding.root.isFocusable = true
binding.root.setBackgroundResource(R.drawable.bg_ripple)
binding.root.setOnClickListener {
onClickListener(item)
}
}
}
}
@@ -0,0 +1,93 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.activities
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import com.itsaky.androidide.R
import com.itsaky.androidide.adapters.ContributorsGridAdapter
import com.itsaky.androidide.app.LimitlessIDEActivity
import com.itsaky.androidide.databinding.ActivityContributorsBinding
import com.itsaky.androidide.viewmodel.ContributorsViewModel
/**
* @author Akash Yadav
*/
class ContributorsActivity : LimitlessIDEActivity() {
private var _binding: ActivityContributorsBinding? = null
private val binding: ActivityContributorsBinding
get() = checkNotNull(_binding) {
"Activity has been destroyed"
}
private val viewModel by viewModels<ContributorsViewModel>()
override fun bindLayout(): View {
_binding = ActivityContributorsBinding.inflate(layoutInflater)
return binding.root
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.apply {
setSupportActionBar(toolbar)
supportActionBar!!.setTitle(R.string.title_contributors)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
toolbar.setNavigationOnClickListener { finish() }
githubContributors.apply {
sectionTitle.setText(R.string.title_github_contributors)
}
translationContributors.apply {
sectionTitle.setText(R.string.title_crowdin_translators)
}
}
viewModel._crowdinTranslators.observe(this) { translators ->
binding.translationContributors.sectionItems.adapter = ContributorsGridAdapter(translators)
}
viewModel._githubContributors.observe(this) { githubContributors ->
binding.githubContributors.sectionItems.adapter = ContributorsGridAdapter(githubContributors)
}
viewModel.fetchAll()
}
override fun onInsetsUpdated(insets: Rect) {
super.onInsetsUpdated(insets)
binding.toolbar.apply {
setPaddingRelative(
paddingStart + insets.left,
paddingTop,
paddingEnd + insets.right,
paddingBottom
)
}
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
@@ -0,0 +1,112 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.itsaky.androidide.R
import com.itsaky.androidide.app.IDEApplication
import com.itsaky.androidide.contributors.Contributor
import com.itsaky.androidide.databinding.LayoutContributorsItemBinding
import com.itsaky.androidide.templates.Template
/**
* @author Akash Yadav
*/
class ContributorsGridAdapter(
contributors: List<Contributor>
) : RecyclerView.Adapter<ContributorsGridAdapter.ViewHolder>() {
private val contributors = contributors.toMutableList()
class ViewHolder(val binding: LayoutContributorsItemBinding) :
RecyclerView.ViewHolder(binding.root)
override fun getItemCount(): Int {
return contributors.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutContributorsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding
val contributor = contributors[position]
if (contributor is EmptyContributor) {
binding.root.visibility = View.INVISIBLE
return
}
Glide.with(binding.root)
.load(contributor.avatarUrl)
.placeholder(R.drawable.ic_account)
.transition(DrawableTransitionOptions.withCrossFade(100))
.into(binding.root)
binding.root.setOnClickListener {
IDEApplication.instance.openUrl(contributor.profileUrl)
}
}
object EmptyContributor : Contributor {
override val id: Int
get() = 0
override val username: String
get() = ""
override val avatarUrl: String
get() = ""
override val profileUrl: String
get() = ""
}
internal fun fillDiff(extras: Int) {
val count = itemCount
for (i in 1..extras) {
contributors.add(EmptyContributor)
}
val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return count
}
override fun getNewListSize(): Int {
return count + extras
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return newItemPosition < count && oldItemPosition == newItemPosition
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return areItemsTheSame(oldItemPosition, newItemPosition)
}
})
diff.dispatchUpdatesTo(this)
}
}
@@ -57,9 +57,9 @@ open class DefaultOnboardingItemAdapter<T : OnboardingItem>(
binding.content.title.text = item.title
if (item.description.isNotBlank()) {
binding.content.subtitle.text = item.description
binding.content.description.text = item.description
} else {
binding.content.subtitle.visibility = View.INVISIBLE
binding.content.description.visibility = View.INVISIBLE
}
if (item.icon != 0) {
@@ -51,7 +51,7 @@ class OnboardingPermissionsAdapter(private val permissions: List<OnboardingPermi
binding.infoContent.apply {
title.setText(permission.title)
subtitle.setText(permission.description)
description.setText(permission.description)
}
binding.grantButton.setOnClickListener {
@@ -0,0 +1,46 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.contributors
/**
* A contributor.
*
* @author Akash Yadav
*/
interface Contributor {
/**
* Unique integer ID.
*/
val id: Int
/**
* Unique username.
*/
val username: String
/**
* URL for the contributor's avatar.
*/
val avatarUrl: String
/**
* URL for the contributor's profile.
*/
val profileUrl: String
}
@@ -0,0 +1,86 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.contributors
import com.google.gson.annotations.SerializedName
import com.itsaky.androidide.utils.ILogger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
private interface CrowdinTranslatorsService {
@GET(CrowdinTranslators.CROWDIN_CONTRIBUTORS_JSON)
fun getAllTranslators(): Call<List<CrowdinTranslator>>
}
object CrowdinTranslators {
internal const val CROWDIN_CONTRIBUTORS_JSON = "crowdin-contributors.json"
private val log = ILogger.newInstance("CrowdinTranslators")
/**
* Get all Crowdin translators.
*/
suspend fun getAllTranslators(): List<CrowdinTranslator> {
val retrofit = Retrofit.Builder()
.baseUrl("${GITHUB_RAW_API_REPO_BRANCH_URL}/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(CrowdinTranslatorsService::class.java)
val response = withContext(Dispatchers.IO) { service.getAllTranslators().execute() }
if (!response.isSuccessful) {
log.error("Failed to get Crowdin translators list, request unsuccessful",
response.errorBody()?.string() ?: "(empty error response)")
return emptyList()
}
return response.body() ?: run {
log.error("Response body is null")
emptyList()
}
}
}
/**
* A Crowdin translator.
*
* @author Akash Yadav
*/
data class CrowdinTranslator(
@SerializedName("id") private val _id: String,
@SerializedName("username") override val username: String,
@SerializedName("picture") override val avatarUrl: String,
) : Contributor {
override val id: Int
get() = _id.toInt()
override val profileUrl: String
get() = "${CROWDIN_PROFILE_BASE_URL}/$username"
companion object {
const val CROWDIN_PROFILE_BASE_URL = "https://crowdin.com/profile"
}
}
@@ -0,0 +1,75 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.contributors
import com.google.gson.annotations.SerializedName
import com.itsaky.androidide.utils.ILogger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
/**
* @author Akash Yadav
*/
interface GitHubContributorsService {
@GET("contributors")
fun getAllContributors(): Call<List<GitHubContributor>>
}
object GitHubContributors {
private val log = ILogger.newInstance("GitHubContributors")
/**
* Get all GitHub contributors.
*/
suspend fun getAllContributors(): List<GitHubContributor> {
val retrofit = Retrofit.Builder()
.baseUrl("${GITHUB_API_REPO_URL}/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(GitHubContributorsService::class.java)
val response = withContext(Dispatchers.IO) { service.getAllContributors().execute() }
if (!response.isSuccessful) {
log.error("Failed to get GitHub contributors list, request unsuccessful",
response.errorBody()?.string() ?: "(empty error response)")
return emptyList()
}
return response.body() ?: run {
log.error("Response body is null")
emptyList()
}
}
}
/**
* A GitHub contributor.
*/
data class GitHubContributor(
@SerializedName("id") override val id: Int,
@SerializedName("login") override val username: String,
@SerializedName("avatar_url") override val avatarUrl: String,
@SerializedName("html_url") override val profileUrl: String
) : Contributor
@@ -0,0 +1,28 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.contributors
import com.itsaky.androidide.buildinfo.BuildInfo
const val GITHUB_API_BASE_URL = "https://api.github.com"
const val GITHUB_API_REPOS_URL = "${GITHUB_API_BASE_URL}/repos"
const val GITHUB_API_REPO_URL = "${GITHUB_API_REPOS_URL}/${BuildInfo.REPO_OWNER}/${BuildInfo.REPO_NAME}"
const val GITHUB_RAW_API_BASE_URL = "https://raw.githubusercontent.com"
const val GITHUB_RAW_API_REPO_URL = "${GITHUB_RAW_API_BASE_URL}/${BuildInfo.REPO_OWNER}/${BuildInfo.REPO_NAME}"
const val GITHUB_RAW_API_REPO_BRANCH_URL = "${GITHUB_RAW_API_REPO_URL}/dev"
@@ -18,20 +18,16 @@ package com.itsaky.androidide.fragments
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.blankj.utilcode.util.AppUtils.getAppVersionCode
import com.blankj.utilcode.util.ClipboardUtils
import com.blankj.utilcode.util.DeviceUtils.getManufacturer
import com.blankj.utilcode.util.DeviceUtils.getModel
import com.itsaky.androidide.BuildConfig
import com.itsaky.androidide.buildinfo.BuildInfo
import com.itsaky.androidide.databinding.LayoutCrashReportBinding
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.BuildInfoUtils
class CrashReportFragment : Fragment() {
@@ -45,26 +41,6 @@ class CrashReportFragment : Fragment() {
const val KEY_TRACE = "crash_trace"
const val KEY_CLOSE_APP_ON_CLICK = "close_on_app_click"
private val CRASH_REPORT_HEADER by lazy {
val map = mapOf(
"Version" to "v${BuildInfo.VERSION_NAME_SIMPLE} (${getAppVersionCode()})",
"CI Build" to BuildInfo.CI_BUILD,
"Branch" to BuildInfo.CI_GIT_BRANCH,
"Commit" to BuildInfo.CI_GIT_COMMIT_HASH,
"Variant" to "${BuildConfig.FLAVOR} (${BuildConfig.BUILD_TYPE})",
"SDK Version" to Build.VERSION.SDK_INT,
"Supported ABIs" to "[${Build.SUPPORTED_ABIS.joinToString(separator = ", ")}]",
"Manufacturer" to getManufacturer(),
"Device" to getModel()
)
"""
AndroidIDE Crash Report
${map.entries.joinToString(separator = System.lineSeparator()) { "${it.key} : ${it.value}" }}
Stacktrace:
""".trim()
}
@JvmStatic
fun newInstance(trace: String): CrashReportFragment {
return newInstance(null, null, trace, true)
@@ -147,7 +123,7 @@ Stacktrace:
private fun buildReportText(trace: String?): String {
return """
$CRASH_REPORT_HEADER
${BuildInfoUtils.getBuildInfoHeader()}
$trace
"""
}
@@ -82,7 +82,7 @@ constructor(
val donate = MainScreenAction(
ACTION_DONATE,
R.string.btn_donate,
R.drawable.ic_donate
R.drawable.ic_heart
)
val docs = MainScreenAction(
@@ -19,44 +19,12 @@ package com.itsaky.androidide.preferences
import android.content.Intent
import com.itsaky.androidide.activities.AboutActivity
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.app.IDEApplication
import com.itsaky.androidide.resources.R
import kotlinx.parcelize.Parcelize
private const val KEY_GITHUB = "idepref_gh"
private const val KEY_TG_CHANNEL = "idepref_tg_channel"
private const val KEY_TG_GROUP = "idepref_tg_group"
private const val KEY_CHANGELOG = "idepref_changelog"
private const val KEY_ABOUT = "idepref_about"
val github =
SimpleClickablePreference(
key = KEY_GITHUB,
title = R.string.title_github,
summary = R.string.idepref_github_summary
) {
BaseApplication.getBaseInstance().openGitHub()
true
}
val channel =
SimpleClickablePreference(
key = KEY_TG_CHANNEL,
title = R.string.official_tg_channel,
summary = R.string.idepref_channel_summary
) {
BaseApplication.getBaseInstance().openTelegramChannel()
true
}
val group =
SimpleClickablePreference(
key = KEY_TG_GROUP,
title = R.string.discussions_on_telegram,
summary = R.string.idepref_group_summary
) {
BaseApplication.getBaseInstance().openTelegramGroup()
true
}
val changelog =
SimpleClickablePreference(
key = KEY_CHANGELOG,
@@ -74,9 +74,6 @@ class AboutPreferences(
) : IPreferenceGroup() {
init {
addPreference(github)
addPreference(channel)
addPreference(group)
addPreference(changelog)
addPreference(about)
}
@@ -0,0 +1,46 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.ui
import android.content.Context
import android.util.AttributeSet
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
import com.itsaky.androidide.adapters.ContributorsGridAdapter
import com.itsaky.androidide.utils.FlexboxUtils
class ContributorsRecyclerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {
private var globalLayoutListener = FlexboxUtils.createGlobalLayoutListenerToDistributeFlexboxItemsEvenly(
{ adapter }, { layoutManager as FlexboxLayoutManager }) { adapter, extras ->
(adapter as ContributorsGridAdapter).fillDiff(extras)
}
init {
layoutManager = FlexboxLayoutManager(context, FlexDirection.ROW).apply {
justifyContent = JustifyContent.SPACE_EVENLY
}
viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener)
}
}
@@ -0,0 +1,79 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.utils
import android.content.Context
import android.os.Build
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.DeviceUtils
import com.itsaky.androidide.BuildConfig
import com.itsaky.androidide.app.IDEApplication
import com.itsaky.androidide.buildinfo.BuildInfo
import com.termux.shared.android.PackageUtils
import com.termux.shared.termux.TermuxConstants
import com.termux.shared.termux.TermuxUtils
/**
* @author Akash Yadav
*/
object BuildInfoUtils {
private val BUILD_INFO_HEADER by lazy {
val map = mapOf(
"Version" to "v${BuildInfo.VERSION_NAME_SIMPLE} (${AppUtils.getAppVersionCode()})",
"CI Build" to BuildInfo.CI_BUILD,
"Branch" to BuildInfo.CI_GIT_BRANCH,
"Commit" to BuildInfo.CI_GIT_COMMIT_HASH,
"Variant" to "${BuildConfig.FLAVOR} (${BuildConfig.BUILD_TYPE})",
"Build type" to getBuildType(),
"SDK Version" to Build.VERSION.SDK_INT,
"Supported ABIs" to "[${Build.SUPPORTED_ABIS.joinToString(separator = ", ")}]",
"Manufacturer" to DeviceUtils.getManufacturer(),
"Device" to DeviceUtils.getModel(),
)
"""
AndroidIDE Crash Report
${map.entries.joinToString(separator = System.lineSeparator()) { "${it.key} : ${it.value}" }}
Stacktrace:
""".trim()
}
@JvmStatic
fun getBuildInfoHeader(): String {
return BUILD_INFO_HEADER
}
private fun getBuildType() = getBuildType(IDEApplication.instance)
fun getBuildType(context: Context) = if (isOfficialBuild(context)) "OFFICIAL" else "UNOFFICIAL"
/**
* Whether the AndroidIDE build is official or not. This checks the signature digest of the
* APK against the signature digest of the official signing key.
*/
@JvmStatic
fun isOfficialBuild(context: Context): Boolean {
val sha256DigestForPackage = PackageUtils.getSigningCertificateSHA256DigestForPackage(
context,
TermuxConstants.TERMUX_PACKAGE_NAME
)
return TermuxConstants.APK_RELEASE_ANDROIDIDE == TermuxUtils.getAPKRelease(
sha256DigestForPackage)
}
}
@@ -0,0 +1,80 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.itsaky.androidide.contributors.Contributor
import com.itsaky.androidide.contributors.CrowdinTranslator
import com.itsaky.androidide.contributors.CrowdinTranslators
import com.itsaky.androidide.contributors.GitHubContributor
import com.itsaky.androidide.contributors.GitHubContributors
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
* @author Akash Yadav
*/
class ContributorsViewModel : ViewModel() {
internal val _crowdinTranslators = MutableLiveData(emptyList<CrowdinTranslator>())
internal val _githubContributors = MutableLiveData(emptyList<GitHubContributor>())
companion object {
private const val CONTRIBUTORS_MAX_SIZE = 30
}
val crowdinTranslators: List<CrowdinTranslator>
get() = _crowdinTranslators.value ?: emptyList()
val githubContributors: List<GitHubContributor>
get() = _githubContributors.value ?: emptyList()
fun fetchCrowdinTranslators() {
viewModelScope.launch(Dispatchers.Default) {
val translators = CrowdinTranslators.getAllTranslators()
withContext(Dispatchers.Main) {
_crowdinTranslators.value = translators.trimToMaxSize()
}
}
}
fun fetchGitHubTranslators() {
viewModelScope.launch(Dispatchers.Default) {
val contributors = GitHubContributors.getAllContributors()
withContext(Dispatchers.Main) {
_githubContributors.value = contributors.trimToMaxSize()
}
}
}
fun fetchAll() {
fetchCrowdinTranslators()
fetchGitHubTranslators()
}
private fun <T : Contributor> List<T>.trimToMaxSize() : List<T> {
return if (size > CONTRIBUTORS_MAX_SIZE) {
subList(0, CONTRIBUTORS_MAX_SIZE)
} else {
this
}
}
}
+136
View File
@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding_double"
android:paddingTop="@dimen/content_padding_double"
android:clipChildren="false"
android:clipToPadding="false"
android:fillViewport="true"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ide_card"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/social_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/socials"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/misc_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_double"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/social_card">
<include
android:id="@+id/misc"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.itsaky.androidide.ui.BottomInsetHeightDistributor
android:id="@+id/height_distributor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_double"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/misc_card" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/ide_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/content_padding_double"
android:layout_marginBottom="@dimen/content_padding_double"
android:layout_marginStart="@dimen/content_padding_double"
android:layout_marginEnd="@dimen/content_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/scroll_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<include
android:id="@+id/about_header"
layout="@layout/layout_about_header" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="8dp"
android:fitsSystemWindows="true"
app:elevation="8dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -47,7 +47,7 @@
app:layout_constraintVertical_bias="0.4" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/subtitle"
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
+136
View File
@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding_double"
android:paddingTop="@dimen/content_padding_double"
android:clipChildren="false"
android:clipToPadding="false"
android:fillViewport="true"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ide_card"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/social_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/socials"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/misc_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_double"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/social_card">
<include
android:id="@+id/misc"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.itsaky.androidide.ui.BottomInsetHeightDistributor
android:id="@+id/height_distributor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_double"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/misc_card" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/ide_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/content_padding_double"
android:layout_marginBottom="@dimen/content_padding_double"
android:layout_marginStart="@dimen/content_padding_double"
android:layout_marginEnd="@dimen/content_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/scroll_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<include
android:id="@+id/about_header"
layout="@layout/layout_about_header" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="8dp"
android:fitsSystemWindows="true"
app:elevation="8dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -47,7 +47,7 @@
app:layout_constraintVertical_bias="0.4" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/subtitle"
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
+106 -75
View File
@@ -1,85 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutDescription="@xml/motion_about">
<View
android:id="@+id/icon_anchor"
android:layout_width="0dp"
android:layout_height="200dp"
android:background="?android:attr/colorBackground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/icon_container"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginStart="16dp"
android:layout_marginTop="-28dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:cardCornerRadius="56dp"
app:cardElevation="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_anchor">
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp"
android:gravity="center"
android:text="@string/app_name"
android:textColor="?attr/colorOnPrimaryContainer"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_container" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/about_subtitle"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/colorOnSecondaryContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
android:animateLayoutChanges="true">
<androidx.core.widget.NestedScrollView
android:id="@+id/about_scroller"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitle">
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<include
android:id="@+id/items"
layout="@layout/layout_about_items"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="24dp" />
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/ide_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/about_header"
layout="@layout/layout_about_header" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/social_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ide_card">
<include
android:id="@+id/socials"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/misc_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/social_card">
<include
android:id="@+id/misc"
layout="@layout/layout_about_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.itsaky.androidide.ui.BottomInsetHeightDistributor
android:id="@+id/height_distributor"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/misc_card" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="8dp"
android:fitsSystemWindows="true"
app:elevation="8dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/github_contributors_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/github_contributors"
layout="@layout/layout_contributors_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/translation_contributors_card"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/github_contributors_card">
<include
android:id="@+id/translation_contributors"
layout="@layout/layout_contributors_list_section" />
</com.google.android.material.card.MaterialCardView>
<com.itsaky.androidide.ui.BottomInsetHeightDistributor
android:id="@+id/height_distributor"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/translation_contributors_card" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="8dp"
android:fitsSystemWindows="true"
app:elevation="8dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -45,7 +45,7 @@
app:layout_constraintTop_toBottomOf="@id/icon" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/subtitle"
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.Constraints
android:id="@+id/ide_bottom_padding"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ide_version" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/icon"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_margin="16dp"
android:background="@color/primaryColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Full"
app:srcCompat="@mipmap/ic_launcher_foreground" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/greeting_subtitle"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/ide_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
app:layout_constraintBottom_toTopOf="@id/ide_bottom_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/description"
tools:text="v2.6.1-beta for arm64 (dev/offcial)" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -1,140 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="16dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:fillViewport="true"
tools:ignore="ScrollViewSize">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/github"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:tint="?attr/colorOnBackground"
app:srcCompat="@drawable/ic_github" />
<ImageView
android:id="@+id/discuss"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:tint="?attr/colorOnBackground"
app:srcCompat="@drawable/ic_telegram" />
<ImageView
android:id="@+id/email"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:tint="?attr/colorOnBackground"
app:srcCompat="@drawable/ic_email" />
<ImageView
android:id="@+id/website"
android:layout_width="30dp"
android:layout_height="30dp"
app:tint="?attr/colorOnBackground"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_website" />
<ImageView
android:id="@+id/licenses"
app:tint="?attr/colorOnBackground"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_licenses" />
</LinearLayout>
</HorizontalScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="4dp"
android:text="@string/title_translations"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/dividerVertical" />
<TextView
android:id="@+id/translations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
android:layout_marginEnd="16dp"
tools:text="Hindi - Akash Yadav"
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/footer_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center"
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
android:textColor="?attr/colorOnBackground"
tools:text="AndroidIDE v2.1.3-beta for arm64-v8a" />
</LinearLayout>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/section_items"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/section_title"
tools:itemCount="5"
tools:listitem="@layout/layout_icon_title_description" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/title_socials" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="4dp"
android:clickable="true"
android:focusable="true"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Full"
tools:tint="?colorOnSurface"
tools:srcCompat="@drawable/ic_android">
</com.google.android.material.imageview.ShapeableImageView>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/title_socials" />
<com.itsaky.androidide.ui.ContributorsRecyclerView
android:id="@+id/section_items"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/section_title"
tools:itemCount="30"
tools:listitem="@layout/layout_contributors_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -25,6 +25,6 @@
<include
android:id="@+id/content"
layout="@layout/layout_icon_title_subtitle" />
layout="@layout/layout_icon_title_description" />
</com.google.android.material.card.MaterialCardView>
-135
View File
@@ -1,135 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="50">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="@id/about_scroller" />
<KeyFrameSet>
<KeyAttribute
android:alpha="0.0"
app:framePosition="50"
app:motionTarget="@id/icon_container" />
<KeyAttribute
android:alpha="0.0"
app:framePosition="30"
app:motionTarget="@id/subtitle" />
</KeyFrameSet>
</Transition>
<ConstraintSet>
<Constraint
android:id="@+id/icon_anchor"
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/icon_container"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginStart="16dp"
android:layout_marginTop="-28dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_anchor" />
<Constraint
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_container" />
<Constraint
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:alpha="1.0"
android:scaleX="1.0"
android:scaleY="1.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<Constraint
android:id="@+id/about_scroller"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitle" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/icon_anchor"
android:layout_width="0dp"
android:layout_height="56dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/icon_container"
android:layout_width="48dp"
android:layout_height="48dp"
android:alpha="0.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_anchor" />
<Constraint
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:scaleX="0.7"
android:scaleY="0.7"
app:layout_constraintBottom_toBottomOf="@id/icon_anchor"
app:layout_constraintStart_toStartOf="@id/icon_anchor"
app:layout_constraintTop_toTopOf="@id/icon_anchor" />
<Constraint
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.0"
android:scaleX="0.0"
android:scaleY="0.0"
app:layout_constraintBottom_toBottomOf="@id/icon_anchor"
app:layout_constraintStart_toStartOf="@id/icon_anchor"
app:layout_constraintTop_toBottomOf="@id/title" />
<Constraint
android:id="@+id/about_scroller"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon_anchor" />
</ConstraintSet>
</MotionScene>
@@ -0,0 +1,44 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.contributors
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
/**
* @author Akash Yadav
*/
@RunWith(RobolectricTestRunner::class)
class ContributorsAPITest {
@Test
fun `test crowdin contributors deserialization`() = runBlocking {
val translators = CrowdinTranslators.getAllTranslators()
assertThat(translators).isNotEmpty()
}
@Test
fun `test GitHub contributors exclusion`() = runBlocking {
val contributors = GitHubContributors.getAllContributors()
assertThat(contributors).isNotEmpty()
assertThat(contributors.filter { it.username == "itsaky" }).isNotEmpty()
}
}
@@ -20,11 +20,9 @@ package com.itsaky.androidide.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.itsaky.androidide.databinding.LayoutSimpleIconTextBinding;
import com.itsaky.androidide.common.databinding.LayoutSimpleIconTextBinding;
/**
* A RecyclerView.Adapter which can be used to show a list with an icon and a text.
@@ -44,8 +42,8 @@ public abstract class IconTextAdapter<E> extends RecyclerView.Adapter<IconTextAd
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new VH(
LayoutSimpleIconTextBinding.inflate(
LayoutInflater.from(parent.getContext()), parent, false));
LayoutSimpleIconTextBinding.inflate(LayoutInflater.from(parent.getContext()), parent,
false));
}
@Override
@@ -109,10 +107,12 @@ public abstract class IconTextAdapter<E> extends RecyclerView.Adapter<IconTextAd
}
public interface OnBindListener<T> {
default boolean onBind(T item, VH holder, int position) {
return false;
}
default void postBind(T item, VH holder, int position) {}
default void postBind(T item, VH holder, int position) {
}
}
}
@@ -0,0 +1,54 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.itsaky.androidide.common.databinding.LayoutIconTitleDescriptionBinding
import com.itsaky.androidide.models.IconTitleDescriptionItem
/**
* [RecyclerView.Adapter] for showing [IconTitleDescription] items.
*
* @author Akash Yadav
*/
abstract class IconTitleDescriptionAdapter() :
RecyclerView.Adapter<IconTitleDescriptionAdapter.ViewHolder>() {
class ViewHolder(val binding: LayoutIconTitleDescriptionBinding) :
RecyclerView.ViewHolder(binding.root)
abstract fun getItem(position: Int): IconTitleDescriptionItem
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutIconTitleDescriptionBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding
val item = getItem(position)
binding.apply {
icon.setImageDrawable(item.icon)
title.text = item.title
description.text = item.description
}
}
}
@@ -0,0 +1,38 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import com.itsaky.androidide.models.IconTitleDescriptionItem
/**
* Simple implementation of [IconTitleDescriptionAdapter].
*
* @author Akash Yadav
*/
open class SimpleIconTitleDescriptionAdapter(
protected val items: List<IconTitleDescriptionItem>
) : IconTitleDescriptionAdapter() {
override fun getItem(position: Int): IconTitleDescriptionItem {
return items[position]
}
override fun getItemCount(): Int {
return items.size
}
}
@@ -19,14 +19,15 @@ package com.itsaky.androidide.app;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import androidx.core.app.NotificationManagerCompat;
import com.blankj.utilcode.util.ThrowableUtils;
import com.itsaky.androidide.buildinfo.BuildInfo;
import com.itsaky.androidide.common.R;
import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.androidide.managers.ToolsManager;
import com.itsaky.androidide.resources.R;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.FileUtil;
import com.itsaky.androidide.utils.FlashbarUtilsKt;
@@ -41,6 +42,7 @@ public class BaseApplication extends Application {
public static final String TELEGRAM_CHANNEL_URL = "https://t.me/AndroidIDEOfficial";
public static final String SPONSOR_URL = BuildInfo.PROJECT_SITE + "/donate";
public static final String DOCS_URL = BuildInfo.PROJECT_SITE + "/docs";
public static final String CONTRIBUTOR_GUIDE_URL = BuildInfo.REPO_URL + "/blob/dev/CONTRIBUTING.md";
public static final String EMAIL = "contact@androidide.com";
private static BaseApplication instance;
private PreferenceManager mPrefsManager;
@@ -125,6 +127,8 @@ public class BaseApplication extends Application {
} catch (Throwable th) {
if (pkg != null) {
openUrl(url);
} else if (th instanceof ActivityNotFoundException) {
FlashbarUtilsKt.flashError(R.string.msg_app_unavailable_for_intent);
} else {
FlashbarUtilsKt.flashError(th.getMessage());
}
@@ -25,7 +25,7 @@ import androidx.annotation.LayoutRes
import androidx.viewbinding.ViewBinding
/**
* Handles inflation and release of [ViewBinding][androidx.viewbinding.ViewBinding] for the fragment.
* Handles inflation and release of [ViewHolder][androidx.viewbinding.ViewBinding] for the fragment.
*
* @author Akash Yadav
*/
@@ -36,7 +36,7 @@ abstract class FragmentWithBinding<T : ViewBinding> : BaseFragment {
protected val binding: T
get() = checkNotNull(
_binding) { "Cannot access ViewBinding. Fragment may have been destroyed." }
_binding) { "Cannot access ViewHolder. Fragment may have been destroyed." }
private var bind: ((View) -> T)? = null
@@ -0,0 +1,31 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.models
import android.graphics.drawable.Drawable
/**
* Model for [com.itsaky.androidide.adapters.IconTitleDescriptionAdapter].
*
* @author Akash Yadav
*/
interface IconTitleDescriptionItem {
val icon: Drawable?
val title: CharSequence
val description: CharSequence
}
@@ -0,0 +1,54 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.models
import android.content.Context
import android.graphics.drawable.Drawable
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
/**
* @author Akash Yadav
*/
data class SimpleIconTitleDescriptionItem(
val id: Int,
override val icon: Drawable?,
override val title: CharSequence,
override val description: CharSequence
) : IconTitleDescriptionItem {
companion object {
@JvmStatic
fun create(
context: Context,
id: Int,
@DrawableRes icon: Int,
@StringRes title: Int,
@StringRes description: Int
): SimpleIconTitleDescriptionItem {
return SimpleIconTitleDescriptionItem(
id,
ContextCompat.getDrawable(context, icon),
ContextCompat.getString(context, title),
ContextCompat.getString(context, description)
)
}
}
}
@@ -31,8 +31,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_android"
tools:tint="?attr/colorOnSurface" />
app:tint="?attr/colorOnSurface"
tools:src="@drawable/ic_android" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
@@ -44,14 +44,14 @@
android:gravity="bottom|start"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintBottom_toTopOf="@id/subtitle"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/greeting_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/subtitle"
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
@@ -31,14 +31,14 @@
android:gravity="bottom|start"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintBottom_toTopOf="@id/subtitle"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/greeting_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/subtitle"
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
@@ -0,0 +1,76 @@
<!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="720dp"
android:viewportHeight="720"
android:viewportWidth="1280"
android:width="1280dp">
<path
android:fillColor="#FF000000"
android:pathData="M1142.6,413.3V311.9H1200.9v11.4h-46v31.4h41.1v11.3h-41.1v36H1200.9v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m1058.1,311.9v101.4h26.3c6.6,0 12.2,-1.2 16.9,-3.8 4.8,-2.5 8.5,-6 11.1,-10.6 2.7,-4.6 4,-10 4,-16.3v-40.4c0,-6.2 -1.3,-11.6 -4,-16.1 -2.6,-4.5 -6.3,-8.1 -11.1,-10.6 -4.7,-2.5 -10.4,-3.8 -16.9,-3.8zM1070.6,323h13.8c6.1,0 10.9,1.7 14.3,5.1 3.5,3.4 5.3,8.2 5.3,14.2v40.4c0,6.1 -1.8,10.9 -5.3,14.3 -3.4,3.4 -8.2,5.1 -14.3,5.1h-13.8z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m976.6,413.3v-11.4h20.7v-78.6h-20.7v-11.4h54.2v11.4h-20.7v78.6h20.7v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m936.7,311.9v22.2l0.3,17.4h-0.4c-0.6,-4.9 -2.8,-8.8 -6.5,-11.7 -3.7,-2.9 -8.4,-4.3 -14.2,-4.3 -7.7,0 -13.8,2.5 -18.5,7.6 -4.6,5.1 -6.9,12 -6.9,20.8v22.4c0,8.7 2.3,15.6 6.9,20.7 4.7,5.1 10.9,7.6 18.5,7.6 5.7,0 10.5,-1.4 14.2,-4.2 3.7,-2.9 5.9,-6.8 6.5,-11.8h0.1v14.6h12.5L949.2,311.9ZM920,346.3c5.2,0 9.3,1.6 12.2,4.9 3,3.2 4.4,7.7 4.4,13.5v20.8c0,5.7 -1.5,10.2 -4.4,13.5 -3,3.2 -7,4.9 -12.2,4.9 -5.3,0 -9.4,-1.6 -12.5,-4.7 -3.1,-3.1 -4.6,-7.7 -4.6,-13.6L902.9,364.7c0,-5.9 1.5,-10.5 4.6,-13.6 3.1,-3.1 7.2,-4.7 12.5,-4.7z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m839,323.1q-4.6,0 -7.2,-2.4 -2.6,-2.4 -2.6,-6.4 0,-4.2 2.6,-6.5 2.6,-2.5 7.2,-2.5 4.6,0 7.2,2.5 2.6,2.4 2.6,6.5 0,4 -2.6,6.4 -2.6,2.4 -7.2,2.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m807.1,413.3v-11.4h27.1V348.3h-23.6v-11.4h36.1v65h25.7v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m753.6,335.8c-9.3,0 -16.6,2.6 -21.9,7.8 -5.3,5.2 -7.9,12.3 -7.9,21.4v20.3c0,9 2.6,16.1 7.9,21.4 5.4,5.2 12.7,7.8 21.9,7.8 9.3,0 16.5,-2.6 21.8,-7.8 5.4,-5.3 8.1,-12.4 8.1,-21.4v-20.4c0,-9 -2.7,-16.1 -8.1,-21.3 -5.3,-5.2 -12.5,-7.8 -21.8,-7.8zM753.6,346.9c5.5,0 9.7,1.5 12.8,4.6 3.1,3.1 4.6,7.5 4.6,13.5v20.3c0,5.9 -1.5,10.4 -4.6,13.5 -3.1,3.1 -7.3,4.6 -12.8,4.6 -5.4,0 -9.6,-1.5 -12.8,-4.6 -3.1,-3.1 -4.6,-7.5 -4.6,-13.5v-20.3c0,-5.9 1.5,-10.4 4.6,-13.5 3.1,-3.1 7.4,-4.6 12.8,-4.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m644,413.3v-76.4h12.2v13.6q3.8,-15 20.1,-15 12.1,0 19.2,7.6 7.2,7.5 7.2,20.4v4.6h-12.5v-3.5q0,-9 -4.4,-13.8 -4.3,-4.9 -12.4,-4.9 -7.9,0 -12.5,4.9 -4.4,4.9 -4.4,13.8v48.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m603.3,311.9v22.2l0.3,17.4h-0.4c-0.6,-4.9 -2.8,-8.8 -6.5,-11.7 -3.7,-2.9 -8.4,-4.3 -14.2,-4.3 -7.7,0 -13.8,2.5 -18.5,7.6 -4.6,5.1 -6.9,12 -6.9,20.8v22.4c0,8.7 2.3,15.6 6.9,20.7 4.7,5.1 10.9,7.6 18.5,7.6 5.7,0 10.5,-1.4 14.2,-4.2 3.7,-2.9 5.9,-6.8 6.5,-11.8h0.1v14.6h12.5L615.8,311.9ZM586.6,346.3c5.2,0 9.3,1.6 12.2,4.9 3,3.2 4.4,7.7 4.4,13.5v20.8c0,5.7 -1.5,10.2 -4.4,13.5 -3,3.2 -7,4.9 -12.2,4.9 -5.3,0 -9.4,-1.6 -12.5,-4.7 -3.1,-3.1 -4.6,-7.7 -4.6,-13.6L569.5,364.7c0,-5.9 1.5,-10.5 4.6,-13.6 3.1,-3.1 7.2,-4.7 12.5,-4.7z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m474.6,413.3v-76.4h12.5v14.6h0.1q1,-7.6 6.3,-11.8 5.3,-4.2 14,-4.2 11.5,0 18.3,7.1 6.8,7.1 6.8,19.3v51.4H520.2v-50q0,-8.2 -4.4,-12.5 -4.3,-4.4 -11.8,-4.4 -7.8,0 -12.4,4.7 -4.4,4.7 -4.4,13.6v48.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m411.9,311.9 l-26.4,101.4h12.8l6.7,-26.9h30.7l6.7,26.9h12.6l-26.3,-101.4zM420.2,321.9c0.2,1.2 0.7,3.8 1.5,7.8 0.8,4 2,8.9 3.5,14.9l7.8,31.3h-25.6l7.8,-31.4c1.5,-5.8 2.6,-10.7 3.5,-14.7 0.8,-4 1.3,-6.6 1.5,-7.8z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#000000"
android:pathData="m147.4,321c-0.2,-0 -0.5,0 -0.7,0.1 -0.8,0.2 -1.6,0.8 -1.6,2 -0,0.7 0.2,1.3 0.6,1.8 1.5,2.6 3,5.2 4.5,7.8 1.3,2.3 2.6,4.5 3.9,6.8 0.4,0.6 0.7,1.3 1.1,1.9 -8.8,4.9 -15.9,11.5 -21.3,19.9 -5.4,8.4 -8.3,17.5 -9.2,27.4 1.3,0.2 119.7,0.1 120.3,-0.1 -0.1,-1.1 -0.2,-2.1 -0.4,-3.2 -0.2,-1.3 -0.5,-2.5 -0.7,-3.8 -0.3,-2 -0.9,-4 -1.5,-6 -0.3,-1 -0.7,-2.1 -1.1,-3.1 -0.5,-1.4 -1,-2.7 -1.6,-4.1 -0.7,-1.6 -1.6,-3.1 -2.4,-4.7 -1.3,-2.2 -2.6,-4.2 -4.1,-6.2 -1.4,-1.8 -2.7,-3.5 -4.3,-5.1 -1.2,-1.2 -2.4,-2.4 -3.7,-3.5 -1.1,-1 -2.3,-2 -3.6,-3 -1.9,-1.5 -3.9,-2.8 -6,-4 -0.4,-0.2 -0.7,-0.5 -1.1,-0.7 0.6,-1 1.1,-2 1.6,-2.9 1.2,-2.1 2.5,-4.2 3.7,-6.3 1,-1.7 2,-3.5 3,-5.2 0.6,-1 1.1,-1.9 1.6,-3 0.5,-1 -0.1,-2.3 -1.1,-2.8 -1,-0.5 -2.1,-0.2 -2.8,0.9 -0.7,1.2 -1.4,2.4 -2.1,3.7 -1.2,2 -2.4,4 -3.5,5.9 -1.4,2.4 -2.8,4.9 -4.3,7.3 -0.1,0.1 -0.2,0.3 -0.3,0.4 -1.7,-0.6 -3.2,-1.3 -4.9,-1.9 -0.8,-0.3 -1.6,-0.6 -2.4,-0.8 -1.9,-0.5 -3.8,-1 -5.7,-1.4 -1,-0.2 -1.9,-0.4 -2.9,-0.5 -0.8,-0.1 -1.6,-0.2 -2.3,-0.3 -0.7,-0.1 -1.4,-0.3 -2.2,-0.3 -2.2,-0.1 -4.4,-0 -6.6,-0.1 -2.5,-0 -4.9,0.1 -7.4,0.5 -1.9,0.3 -3.7,0.6 -5.6,1 -3.1,0.7 -6.1,1.6 -9,2.8 -0.8,0.3 -1.6,0.7 -2.4,1 -0.7,-1.2 -1.3,-2.3 -2,-3.5C155.3,332.6 153.3,329.2 151.3,325.9 150.6,324.6 149.9,323.4 149.1,322.1 148.8,321.5 148.1,321.1 147.4,321ZM212.5,361.9c0.1,-0 0.2,0 0.3,0 1.2,0.1 2.4,0.6 3.3,1.6 0.9,0.9 1.4,2.1 1.4,3.4 -0,0.9 -0.4,1.7 -0.9,2.5 -1,1.4 -2.4,2.1 -4.2,2.2 -1.5,-0.2 -2.6,-0.7 -3.5,-1.7 -0.6,-0.7 -0.9,-1.4 -1.1,-2.2 -0.3,-1.3 0.1,-2.5 0.8,-3.6 0.7,-1.1 1.8,-1.7 3,-2 0.3,-0.1 0.7,-0.1 1,-0.1zM157.1,361.9c0.1,-0 0.2,-0 0.3,0 0.9,0 1.8,0.3 2.6,0.9 1.5,1.1 2.2,2.5 2.1,4.4 -0.2,2.8 -3,4.8 -5.5,4.3 -2.5,-0.5 -3.6,-1.9 -4.2,-4 -0.2,-0.6 -0.2,-1.3 0.1,-2 0.3,-0.7 0.5,-1.2 0.9,-1.7 0.9,-1.2 2.3,-1.9 3.7,-1.9z" />
<path
android:fillColor="#000000"
android:pathData="m233.7,281.8c-0.6,0 -1,0 -1.5,0l0,13.3l0.8,0c3,0 6,0.1 9,0.1 2.7,0.1 5.3,0.7 7.7,1.8 2.1,1 3.8,2.4 4.9,4.4 1,1.8 1.5,3.9 1.6,6 0,1.2 -0,2.3 -0.1,3.5 -0.1,1.3 -0.1,2.7 -0.2,4 -0.1,2 -0.3,4.1 -0.4,6.1 -0.1,1.3 -0.1,2.6 -0.2,3.9 -0.1,1.9 -0.3,3.8 -0.4,5.7 -0.1,2 -0.3,4 -0.4,6 -0.1,2.6 -0.1,5.2 0.5,7.7 0.9,4.4 3,8.1 6.4,11 2.2,1.8 4.6,3.1 7.3,3.9 0.8,0.2 1.5,0.4 2.3,0.6 -0.9,0.3 -1.8,0.5 -2.7,0.7 -3.6,1.1 -6.7,3.1 -9.1,6.1 -3.2,3.8 -4.6,8.3 -4.7,13.2 -0,1.7 0.1,3.4 0.1,5.1 0.1,1.5 0.1,2.9 0.2,4.4 0.1,1.9 0.3,3.8 0.4,5.7 0.1,2 0.3,4 0.4,6.1 0.1,1.5 0.2,3.1 0.3,4.6 0.1,1.3 0.1,2.5 0.2,3.8 0.2,1.8 0.1,3.6 -0.2,5.3 -0.5,2.5 -1.6,4.6 -3.6,6.2 -2.5,2.1 -5.5,3.1 -8.7,3.4 -2.1,0.2 -4.1,0.2 -6.2,0.3 -1.5,0 -2.9,0 -4.4,0 -0.3,0 -0.5,0 -0.8,0l0,13.3l0.8,0 5.9,0c2.3,-0 4.6,-0.1 6.9,-0.3 3,-0.3 6,-0.9 8.8,-1.9 4.2,-1.4 8,-3.6 11,-6.9 1.6,-1.7 2.8,-3.5 3.8,-5.6 2,-4.2 2.5,-8.7 2.2,-13.2 -0.1,-1.9 -0.3,-3.9 -0.4,-5.8 -0.1,-1.9 -0.2,-3.9 -0.3,-5.8 -0.1,-1.6 -0.2,-3.1 -0.3,-4.7 -0.1,-1.3 -0.1,-2.6 -0.2,-3.9 -0.1,-1.9 -0.3,-3.8 -0.4,-5.7 -0.1,-1.6 -0.2,-3.3 -0.1,-5 0.1,-1.9 0.4,-3.9 1.1,-5.7 0.9,-2.5 2.5,-4.3 5,-5.3 2.8,-1.1 5.7,-1.4 8.6,-1.6 2,-0.1 4.1,-0.1 6.1,-0.1l14.3,0 0.8,0l0,-13.3l-0.8,0c-5.2,0 -10.3,-0 -15.5,0 -2.5,0 -5,-0 -7.6,-0.3 -1.9,-0.2 -3.8,-0.6 -5.7,-1.2 -2.3,-0.8 -4,-2.3 -5,-4.6 -1.2,-2.8 -1.4,-5.7 -1.5,-8.7 -0,-1.2 0.2,-2.5 0.2,-3.7 0.2,-2.5 0.3,-5.1 0.5,-7.6 0.1,-1.7 0.2,-3.3 0.3,-5 0.2,-2.5 0.3,-5.1 0.5,-7.6 0.1,-1.7 0.2,-3.4 0.3,-5 0.1,-2.5 0,-5 -0.4,-7.5 -0.9,-5.3 -3.5,-9.6 -7.4,-13.1 -2.5,-2.2 -5.5,-3.8 -8.7,-4.9 -4.5,-1.6 -9.3,-2.3 -14.1,-2.3 -2.4,-0 -4.9,0 -7.4,0z" />
<path
android:fillColor="#000000"
android:pathData="M129.3,281.8C127.3,281.8 125.4,281.9 123.4,282.1 119.7,282.5 116.1,283.4 112.7,284.9 109.3,286.4 106.3,288.5 103.8,291.4 99.9,296.1 98.4,301.6 98.5,307.6c0,1.9 0.2,3.9 0.3,5.8 0.1,1.3 0.1,2.6 0.2,3.9 0.1,2 0.3,4 0.4,6 0.1,2 0.2,4 0.4,6 0.1,2.3 0.3,4.6 0.4,6.9 0.1,1.4 0.1,2.9 0.1,4.3 -0,2.1 -0.4,4.1 -1.1,6.1 -0.9,2.4 -2.4,4.2 -4.8,5.1 -0.7,0.3 -1.4,0.5 -2.2,0.7 -2.6,0.7 -5.3,0.9 -8,0.9 -6,0.1 -12,0 -18,0 -0.3,0 -0.5,0 -0.8,0l0,13.3l0.9,0c7,0.1 14,-0.2 20.9,0.2 2.2,0.1 4.4,0.5 6.5,1.2 2.3,0.8 4,2.2 5,4.4 0.9,1.9 1.3,3.9 1.5,6 0.1,2.1 0.1,4.1 -0.1,6.2 -0.2,2 -0.2,4 -0.3,6 -0.1,2.3 -0.3,4.6 -0.5,6.9 -0.1,1.7 -0.2,3.4 -0.3,5.2 -0.2,2.6 -0.4,5.2 -0.5,7.8 -0.1,2.4 -0,4.8 0.4,7.2 1,5.4 3.5,9.8 7.5,13.4 2.9,2.5 6.2,4.2 9.9,5.3 4.1,1.3 8.3,1.7 12.5,1.8 2.5,0 4.9,0 7.4,0 0.2,0 0.4,-0 0.7,-0.1l0,-13.2c-0.1,-0 -0.2,-0 -0.3,-0 -2.8,-0 -5.6,-0.1 -8.5,-0.1 -2.5,-0 -5,-0.5 -7.4,-1.5 -3.7,-1.6 -6,-4.2 -6.8,-8.2 -0.3,-1.6 -0.5,-3.2 -0.3,-4.8 0.2,-2.1 0.3,-4.2 0.4,-6.4 0.1,-1.6 0.2,-3.2 0.3,-4.8 0.1,-1.3 0.1,-2.5 0.2,-3.8 0.1,-2 0.3,-3.9 0.4,-5.9 0.1,-2 0.2,-4 0.3,-6 0.2,-3.1 0.1,-6.3 -0.8,-9.3 -1.8,-6.3 -5.6,-10.7 -11.7,-13.2 -1.1,-0.4 -2.3,-0.7 -3.5,-1.1 0.3,-0.1 0.5,-0.1 0.8,-0.2 4.6,-1.1 8.4,-3.3 11.3,-7.2 2.7,-3.7 3.9,-7.8 4,-12.3 0.1,-2.2 -0.1,-4.5 -0.2,-6.8 -0,-0.7 -0.1,-1.4 -0.1,-2 -0.1,-2.3 -0.3,-4.6 -0.4,-6.9 -0.1,-2 -0.2,-4 -0.3,-6 -0.1,-2.3 -0.4,-4.6 -0.4,-7 -0.1,-1.6 -0.2,-3.1 -0.1,-4.7 0.3,-2.5 0.9,-4.9 2.6,-6.8 1.5,-1.8 3.5,-3 5.7,-3.8 2.2,-0.8 4.4,-1 6.7,-1.1 2.5,-0 5,-0 7.5,-0 0.2,0 0.5,-0 0.7,-0L136.8,281.8L136,281.8Z" />
</vector>
@@ -0,0 +1,59 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="156dp"
android:viewportHeight="156.4"
android:viewportWidth="1135.6"
android:width="1132.6957dp">
<path
android:fillColor="#FF000000"
android:pathData="M1077.3,131.5L1077.3,30.1L1135.6,30.1v11.4h-46v31.4h41.1v11.3h-41.1v36L1135.6,120.1v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m992.8,30.1v101.4h26.3c6.6,0 12.2,-1.2 16.9,-3.8 4.8,-2.5 8.5,-6 11.1,-10.6 2.7,-4.6 4,-10 4,-16.3v-40.4c0,-6.2 -1.3,-11.6 -4,-16.1 -2.6,-4.5 -6.3,-8.1 -11.1,-10.6 -4.7,-2.5 -10.4,-3.8 -16.9,-3.8zM1005.3,41.2h13.8c6.1,0 10.9,1.7 14.3,5.1 3.5,3.4 5.3,8.2 5.3,14.2v40.4c0,6.1 -1.8,10.9 -5.3,14.3 -3.4,3.4 -8.2,5.1 -14.3,5.1h-13.8z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m911.3,131.5v-11.4h20.7v-78.6h-20.7v-11.4h54.2v11.4h-20.7v78.6h20.7v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m871.4,30.1v22.2l0.3,17.4h-0.4c-0.6,-4.9 -2.8,-8.8 -6.5,-11.7 -3.7,-2.9 -8.4,-4.3 -14.2,-4.3 -7.7,0 -13.8,2.5 -18.5,7.6 -4.6,5.1 -6.9,12 -6.9,20.8v22.4c0,8.7 2.3,15.6 6.9,20.7 4.7,5.1 10.9,7.6 18.5,7.6 5.7,0 10.5,-1.4 14.2,-4.2 3.7,-2.9 5.9,-6.8 6.5,-11.8h0.1v14.6h12.5L883.9,30.1ZM854.7,64.5c5.2,0 9.3,1.6 12.2,4.9 3,3.2 4.4,7.7 4.4,13.5v20.8c0,5.7 -1.5,10.2 -4.4,13.5 -3,3.2 -7,4.9 -12.2,4.9 -5.3,0 -9.4,-1.6 -12.5,-4.7 -3.1,-3.1 -4.6,-7.7 -4.6,-13.6L837.7,82.9c0,-5.9 1.5,-10.5 4.6,-13.6 3.1,-3.1 7.2,-4.7 12.5,-4.7z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m773.8,41.3q-4.6,0 -7.2,-2.4 -2.6,-2.4 -2.6,-6.4 0,-4.2 2.6,-6.5 2.6,-2.5 7.2,-2.5 4.6,0 7.2,2.5 2.6,2.4 2.6,6.5 0,4 -2.6,6.4 -2.6,2.4 -7.2,2.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m741.8,131.5v-11.4h27.1L768.9,66.5h-23.6v-11.4h36.1v65h25.7v11.4z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m688.3,54c-9.3,0 -16.6,2.6 -21.9,7.8 -5.3,5.2 -7.9,12.3 -7.9,21.4v20.3c0,9 2.6,16.1 7.9,21.4 5.4,5.2 12.7,7.8 21.9,7.8 9.3,0 16.5,-2.6 21.8,-7.8 5.4,-5.3 8.1,-12.4 8.1,-21.4v-20.4c0,-9 -2.7,-16.1 -8.1,-21.3 -5.3,-5.2 -12.5,-7.8 -21.8,-7.8zM688.3,65.1c5.5,0 9.7,1.5 12.8,4.6 3.1,3.1 4.6,7.5 4.6,13.5v20.3c0,5.9 -1.5,10.4 -4.6,13.5 -3.1,3.1 -7.3,4.6 -12.8,4.6 -5.4,0 -9.6,-1.5 -12.8,-4.6 -3.1,-3.1 -4.6,-7.5 -4.6,-13.5v-20.3c0,-5.9 1.5,-10.4 4.6,-13.5 3.1,-3.1 7.4,-4.6 12.8,-4.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m578.7,131.5v-76.4h12.2v13.6q3.8,-15 20.1,-15 12.1,0 19.2,7.6 7.2,7.5 7.2,20.4v4.6h-12.5v-3.5q0,-9 -4.4,-13.8 -4.3,-4.9 -12.4,-4.9 -7.9,0 -12.5,4.9 -4.4,4.9 -4.4,13.8v48.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m538,30.1v22.2l0.3,17.4h-0.4c-0.6,-4.9 -2.8,-8.8 -6.5,-11.7 -3.7,-2.9 -8.4,-4.3 -14.2,-4.3 -7.7,0 -13.8,2.5 -18.5,7.6 -4.6,5.1 -6.9,12 -6.9,20.8v22.4c0,8.7 2.3,15.6 6.9,20.7 4.7,5.1 10.9,7.6 18.5,7.6 5.7,0 10.5,-1.4 14.2,-4.2 3.7,-2.9 5.9,-6.8 6.5,-11.8h0.1v14.6h12.5L550.5,30.1ZM521.3,64.5c5.2,0 9.3,1.6 12.2,4.9 3,3.2 4.4,7.7 4.4,13.5v20.8c0,5.7 -1.5,10.2 -4.4,13.5 -3,3.2 -7,4.9 -12.2,4.9 -5.3,0 -9.4,-1.6 -12.5,-4.7 -3.1,-3.1 -4.6,-7.7 -4.6,-13.6L504.3,82.9c0,-5.9 1.5,-10.5 4.6,-13.6 3.1,-3.1 7.2,-4.7 12.5,-4.7z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m409.4,131.5v-76.4h12.5v14.6h0.1q1,-7.6 6.3,-11.8 5.3,-4.2 14,-4.2 11.5,0 18.3,7.1 6.8,7.1 6.8,19.3v51.4L454.9,131.5v-50q0,-8.2 -4.4,-12.5 -4.3,-4.4 -11.8,-4.4 -7.8,0 -12.4,4.7 -4.4,4.7 -4.4,13.6v48.6z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#FF000000"
android:pathData="m346.6,30.1 l-26.4,101.4h12.8l6.7,-26.9h30.7l6.7,26.9h12.6l-26.3,-101.4zM354.9,40.1c0.2,1.2 0.7,3.8 1.5,7.8 0.8,4 2,8.9 3.5,14.9l7.8,31.3h-25.6l7.8,-31.4c1.5,-5.8 2.6,-10.7 3.5,-14.7 0.8,-4 1.3,-6.6 1.5,-7.8z"
android:strokeWidth="6.36084" />
<path
android:fillColor="#000000"
android:pathData="m82.2,39.2c-0.2,-0 -0.5,0 -0.7,0.1 -0.8,0.2 -1.6,0.8 -1.6,2 -0,0.7 0.2,1.3 0.6,1.8 1.5,2.6 3,5.2 4.5,7.8 1.3,2.3 2.6,4.5 3.9,6.8 0.4,0.6 0.7,1.3 1.1,1.9 -8.8,4.9 -15.9,11.5 -21.3,19.9 -5.4,8.4 -8.3,17.5 -9.2,27.4 1.3,0.2 119.7,0.1 120.3,-0.1 -0.1,-1.1 -0.2,-2.1 -0.4,-3.2 -0.2,-1.3 -0.5,-2.5 -0.7,-3.8 -0.3,-2 -0.9,-4 -1.5,-6 -0.3,-1 -0.7,-2.1 -1.1,-3.1 -0.5,-1.4 -1,-2.7 -1.6,-4.1 -0.7,-1.6 -1.6,-3.1 -2.4,-4.7 -1.3,-2.2 -2.6,-4.2 -4.1,-6.2 -1.4,-1.8 -2.7,-3.5 -4.3,-5.1 -1.2,-1.2 -2.4,-2.4 -3.7,-3.5 -1.1,-1 -2.3,-2 -3.6,-3 -1.9,-1.5 -3.9,-2.8 -6,-4 -0.4,-0.2 -0.7,-0.5 -1.1,-0.7 0.6,-1 1.1,-2 1.6,-2.9 1.2,-2.1 2.5,-4.2 3.7,-6.3 1,-1.7 2,-3.5 3,-5.2 0.6,-1 1.1,-1.9 1.6,-3 0.5,-1 -0.1,-2.3 -1.1,-2.8 -1,-0.5 -2.1,-0.2 -2.8,0.9 -0.7,1.2 -1.4,2.4 -2.1,3.7 -1.2,2 -2.4,4 -3.5,5.9 -1.4,2.4 -2.8,4.9 -4.3,7.3 -0.1,0.1 -0.2,0.3 -0.3,0.4 -1.7,-0.6 -3.2,-1.3 -4.9,-1.9 -0.8,-0.3 -1.6,-0.6 -2.4,-0.8 -1.9,-0.5 -3.8,-1 -5.7,-1.4 -1,-0.2 -1.9,-0.4 -2.9,-0.5 -0.8,-0.1 -1.6,-0.2 -2.3,-0.3 -0.7,-0.1 -1.4,-0.3 -2.2,-0.3 -2.2,-0.1 -4.4,-0 -6.6,-0.1 -2.5,-0 -4.9,0.1 -7.4,0.5 -1.9,0.3 -3.7,0.6 -5.6,1 -3.1,0.7 -6.1,1.6 -9,2.8 -0.8,0.3 -1.6,0.7 -2.4,1 -0.7,-1.2 -1.3,-2.3 -2,-3.5C90,50.8 88,47.4 86.1,44.1 85.3,42.8 84.6,41.6 83.9,40.3 83.5,39.7 82.9,39.3 82.2,39.2ZM147.2,80.1c0.1,-0 0.2,0 0.3,0 1.2,0.1 2.4,0.6 3.3,1.6 0.9,0.9 1.4,2.1 1.4,3.4 -0,0.9 -0.4,1.7 -0.9,2.5 -1,1.4 -2.4,2.1 -4.2,2.2 -1.5,-0.2 -2.6,-0.7 -3.5,-1.7 -0.6,-0.7 -0.9,-1.4 -1.1,-2.2 -0.3,-1.3 0.1,-2.5 0.8,-3.6 0.7,-1.1 1.8,-1.7 3,-2 0.3,-0.1 0.7,-0.1 1,-0.1zM91.8,80.1c0.1,-0 0.2,-0 0.3,0 0.9,0 1.8,0.3 2.6,0.9 1.5,1.1 2.2,2.5 2.1,4.4 -0.2,2.8 -3,4.8 -5.5,4.3 -2.5,-0.5 -3.6,-1.9 -4.2,-4 -0.2,-0.6 -0.2,-1.3 0.1,-2 0.3,-0.7 0.5,-1.2 0.9,-1.7 0.9,-1.2 2.3,-1.9 3.7,-1.9z" />
<path
android:fillColor="#000000"
android:pathData="m168.5,0c-0.6,0 -1,0 -1.5,0l0,13.3l0.8,0c3,0 6,0.1 9,0.1 2.7,0.1 5.3,0.7 7.7,1.8 2.1,1 3.8,2.4 4.9,4.4 1,1.8 1.5,3.9 1.6,6 0,1.2 -0,2.3 -0.1,3.5 -0.1,1.3 -0.1,2.7 -0.2,4 -0.1,2 -0.3,4.1 -0.4,6.1 -0.1,1.3 -0.1,2.6 -0.2,3.9 -0.1,1.9 -0.3,3.8 -0.4,5.7 -0.1,2 -0.3,4 -0.4,6 -0.1,2.6 -0.1,5.2 0.5,7.7 0.9,4.4 3,8.1 6.4,11 2.2,1.8 4.6,3.1 7.3,3.9 0.8,0.2 1.5,0.4 2.3,0.6 -0.9,0.3 -1.8,0.5 -2.7,0.7 -3.6,1.1 -6.7,3.1 -9.1,6.1 -3.2,3.8 -4.6,8.3 -4.7,13.2 -0,1.7 0.1,3.4 0.1,5.1 0.1,1.5 0.1,2.9 0.2,4.4 0.1,1.9 0.3,3.8 0.4,5.7 0.1,2 0.3,4 0.4,6.1 0.1,1.5 0.2,3.1 0.3,4.6 0.1,1.3 0.1,2.5 0.2,3.8 0.2,1.8 0.1,3.6 -0.2,5.3 -0.5,2.5 -1.6,4.6 -3.6,6.2 -2.5,2.1 -5.5,3.1 -8.7,3.4 -2.1,0.2 -4.1,0.2 -6.2,0.3 -1.5,0 -2.9,0 -4.4,0 -0.3,0 -0.5,0 -0.8,0l0,13.3l0.8,0 5.9,0c2.3,-0 4.6,-0.1 6.9,-0.3 3,-0.3 6,-0.9 8.8,-1.9 4.2,-1.4 8,-3.6 11,-6.9 1.6,-1.7 2.8,-3.5 3.8,-5.6 2,-4.2 2.5,-8.7 2.2,-13.2 -0.1,-1.9 -0.3,-3.9 -0.4,-5.8 -0.1,-1.9 -0.2,-3.9 -0.3,-5.8 -0.1,-1.6 -0.2,-3.1 -0.3,-4.7 -0.1,-1.3 -0.1,-2.6 -0.2,-3.9 -0.1,-1.9 -0.3,-3.8 -0.4,-5.7 -0.1,-1.6 -0.2,-3.3 -0.1,-5 0.1,-1.9 0.4,-3.9 1.1,-5.7 0.9,-2.5 2.5,-4.3 5,-5.3 2.8,-1.1 5.7,-1.4 8.6,-1.6 2,-0.1 4.1,-0.1 6.1,-0.1l14.3,0 0.8,0l0,-13.3l-0.8,0c-5.2,0 -10.3,-0 -15.5,0 -2.5,0 -5,-0 -7.6,-0.3 -1.9,-0.2 -3.8,-0.6 -5.7,-1.2 -2.3,-0.8 -4,-2.3 -5,-4.6 -1.2,-2.8 -1.4,-5.7 -1.5,-8.7 -0,-1.2 0.2,-2.5 0.2,-3.7 0.2,-2.5 0.3,-5.1 0.5,-7.6 0.1,-1.7 0.2,-3.3 0.3,-5 0.2,-2.5 0.3,-5.1 0.5,-7.6 0.1,-1.7 0.2,-3.4 0.3,-5 0.1,-2.5 0,-5 -0.4,-7.5 -0.9,-5.3 -3.5,-9.6 -7.4,-13.1 -2.5,-2.2 -5.5,-3.8 -8.7,-4.9 -4.5,-1.6 -9.3,-2.3 -14.1,-2.3 -2.4,-0 -4.9,0 -7.4,0z" />
<path
android:fillColor="#000000"
android:pathData="M64,0C62.1,-0 60.1,0.1 58.1,0.3 54.4,0.7 50.9,1.6 47.4,3.1 44,4.6 41,6.7 38.6,9.6 34.6,14.3 33.1,19.8 33.2,25.8c0,1.9 0.2,3.9 0.3,5.8 0.1,1.3 0.1,2.6 0.2,3.9 0.1,2 0.3,4 0.4,6 0.1,2 0.2,4 0.4,6 0.1,2.3 0.3,4.6 0.4,6.9 0.1,1.4 0.1,2.9 0.1,4.3 -0,2.1 -0.4,4.1 -1.1,6.1 -0.9,2.4 -2.4,4.2 -4.8,5.1 -0.7,0.3 -1.4,0.5 -2.2,0.7 -2.6,0.7 -5.3,0.9 -8,0.9 -6,0.1 -12,0 -18,0 -0.3,0 -0.5,0 -0.8,0l0,13.3l0.9,0c7,0.1 14,-0.2 20.9,0.2 2.2,0.1 4.4,0.5 6.5,1.2 2.3,0.8 4,2.2 5,4.4 0.9,1.9 1.3,3.9 1.5,6 0.1,2.1 0.1,4.1 -0.1,6.2 -0.2,2 -0.2,4 -0.3,6 -0.1,2.3 -0.3,4.6 -0.5,6.9 -0.1,1.7 -0.2,3.4 -0.3,5.2 -0.2,2.6 -0.4,5.2 -0.5,7.8 -0.1,2.4 -0,4.8 0.4,7.2 1,5.4 3.5,9.8 7.5,13.4 2.9,2.5 6.2,4.2 9.9,5.3 4.1,1.3 8.3,1.7 12.5,1.8 2.5,0 4.9,0 7.4,0 0.2,0 0.4,-0 0.7,-0.1l0,-13.2c-0.1,-0 -0.2,-0 -0.3,-0 -2.8,-0 -5.6,-0.1 -8.5,-0.1 -2.5,-0 -5,-0.5 -7.4,-1.5 -3.7,-1.6 -6,-4.2 -6.8,-8.2 -0.3,-1.6 -0.5,-3.2 -0.3,-4.8 0.2,-2.1 0.3,-4.2 0.4,-6.4 0.1,-1.6 0.2,-3.2 0.3,-4.8 0.1,-1.3 0.1,-2.5 0.2,-3.8 0.1,-2 0.3,-3.9 0.4,-5.9 0.1,-2 0.2,-4 0.3,-6 0.2,-3.1 0.1,-6.3 -0.8,-9.3 -1.8,-6.3 -5.6,-10.7 -11.7,-13.2 -1.1,-0.4 -2.3,-0.7 -3.5,-1.1 0.3,-0.1 0.5,-0.1 0.8,-0.2 4.6,-1.1 8.4,-3.3 11.3,-7.2 2.7,-3.7 3.9,-7.8 4,-12.3 0.1,-2.2 -0.1,-4.5 -0.2,-6.8 -0,-0.7 -0.1,-1.4 -0.1,-2 -0.1,-2.3 -0.3,-4.6 -0.4,-6.9 -0.1,-2 -0.2,-4 -0.3,-6 -0.1,-2.3 -0.4,-4.6 -0.4,-7 -0.1,-1.6 -0.2,-3.1 -0.1,-4.7 0.3,-2.5 0.9,-4.9 2.6,-6.8 1.5,-1.8 3.5,-3 5.7,-3.8 2.2,-0.8 4.4,-1 6.7,-1.1 2.5,-0 5,-0 7.5,-0 0.2,0 0.5,-0 0.7,-0L71.6,0L70.8,0Z" />
</vector>
@@ -5,10 +5,7 @@
<shape>
<solid android:color="#000" />
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
android:radius="16dp" />
</shape>
</item>
<item>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="#000000"
android:pathData="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" />
</vector>
@@ -1,4 +1,3 @@
<!-- drawable/heart.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="#000000"
android:pathData="M12.1,18.55L12,18.65L11.89,18.55C7.14,14.24 4,11.39 4,8.5C4,6.5 5.5,5 7.5,5C9.04,5 10.54,6 11.07,7.36H12.93C13.46,6 14.96,5 16.5,5C18.5,5 20,6.5 20,8.5C20,11.39 16.86,14.24 12.1,18.55M16.5,3C14.76,3 13.09,3.81 12,5.08C10.91,3.81 9.24,3 7.5,3C4.42,3 2,5.41 2,8.5C2,12.27 5.4,15.36 10.55,20.03L12,21.35L13.45,20.03C18.6,15.36 22,12.27 22,8.5C22,5.41 19.58,3 16.5,3Z" />
</vector>
+2 -1
View File
@@ -6,8 +6,9 @@
<color name="primaryIconColor">#ffffff</color>
<color name="rippleHighlightColor">#85121212</color>
<color name="color_error">#f44336</color>
<color name="color_success">@color/green_500</color>
<color name="color_warning">#ff9800</color>
<color name="color_error">#f44336</color>
<color name="diagnostic_error">@color/color_error</color>
<color name="diagnostic_warning">@color/color_warning</color>
+11
View File
@@ -547,4 +547,15 @@
<string name="msg_terminal_new_sessions_disabled">Cannot create session. New sessions are disabled!</string>
<string name="title_install_location_error">Install location error</string>
<string name="title_unsupported_user">Unsupported user</string>
<string name="title_socials">Socials</string>
<string name="title_contributors">Contributors</string>
<string name="summary_contributors">Top community contributors.</string>
<string name="title_github_contributors">GitHub Contributors</string>
<string name="title_crowdin_translators">Crowdin Translators</string>
<string name="title_misc">Misc</string>
<string name="title_contribute">Contribute</string>
<string name="summary_contribute">It\'s not just an IDE, it\'s a community. Contribute code, ideas, and passion to AndroidIDE.</string>
<string name="msg_app_unavailable_for_intent">No application available to handle intent.</string>
<string name="title_open_source_licenses">Open source licenses</string>
<string name="summary_open_source_licenses">View open source licenses.</string>
</resources>
@@ -87,7 +87,7 @@ abstract class AppIntroBaseFragment : Fragment(), SlideSelectionListener, SlideB
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(layoutId, container, false)
val titleText = view.findViewById<TextView>(R.id.title)
val titleText = view.findViewById<TextView>(R.id.ide_title)
val descriptionText = view.findViewById<TextView>(R.id.description)
val slideImage = view.findViewById<ImageView>(R.id.image)
val mainLayout = view.findViewById<ConstraintLayout>(R.id.main)
@@ -36,7 +36,7 @@ sealed class AppIntroPageTransformerType {
val titleParallaxFactor: Double = 1.0,
val imageParallaxFactor: Double = -1.0,
val descriptionParallaxFactor: Double = 2.0,
@IdRes val titleViewId: Int = R.id.title,
@IdRes val titleViewId: Int = R.id.ide_title,
@IdRes val imageViewId: Int = R.id.image,
@IdRes val descriptionViewId: Int = R.id.description
) : AppIntroPageTransformerType()
@@ -10,7 +10,7 @@
tools:background="@color/appintro_background_color">
<TextView
android:id="@+id/title"
android:id="@+id/ide_title"
style="@style/AppIntroDefaultHeading"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -44,7 +44,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/midline"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/ide_title"
app:layout_constraintVertical_chainStyle="spread"
app:layout_constraintVertical_weight="3"
tools:text="This is a demo of the AppIntro Library" />
@@ -10,7 +10,7 @@
tools:background="@color/appintro_background_color">
<TextView
android:id="@+id/title"
android:id="@+id/ide_title"
style="@style/AppIntroDefaultHeading"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -32,7 +32,7 @@
app:layout_constraintBottom_toTopOf="@+id/description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/ide_title"
app:layout_constraintVertical_weight="5" />
<TextView
@@ -175,7 +175,7 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
sources.addAll(mainSourceSet.sourceProvider.kotlinDirectories)
// build/generated/**
// AIDL, ViewBinding, Renderscript, BuildConfig i.e every generated source sources
// AIDL, ViewHolder, Renderscript, BuildConfig i.e every generated source sources
val selectedVariant = getSelectedVariant()
if (selectedVariant != null) {
sources.addAll(selectedVariant.mainArtifact.generatedSourceFolders)