diff --git a/app/build.gradle b/app/build.gradle index cc2eaa40..ff7bbf81 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,6 +32,7 @@ android { packagingOptions { exclude 'META-INF/**' + exclude 'kotlin/**' exclude 'org/**' exclude '**.properties' exclude '**.bin' @@ -72,5 +73,9 @@ dependencies { implementation 'tech.rectifier.preferencex-android:preferencex-simplemenu:88f93154b2' implementation 'me.zhanghai.android.appiconloader:appiconloader-glide:1.2.0' implementation 'me.zhanghai.android.fastscroll:library:1.1.5' + //noinspection DifferentStdlibGradleVersion + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.21' + implementation 'com.github.jinatonic.confetti:confetti:1.1.2' + implementation files('libs/WeatherView-2.0.3.aar') compileOnly project(":hiddenapi-stubs") } diff --git a/app/libs/WeatherView-2.0.3.aar b/app/libs/WeatherView-2.0.3.aar new file mode 100644 index 00000000..6da15dd9 Binary files /dev/null and b/app/libs/WeatherView-2.0.3.aar differ diff --git a/app/src/main/java/io/github/lsposed/manager/ui/activity/BaseActivity.java b/app/src/main/java/io/github/lsposed/manager/ui/activity/BaseActivity.java index 0b85cdc1..6143cf3b 100644 --- a/app/src/main/java/io/github/lsposed/manager/ui/activity/BaseActivity.java +++ b/app/src/main/java/io/github/lsposed/manager/ui/activity/BaseActivity.java @@ -149,7 +149,7 @@ public class BaseActivity extends AppCompatActivity { getWindow().setStatusBarColor(getThemedColor(R.attr.colorPrimaryDark)); } } else { - getWindow().setStatusBarColor(getThemedColor(android.R.attr.colorBackground)); + getWindow().setStatusBarColor(0); } if (!Objects.equals(theme, getTheme(this) + getCustomTheme() + preferences.getBoolean("md2", true))) { recreate(); diff --git a/app/src/main/java/io/github/lsposed/manager/ui/activity/MainActivity.java b/app/src/main/java/io/github/lsposed/manager/ui/activity/MainActivity.java index 30d3d0a1..078a47cf 100644 --- a/app/src/main/java/io/github/lsposed/manager/ui/activity/MainActivity.java +++ b/app/src/main/java/io/github/lsposed/manager/ui/activity/MainActivity.java @@ -2,10 +2,15 @@ package io.github.lsposed.manager.ui.activity; import android.annotation.SuppressLint; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.view.View; import androidx.core.content.ContextCompat; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; import com.bumptech.glide.Glide; import com.google.android.material.snackbar.Snackbar; @@ -20,6 +25,8 @@ import io.github.lsposed.manager.util.GlideHelper; import io.github.lsposed.manager.util.ModuleUtil; import io.github.lsposed.manager.util.NavUtil; import io.github.lsposed.manager.util.light.Light; +import name.mikanoshi.customiuizer.holidays.HolidayHelper; +import name.mikanoshi.customiuizer.utils.Helpers; public class MainActivity extends BaseActivity { ActivityMainBinding binding; @@ -30,6 +37,15 @@ public class MainActivity extends BaseActivity { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + WindowCompat.setDecorFitsSystemWindows(getWindow(), false); + ViewCompat.setOnApplyWindowInsetsListener(binding.nestedScrollView, (v, insets) -> { + Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime()); + v.setPadding(insets1.left, insets1.top, insets1.right, insets1.bottom); + return WindowInsetsCompat.CONSUMED; + }); + } + HolidayHelper.setup(this); binding.status.setOnClickListener(v -> { if (Constants.getXposedVersionCode() != -1) { new StatusDialogBuilder(this) @@ -51,7 +67,11 @@ public class MainActivity extends BaseActivity { if (installedXposedVersion != null) { binding.statusTitle.setText(String.format(Locale.US, "%s %s", getString(R.string.Activated), Constants.getXposedVariant())); if (!Constants.isPermissive()) { - binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.colorNormal)); + if (Helpers.currentHoliday == Helpers.Holidays.LUNARNEWYEAR) { + binding.status.setCardBackgroundColor(0xfff05654); + } else { + binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.colorNormal)); + } binding.statusIcon.setImageResource(R.drawable.ic_check_circle); binding.statusSummary.setText(String.format(Locale.US, "%s (%d)", installedXposedVersion, Constants.getXposedVersionCode())); } else { @@ -99,5 +119,18 @@ public class MainActivity extends BaseActivity { }); super.onResume(); binding.modulesSummary.setText(String.format(getString(R.string.ModulesDetail), ModuleUtil.getInstance().getEnabledModules().size())); + HolidayHelper.onResume(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + HolidayHelper.onDestroy(); + } + + @Override + protected void onPause() { + super.onPause(); + HolidayHelper.onPause(); } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java new file mode 100644 index 00000000..b48c595b --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java @@ -0,0 +1,29 @@ +package name.mikanoshi.customiuizer.holidays; + +import android.content.Context; + +import com.github.jinatonic.confetti.ConfettoGenerator; +import com.github.jinatonic.confetti.confetto.Confetto; +import com.github.matteobattilana.weather.PrecipType; +import com.github.matteobattilana.weather.confetti.ConfettoInfo; + +import java.util.Random; + +public class FlowerGenerator implements ConfettoGenerator { + private final ConfettoInfo confettoInfo; + private final Context context; + + public FlowerGenerator(Context ctx) { + super(); + this.context = ctx; + this.confettoInfo = new ConfettoInfo(PrecipType.SNOW); + } + + public Confetto generateConfetto(Random random) { + return new FlowerParticle(this.context, this.confettoInfo); + } + + public final ConfettoInfo getConfettoInfo() { + return this.confettoInfo; + } +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java new file mode 100644 index 00000000..f1193f25 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java @@ -0,0 +1,70 @@ +package name.mikanoshi.customiuizer.holidays; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.view.Surface; +import android.view.WindowManager; + +import com.github.jinatonic.confetti.confetto.Confetto; +import com.github.matteobattilana.weather.confetti.ConfettoInfo; + +import java.util.Random; + +import io.github.lsposed.manager.R; + +@SuppressWarnings("FieldCanBeLocal") +public class FlowerParticle extends Confetto { + private final ConfettoInfo confettoInfo; + private final Bitmap petal; + private float petalScale; + private final int[] petals = new int[]{R.drawable.confetti1, R.drawable.confetti1, R.drawable.confetti2, R.drawable.confetti2, R.drawable.confetti3, R.drawable.confetti3, R.drawable.petal}; + + FlowerParticle(Context context, ConfettoInfo confettoInfo) { + super(); + this.confettoInfo = confettoInfo; + petalScale = 0.6f - (float) Math.random() * 0.15f; + petal = BitmapFactory.decodeResource(context.getResources(), petals[new Random().nextInt(petals.length)]); + + int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); + if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) petalScale *= 1.5; + } + + public int getHeight() { + return 0; + } + + public int getWidth() { + return 0; + } + + public void reset() { + super.reset(); + } + + protected void configurePaint(Paint paint) { + super.configurePaint(paint); + paint.setColor(-1); + paint.setAntiAlias(true); + } + + protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { + switch (confettoInfo.getPrecipType()) { + case CLEAR: + break; + case SNOW: + matrix.postScale(petalScale, petalScale); + matrix.postRotate(rotation, petal.getWidth() / 2f, petal.getHeight() / 2f); + matrix.postTranslate(x, y); + canvas.drawBitmap(petal, matrix, paint); + break; + } + } + + public final ConfettoInfo getConfettoInfo() { + return this.confettoInfo; + } +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java new file mode 100644 index 00000000..98e89619 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java @@ -0,0 +1,119 @@ +package name.mikanoshi.customiuizer.holidays; + +import android.app.Activity; +import android.view.Surface; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RelativeLayout; + +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.github.jinatonic.confetti.ConfettiManager; +import com.github.jinatonic.confetti.ConfettoGenerator; +import com.github.matteobattilana.weather.PrecipType; +import com.github.matteobattilana.weather.WeatherView; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; + +import io.github.lsposed.manager.R; +import name.mikanoshi.customiuizer.utils.GravitySensor; +import name.mikanoshi.customiuizer.utils.Helpers; + +public class HolidayHelper { + + private static WeakReference weatherView; + private static WeakReference angleListener; + + public static void setWeatherGenerator(ConfettoGenerator generator) { + try { + ConfettiManager manager = weatherView.get().getConfettiManager(); + Field confettoGenerator = ConfettiManager.class.getDeclaredField("confettoGenerator"); + confettoGenerator.setAccessible(true); + confettoGenerator.set(manager, generator); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static void setup(Activity activity) { + Helpers.detectHoliday(); + + WeatherView view = activity.findViewById(R.id.weather_view); + ImageView header = activity.findViewById(R.id.holiday_header); + + view.setLayerType(View.LAYER_TYPE_HARDWARE, null); + weatherView = new WeakReference<>(view); + GravitySensor listener = null; + if (Helpers.currentHoliday == Helpers.Holidays.NEWYEAR) { + int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + view.setPrecipType(PrecipType.SNOW); + view.setSpeed(50); + view.setEmissionRate(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 8 : 4); + view.setFadeOutPercent(0.75f); + view.setAngle(0); + RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams(); + lp.height = activity.getResources().getDisplayMetrics().heightPixels / (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 2 : 3); + view.setLayoutParams(lp); + setWeatherGenerator(new SnowGenerator(activity)); + view.resetWeather(); + view.setVisibility(View.VISIBLE); + view.getConfettiManager().setRotationalVelocity(0, 45); + + listener = new GravitySensor(activity, view); + listener.setOrientation(rotation); + listener.setSpeed(50); + listener.start(); + + header.setImageResource(R.drawable.newyear_header); + header.setVisibility(View.VISIBLE); + } else if (Helpers.currentHoliday == Helpers.Holidays.LUNARNEWYEAR) { + int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + view.setPrecipType(PrecipType.SNOW); + view.setSpeed(35); + view.setEmissionRate(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 4 : 2); + view.setFadeOutPercent(0.75f); + view.setAngle(0); + CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) view.getLayoutParams(); + lp.height = activity.getResources().getDisplayMetrics().heightPixels / (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 3 : 4); + view.setLayoutParams(lp); + setWeatherGenerator(new FlowerGenerator(activity)); + view.resetWeather(); + view.setVisibility(View.VISIBLE); + view.getConfettiManager().setRotationalVelocity(0, 45); + + listener = new GravitySensor(activity, view); + listener.setOrientation(rotation); + listener.setSpeed(35); + listener.start(); + + header.setImageResource(R.drawable.lunar_newyear_header); + header.setVisibility(View.VISIBLE); + } else { + ((ViewGroup) view.getParent()).removeView(view); + ((ViewGroup) header.getParent()).removeView(header); + } + angleListener = new WeakReference<>(listener); + } + + public static void onPause() { + GravitySensor listener = angleListener.get(); + if (listener != null) listener.onPause(); + WeatherView view = weatherView.get(); + if (view != null) view.getConfettiManager().terminate(); + } + + public static void onResume() { + GravitySensor listener = angleListener.get(); + if (listener != null) listener.onResume(); + WeatherView view = weatherView.get(); + if (view != null) view.getConfettiManager().animate(); + } + + public static void onDestroy() { + GravitySensor listener = angleListener.get(); + if (listener != null) listener.stop(); + } + +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java new file mode 100644 index 00000000..4721d4ac --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java @@ -0,0 +1,29 @@ +package name.mikanoshi.customiuizer.holidays; + +import android.content.Context; + +import com.github.jinatonic.confetti.ConfettoGenerator; +import com.github.jinatonic.confetti.confetto.Confetto; +import com.github.matteobattilana.weather.PrecipType; +import com.github.matteobattilana.weather.confetti.ConfettoInfo; + +import java.util.Random; + +public class SnowGenerator implements ConfettoGenerator { + private final ConfettoInfo confettoInfo; + private final Context context; + + public SnowGenerator(Context ctx) { + super(); + this.context = ctx; + this.confettoInfo = new ConfettoInfo(PrecipType.SNOW); + } + + public Confetto generateConfetto(Random random) { + return new SnowParticle(this.context, this.confettoInfo); + } + + public final ConfettoInfo getConfettoInfo() { + return this.confettoInfo; + } +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java new file mode 100644 index 00000000..f7c4b818 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java @@ -0,0 +1,84 @@ +package name.mikanoshi.customiuizer.holidays; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; + +import com.github.jinatonic.confetti.confetto.Confetto; +import com.github.matteobattilana.weather.confetti.ConfettoInfo; + +import io.github.lsposed.manager.R; + +public class SnowParticle extends Confetto { + private Float prevX; + private Float prevY; + private final ConfettoInfo confettoInfo; + private final Bitmap snowflake; + private final float snowScale; + //private float rainStretch; + + SnowParticle(Context context, ConfettoInfo confettoInfo) { + super(); + this.confettoInfo = confettoInfo; + snowScale = 0.6f - (float) Math.random() * 0.3f; + //rainStretch = 1.5f + (float)Math.random() - 0.5f; + snowflake = BitmapFactory.decodeResource(context.getResources(), R.drawable.snowflake); + } + + public int getHeight() { + return 0; + } + + public int getWidth() { + return 0; + } + + public void reset() { + super.reset(); + this.prevX = null; + this.prevY = null; + } + + protected void configurePaint(Paint paint) { + super.configurePaint(paint); + paint.setColor(-1); + paint.setAntiAlias(true); + } + + protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { + if (prevX == null || prevY == null) { + prevX = x; + prevY = y; + } + + switch (confettoInfo.getPrecipType()) { + case CLEAR: + break; +// case RAIN: +// float dX = x - prevX; +// float dY = y - prevY; +// float x1 = prevX - dX * rainStretch; +// float y1 = prevY - dY * rainStretch; +// float x2 = x + dX * rainStretch; +// float y2 = y + dY * rainStretch; +// paint.setShader(new LinearGradient(x1, y1, x2, y2, new int[] { Color.TRANSPARENT, 0xb29aa3ad, 0xb29aa3ad, Color.TRANSPARENT }, new float[] { 0f, 0.45f, 0.55f, 1f }, Shader.TileMode.CLAMP)); +// canvas.drawLine(x1, y1, x2, y2, paint); +// break; + case SNOW: + matrix.postScale(snowScale, snowScale); + matrix.postRotate(rotation, snowflake.getWidth() / 2f, snowflake.getHeight() / 2f); + matrix.postTranslate(x, y); + canvas.drawBitmap(snowflake, matrix, paint); + break; + } + prevX = x; + prevY = y; + } + + public final ConfettoInfo getConfettoInfo() { + return this.confettoInfo; + } +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java new file mode 100644 index 00000000..d0f6c6e4 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java @@ -0,0 +1,102 @@ +package name.mikanoshi.customiuizer.utils; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.view.Surface; + +import com.github.matteobattilana.weather.WeatherView; + +public final class GravitySensor implements SensorEventListener { + private final SensorManager sensorManager; + private float[] magneticValues; + private float[] accelerometerValues; + private int orientation; + private int speed; + private boolean started; + private final Context context; + private final WeatherView weatherView; + + public GravitySensor(Context context, WeatherView weatherView) { + super(); + this.context = context; + this.weatherView = weatherView; + this.sensorManager = (SensorManager) this.context.getSystemService(Context.SENSOR_SERVICE); + } + + public void setOrientation(int orient) { + this.orientation = orient; + } + + public void setSpeed(int spd) { + this.speed = spd; + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + public void onSensorChanged(SensorEvent event) { + if (event == null || event.sensor == null) return; + switch (event.sensor.getType()) { + case 1: + this.accelerometerValues = event.values; + break; + case 2: + this.magneticValues = event.values; + break; + } + if (this.magneticValues == null || this.accelerometerValues == null) return; + + float[] rotationMatrix = new float[9]; + SensorManager.getRotationMatrix(rotationMatrix, null, this.accelerometerValues, this.magneticValues); + float[] remappedRotationMatrix = new float[9]; + SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRotationMatrix); + float[] orientationAngles = new float[3]; + SensorManager.getOrientation(remappedRotationMatrix, orientationAngles); + //double pitch = Math.toDegrees((double)orientationAngles[1]); + double roll = Math.toDegrees(orientationAngles[2]) + Math.random() * 20 - 10; + if (this.orientation == Surface.ROTATION_90) roll += 90; + else if (this.orientation == Surface.ROTATION_270) roll -= 90; + else if (this.orientation == Surface.ROTATION_180) roll += roll > 0 ? 180 : -180; + if (roll > 90) roll -= 180; + else if (roll < -90) roll += 180; + this.weatherView.setAngle((int) roll); + this.weatherView.setSpeed(this.speed + (int) Math.round(Math.random() * 20 - 10)); + } + + private void registerListener() { + this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(1), 2); + this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(2), 2); + } + + private void unregisterListener() { + this.sensorManager.unregisterListener(this); + } + + public final void start() { + this.started = true; + this.registerListener(); + } + + public final void stop() { + this.started = false; + this.unregisterListener(); + } + + public final void onResume() { + if (this.started) { + this.registerListener(); + } + } + + public final void onPause() { + this.unregisterListener(); + } + + public final Context getContext() { + return this.context; + } + +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java new file mode 100644 index 00000000..f7d7eed2 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -0,0 +1,25 @@ +package name.mikanoshi.customiuizer.utils; + +import java.util.Calendar; + +public class Helpers { + + public static Holidays currentHoliday = Holidays.NONE; + + public enum Holidays { + NONE, NEWYEAR, LUNARNEWYEAR + } + + public static void detectHoliday() { + currentHoliday = Holidays.NONE; + Calendar cal = Calendar.getInstance(); + int month = cal.get(Calendar.MONTH); + int monthDay = cal.get(Calendar.DAY_OF_MONTH); + //int year = cal.get(Calendar.YEAR); + + // Lunar NY + if ((month == 0 && monthDay > 15) || month == 1) currentHoliday = Holidays.LUNARNEWYEAR; + // NY + else if (month == 0 || month == 11) currentHoliday = Holidays.NEWYEAR; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-nodpi/confetti1.png b/app/src/main/res/drawable-nodpi/confetti1.png new file mode 100644 index 00000000..d34c62b5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/confetti1.png differ diff --git a/app/src/main/res/drawable-nodpi/confetti2.png b/app/src/main/res/drawable-nodpi/confetti2.png new file mode 100644 index 00000000..04f89873 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/confetti2.png differ diff --git a/app/src/main/res/drawable-nodpi/confetti3.png b/app/src/main/res/drawable-nodpi/confetti3.png new file mode 100644 index 00000000..4b3babc9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/confetti3.png differ diff --git a/app/src/main/res/drawable-nodpi/lunar_newyear_header.webp b/app/src/main/res/drawable-nodpi/lunar_newyear_header.webp new file mode 100644 index 00000000..74a61214 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/lunar_newyear_header.webp differ diff --git a/app/src/main/res/drawable-nodpi/newyear_header.webp b/app/src/main/res/drawable-nodpi/newyear_header.webp new file mode 100644 index 00000000..acf47c4c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/newyear_header.webp differ diff --git a/app/src/main/res/drawable-nodpi/petal.webp b/app/src/main/res/drawable-nodpi/petal.webp new file mode 100644 index 00000000..b8221bba Binary files /dev/null and b/app/src/main/res/drawable-nodpi/petal.webp differ diff --git a/app/src/main/res/drawable-nodpi/snowflake.webp b/app/src/main/res/drawable-nodpi/snowflake.webp new file mode 100644 index 00000000..ca4ed94a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/snowflake.webp differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index da28c627..f51b56d3 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,6 +5,27 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + - - + + \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 75338b86..7a6640c1 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1,209 +1,111 @@ -Про модифікацію -Активовано -Установити -Натисніть для встановлення LSPosed -Звіти -Модулі -%d модулі(в) увімкнено -Налаштування -Перейти на головну -Перейти вгору -Більше опцій -Готово -Показати всі -Вибрати програму -ЗНИЖКА -УВІМК. -Alt+ -Ctrl+ -delete -enter -Function+ -Meta+ -Shift+ -пробіл -Sym+ -Menu+ -Введіть пошуковий запит… -Очистити запит -Пошуковий запит -Пошук -Наіслати запит -Голосовий пошук -Поділитися: -Поділитися через додаток %s -Згорнути -https://github.com/LSPosed/LSPosed/ -Вихідний код -Колір акценту -System Framework -Android %2$s (%1$s, API %3$d) -Ця програма припинила роботу, будь ласка, переконайтесь, що завантажили її з офіційного джерела. -Запустити -LSPosed Manager -com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior -com.google.android.material.bottomsheet.BottomSheetBehavior -Набрано символів %1$d з %2$d -Перевищено ліміт символів %1$d з %2$d -%1$d/%2$d -Chip text -Очистити текст -Вибрати колір -Колір %1$d -Вибрано колір: %1$d -Кольоровий ActionBar -Помилка оптимізації або повернене значення порожнє -Помилка оптимізації: -Повторна оптимізація -Оптимізація… -Скопіювати -Посилання скопійовано в буфер обміну -Готово! -Не показувати знову -Увімкнути модуль -Помилка -Додатково -Показати спадне меню -com.google.android.material.transformation.FabTransformationScrimBehavior -com.google.android.material.transformation.FabTransformationSheetBehavior -Не вдалося зберегти список областей -Копіювати посилання -Відкрити у веб-переглядачі -Надіслати посилання -Слідувати системі -http://t.me/LSPosed -com.google.android.material.behavior.HideBottomViewOnScrollBehavior -Значок діалогового вікна -Інформація -Обережно! -Вкладка -Завантаження… -Звіт порожній. -"Не вдається прочитати звіт: " -Не вдалося очистити звіт: -Звіт успішно очищено. -Не вдалося зберегти: -LSPosed наразі не встановлений або не активний. -Material Design 2 -Кінець діапазону, -Початок діапазону, -Очистити звіт зараз -Перезавантажити -Зберегти -Надіслати -Створити резервну копію -Створення резервної копії… -Відновити -Ігри -Модулі -Системні програми -Сортування... -Інформація про програму -Модуль %s вимкнено, оскільки жодна програма не вибрана. -(опису не надано) -Модуль LSPosed ще не активований -%s було встановлено, але ще не активовано -Цей модуль не надає інтерфейсу користувача -Налаштування модуля -Видалити -Переглянути в Play Store -Нове сповіщення -Видалити %1$s -Більше %1$d нових сповіщень -%1$d%2$s -Змінити на наступний місяць -Змінити на попередній місяць -Поточний вибір: %1$s -@android:string/cancel -@android:string/ok -%1$s -Виберіть дату -Вибрана дата -Стовпець днів: %1$s -Недійсний формат. -Приклад: %1$s -Використання: %1$s -Недійсний діапазон. -Перейти до року %1$s -Не належить діапазону: %1$s -Дата початку – %1$s -%1$s – Кінцева дата -%1$s – %2$s -Виберіть діапазон дат -Дата початку - дата закінчення -Зберегти -Дата -Дата закінчення -Дата початку -д -м -р -Перемкнутись на режим введення календаря -Торкніться, щоб перейти до вибору дня -Перемкнутись до режиму введення тексту -Торкніться, щоб перейти до вибору року -Детальні звіти -Звіти модулів -Модулі -Цей модуль не визначає потрібну йому версію LSP. -Ви не вибрали жодної програми. Продовжити? -Ви не вибрали жодної програми. Вибрати рекомендовані програми? -Не встановлено -"Це звіт LSPosed Framework та модулів, якщо вам потрібен Android logcat, ви можете спробувати наш модуль Magisk Log Catcher" -Не налаштовано -OK -Версія LSPosed Manager і LSPosed Core не узгоджуються. Будь ласка, встановіть відповідну версію. -Показувати пароль -M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z -M2,4.27 L19.73,22 L22.27,19.46 L4.54,1.73 L4.54,1 L23,1 L23,23 L1,23 L1,4.27 Z -M2,4.27 L2,4.27 L4.54,1.73 L4.54,1.73 L4.54,1 L23,1 L23,23 L1,23 L1,4.27 Z -M3.27,4.27 L19.74,20.74 -Вимкнути детальні звіти -\"%1$s\": скопійовано в буфер обміну. -Основний колір -Використовувати чисто чорну темну тему -Рекомендовано -Прокрутити донизу -Прокрутити догори -Пошук -УВАГА: Статус SELinux не Enforcing! Шкідливі програми, які користуються цим, зможуть повністю керувати вашим пристроєм і спричинити шкоду вашим даним. -Статус SELinux не Enforcing! -Резервне копіювання -Резервне копіювання і відновлення -Резервне копіювання або відновлення списку модулів та списків областей. -Не вдалося зробити резервну копію -Резервне копіювання закінчено! -Резервне копіювання… -Увімкнути хуки ресурсів -УВАГА: Хуки ресурсів застаріли -Framework -Тема -Відновлення -Не вдалося відновити -Відновлення закінчено! -Відновлення… -Тема -Темна -Світла -Варіант -Сортувати за часом встановлення -Сортувати за часом встановлення (зворотній) -Сортувати за назвою програми -Сортувати за назвою програми (зворотній) -Сортувати за назвою пакета -Сортувати за назвою пакету (зворотній) -Сортувати за часом оновлення -Сортувати за часом оновлення (зворотній) -999+ -%1$s, %2$s -Прозорий рядок стану -Рекомендовано -Вибрати рекомендовані програми? -ВИМКНЕНО -УВІМКНЕНО -Цей модуль не можна завантажити, оскільки він встановлений на SD-карті, перенесіть його у внутрішню пам’ять -Цей модуль був створений для версії LSP %1$d, але через несумісні зміни у версії %2$d його було вимкнено -Цей модуль вимагає новішої версії LSP (%d), тому його неможливо активувати -Модуль LSPosed оновлено + Про модифікацію + Активовано + Установити + Натисніть для встановлення LSPosed + Звіти + Модулі + %d модулі(в) увімкнено + Налаштування + https://github.com/LSPosed/LSPosed/ + Вихідний код + Колір акценту + System Framework + Android %2$s (%1$s, API %3$d) + Ця програма припинила роботу, будь ласка, переконайтесь, що завантажили її з офіційного джерела. + Запустити + LSPosed Manager + com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior + Кольоровий ActionBar + Помилка оптимізації або повернене значення порожнє + Помилка оптимізації: + Повторна оптимізація + Оптимізація… + Посилання скопійовано в буфер обміну + Не показувати знову + Увімкнути модуль + Не вдалося зберегти список областей + Слідувати системі + http://t.me/LSPosed + Інформація + Обережно! + Завантаження… + Звіт порожній. + "Не вдається прочитати звіт: " + Не вдалося очистити звіт: + Звіт успішно очищено. + Не вдалося зберегти: + LSPosed наразі не встановлений або не активний. + Material Design 2 + Очистити звіт зараз + Перезавантажити + Зберегти + Надіслати + Створити резервну копію + Створення резервної копії… + Відновити + Ігри + Модулі + Системні програми + Сортування... + Інформація про програму + Модуль %s вимкнено, оскільки жодна програма не вибрана. + (опису не надано) + Модуль LSPosed ще не активований + %s було встановлено, але ще не активовано + Цей модуль не надає інтерфейсу користувача + Налаштування модуля + Видалити + Переглянути в Play Store + Детальні звіти + Звіти модулів + Модулі + Цей модуль не визначає потрібну йому версію LSP. + Ви не вибрали жодної програми. Продовжити? + Ви не вибрали жодної програми. Вибрати рекомендовані програми? + Не встановлено + "Це звіт LSPosed Framework та модулів, якщо вам потрібен Android logcat, ви можете спробувати наш модуль Magisk Log Catcher" + OK + Версія LSPosed Manager і LSPosed Core не узгоджуються. Будь ласка, встановіть відповідну версію. + Вимкнути детальні звіти + Основний колір + Використовувати чисто чорну темну тему + Рекомендовано + Прокрутити донизу + Прокрутити догори + УВАГА: Статус SELinux не Enforcing! Шкідливі програми, які користуються цим, зможуть повністю керувати вашим пристроєм і спричинити шкоду вашим даним. + Статус SELinux не Enforcing! + Резервне копіювання + Резервне копіювання і відновлення + Резервне копіювання або відновлення списку модулів та списків областей. + Не вдалося зробити резервну копію + Резервне копіювання закінчено! + Резервне копіювання… + Увімкнути хуки ресурсів + УВАГА: Хуки ресурсів застаріли + Framework + Тема + Відновлення + Не вдалося відновити + Відновлення закінчено! + Відновлення… + Тема + Темна + Світла + Варіант + Сортувати за часом встановлення + Сортувати за часом встановлення (зворотній) + Сортувати за назвою програми + Сортувати за назвою програми (зворотній) + Сортувати за назвою пакета + Сортувати за назвою пакету (зворотній) + Сортувати за часом оновлення + Сортувати за часом оновлення (зворотній) + Прозорий рядок стану + Рекомендовано + Вибрати рекомендовані програми? + Цей модуль не можна завантажити, оскільки він встановлений на SD-карті, перенесіть його у внутрішню пам’ять + Цей модуль був створений для версії LSP %1$d, але через несумісні зміни у версії %2$d його було вимкнено + Цей модуль вимагає новішої версії LSP (%d), тому його неможливо активувати + Модуль LSPosed оновлено diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ee78107a..840a84d0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -77,7 +77,6 @@ 优化中… - 完成! 禁用详细日志 无法读取日志: \n diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 8f673a1d..3b91f58a 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -75,7 +75,6 @@ 優化中… - 完成! 禁用詳細日誌 無法讀取日誌: \n diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 73f7e2ef..ec3460fb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -8,7 +8,7 @@ 日誌 設定 關於 - + 傳送 儲存 @@ -80,7 +80,6 @@ Android %2$s (%1$s, API %3$d) 這裡是 LSPosed 框架和模組的日誌\n若您需要 Android 的 logcat,您可以嘗試我們 Log Catcher 的 Magisk 模組 - Done! 最佳化中…