Skip to content

Commit

Permalink
android app (misc): change app name + add CustomfetchMainRender + sho…
Browse files Browse the repository at this point in the history
…w dialog for external storage permission

and also I think workaroud for config when using generateConfig by directly overwritting it.
  • Loading branch information
Toni500github committed Dec 12, 2024
1 parent c70fa1f commit 2c1a74c
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 79 deletions.
8 changes: 1 addition & 7 deletions android/app/src/main/cpp/customfetch_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@

#define ARRAY_SIZE(x) sizeof(x) / sizeof(x[0])

extern "C" JNIEXPORT jstring JNICALL
Java_org_toni_customfetch_1android_widget_customfetch_idk(JNIEnv* env, jobject /* this */) {
std::string hello = "Hello from JNI.";
return env->NewStringUTF(hello.c_str());
}

void stringToCharArray(const std::vector<std::string>& tokens, char *argv[]) {
// Allocate memory for each word
for (size_t i = 0; i < tokens.size(); ++i) {
Expand All @@ -25,7 +19,7 @@ void stringToCharArray(const std::vector<std::string>& tokens, char *argv[]) {
extern std::string mainAndroid_and_render(int argc, char *argv[], JNIEnv *env, jobject obj);

extern "C" JNIEXPORT jstring JNICALL
Java_org_toni_customfetch_1android_widget_customfetchConfigureActivity_mainAndroid(JNIEnv *env, jobject obj, jstring args) {
Java_org_toni_customfetch_1android_widget_CustomfetchMainRender_mainAndroid(JNIEnv *env, jobject obj, jstring args) {
const std::string& str_args = env->GetStringUTFChars(args, nullptr);
const std::vector<std::string>& tokens = split(str_args, ' ');
char *argv[tokens.size()];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package org.toni.customfetch_android

import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceFragmentCompat
Expand All @@ -27,12 +22,6 @@ class SettingsActivity : AppCompatActivity() {
.commit()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
startActivity(intent)
}
}
}

class SettingsFragment : PreferenceFragmentCompat() {
Expand All @@ -42,7 +31,7 @@ class SettingsActivity : AppCompatActivity() {
}
}

val TAG: String = "AssetCopy"
const val TAG: String = "AssetCopy"

internal fun copyToAssetFolder(assets: AssetManager, absolutePath: String, assetSubFolder: String) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,8 @@ import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.TextUtils.TruncateAt
import android.text.TextUtils.ellipsize
import android.util.Log
import android.util.TypedValue
import android.widget.RemoteViews
import androidx.core.text.HtmlCompat
import org.toni.customfetch_android.R

/**
Expand Down Expand Up @@ -47,27 +40,17 @@ class customfetch : AppWidgetProvider() {
) {
// Get the new widget size
val widgetSize = WidgetSizeProvider(context)
val minWidthDp = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val maxWidthDp = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
val width = (widgetSize.getWidgetsSize(appWidgetId).first * 0.237f) // getWidgetSize(minWidthDp, maxWidthDp, context)
Log.d("widthTesting", "width = $width")
Log.d("wrappingTest", "disableLineWrap = $disableLineWrap")

val parsedContent = getParsedContent(context, appWidgetId, width, disableLineWrap)
val parsedContent = customfetchRender.getParsedContent(context, appWidgetId, width, disableLineWrap)

val views = RemoteViews(context.packageName, R.layout.customfetch)
views.setTextViewText(R.id.customfetch_text, parsedContent)
appWidgetManager.updateAppWidget(appWidgetId, views)
}

private fun convertDpToPx(context: Context, dp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
context.resources.displayMetrics
).toInt()
}

override fun onEnabled(context: Context) {
// Enter relevant functionality for when the first widget is created
}
Expand Down Expand Up @@ -124,36 +107,12 @@ internal fun updateAppWidget(
Log.d("widthTesting", "width = $width")
Log.d("wrappingTest", "disableLineWrap = $disableLineWrap")

val parsedContent = customfetchRender.getParsedContent(context, appWidgetId, width, disableLineWrap)

// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.customfetch)
views.setTextViewText(R.id.customfetch_text, getParsedContent(context, appWidgetId, width, disableLineWrap))
views.setTextViewText(R.id.customfetch_text, parsedContent)

// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}

internal fun getParsedContent(context: Context, appWidgetId: Int, width: Float, disableLineWrap: Boolean): SpannableStringBuilder {
val parsedContent = SpannableStringBuilder()
val arguments = loadTitlePref(context, appWidgetId)
val htmlContent = customfetchConfigureActivity().mainAndroid("customfetch $arguments")

if (disableLineWrap) {
val eachLine = htmlContent!!.split("<br>").map { it.trim() }
val paint = TextPaint()//.apply { textSize = 7f }
for (line in eachLine) {
var parsedLine = HtmlCompat.fromHtml(line, HtmlCompat.FROM_HTML_MODE_LEGACY)
parsedLine =
ellipsize(parsedLine, paint, width, TruncateAt.END) as Spanned
parsedContent.appendLine(parsedLine)
}
} else {
parsedContent.append(htmlContent?.let {
HtmlCompat.fromHtml(
it,
HtmlCompat.FROM_HTML_MODE_LEGACY
)
})
}

return parsedContent
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package org.toni.customfetch_android.widget

import android.app.Activity
import android.app.AlertDialog
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.os.Environment
import android.provider.Settings
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.TextUtils.TruncateAt
import android.text.TextUtils.ellipsize
import android.view.View
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.TextView
import androidx.core.text.HtmlCompat
import org.toni.customfetch_android.copyToAssetFolder
import org.toni.customfetch_android.databinding.CustomfetchConfigureBinding
import java.nio.file.Files
Expand Down Expand Up @@ -44,9 +52,8 @@ class customfetchConfigureActivity : Activity() {
setResult(RESULT_OK, resultValue)
finish()
}
private lateinit var binding: CustomfetchConfigureBinding

external fun mainAndroid(argv: String): String?
private lateinit var binding: CustomfetchConfigureBinding
public override fun onCreate(icicle: Bundle?) {
super.onCreate(icicle)

Expand All @@ -57,8 +64,28 @@ class customfetchConfigureActivity : Activity() {
binding = CustomfetchConfigureBinding.inflate(layoutInflater)
setContentView(binding.root)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
AlertDialog.Builder(this)
.setTitle("Grant external storage management permission")
.setMessage("Customfetch needs permissions to manage external storage for writing config files\n"+
"By default we going to read/write the following directories:\n"+
"/storage/emulated/0/.config/\n"+
"/storage/emulated/0/.config/customfetch/")
// The dialog is automatically dismissed when a dialog button is clicked.

.setPositiveButton("Grant permission"
) { _, _ ->
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
startActivity(intent)
}
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
}

if (!Files.exists(Path(filesDir.absolutePath + "ascii")))
copyToAssetFolder(assets, filesDir.absolutePath, "ascii");
copyToAssetFolder(assets, filesDir.absolutePath, "ascii")

appWidgetText = binding.appwidgetText
argsHelp = binding.argsHelp
Expand All @@ -67,7 +94,6 @@ class customfetchConfigureActivity : Activity() {
binding.addButton.setOnClickListener(onClickListener)

// Find the widget id from the intent.
val intent = intent
val extras = intent.extras
if (extras != null) {
appWidgetId = extras.getInt(
Expand All @@ -82,25 +108,58 @@ class customfetchConfigureActivity : Activity() {
}

appWidgetText.setText(loadTitlePref(this@customfetchConfigureActivity, appWidgetId))
argsHelp.text = mainAndroid("customfetch --help")
argsHelp.text = customfetchRender.mainAndroid("customfetch --help")

showModulesList.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { _, isChecked ->
showModulesList.setOnCheckedChangeListener { _, isChecked ->
if (isChecked)
argsHelp.text = mainAndroid("customfetch -l")
argsHelp.text = customfetchRender.mainAndroid("customfetch -l")
else
argsHelp.text = mainAndroid("customfetch --help")
})
disableWrapLines.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { _, isChecked ->
argsHelp.text = customfetchRender.mainAndroid("customfetch --help")
}
disableWrapLines.setOnCheckedChangeListener { _, isChecked ->
disableLineWrap = isChecked
})
}
}
}

class CustomfetchMainRender {
fun getParsedContent(context: Context, appWidgetId: Int, width: Float, disableLineWrap: Boolean, otherArguments: String = ""): SpannableStringBuilder {
val parsedContent = SpannableStringBuilder()
val arguments = otherArguments.ifEmpty {
loadTitlePref(context, appWidgetId)
}

val htmlContent = mainAndroid("customfetch $arguments")

if (disableLineWrap) {
val eachLine = htmlContent!!.split("<br>").map { it.trim() }
val paint = TextPaint()//.apply { textSize = 7f }
for (line in eachLine) {
var parsedLine = HtmlCompat.fromHtml(line, HtmlCompat.FROM_HTML_MODE_COMPACT)
parsedLine =
ellipsize(parsedLine, paint, width, TruncateAt.END) as Spanned
parsedContent.appendLine(parsedLine)
}
} else {
parsedContent.append(htmlContent?.let {
HtmlCompat.fromHtml(
it,
HtmlCompat.FROM_HTML_MODE_COMPACT
)
})
}

return parsedContent
}

external fun mainAndroid(argv: String): String?
companion object {
init {
System.loadLibrary("customfetch")
}
}
}
val customfetchRender = CustomfetchMainRender()

private const val PREFS_NAME = "org.toni.customfetch_android.customfetch"
private const val PREF_PREFIX_KEY = "appwidget_"
Expand Down
2 changes: 1 addition & 1 deletion android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<resources>
<string name="app_name">customfetch_android</string>
<string name="app_name">Customfetch Widget</string>
<!-- Settings Activity Title -->
<string name="title_activity_settings">SettingsActivity</string>

Expand Down
4 changes: 3 additions & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void Config::addAliasColors(const std::string& str)
{
const size_t pos = str.find('=');
if (pos == std::string::npos)
die("alias color '{}' does NOT have an equal sign '=' for separiting color name and value.\n"
die("alias color '{}' does NOT have an equal sign '=' for separating color name and value.\n"
"for more check with --help", str);

const std::string& name = str.substr(0, pos);
Expand All @@ -178,11 +178,13 @@ void Config::addAliasColors(const std::string& str)

void Config::generateConfig(const std::string_view filename)
{
#if !ANDROID_APP
if (std::filesystem::exists(filename))
{
if (!askUserYorN(false, "WARNING: config file {} already exists. Do you want to overwrite it?", filename))
std::exit(1);
}
#endif

std::ofstream f(filename.data(), std::ios::trunc);
f << AUTOCONFIG;
Expand Down

0 comments on commit 2c1a74c

Please sign in to comment.