Friendly error page for web panel

This commit is contained in:
utkabobr
2025-04-03 19:24:41 +03:00
parent e1fe683154
commit 6bb8926fb7
8 changed files with 115 additions and 37 deletions
@@ -370,14 +370,15 @@ public class SetupActivity extends AppCompatActivity {
backgroundView.setEGLContextClientVersion(3);
backgroundView.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
backgroundModel = new GLModel();
backgroundModel.initBackgroundTriangles();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
glViewport(0, 0, width, height);
if (backgroundModel == null) {
backgroundModel = new GLModel();
backgroundModel.initBackgroundTriangles();
}
}
private float time;
@@ -11,7 +11,11 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import ru.ytkab0bp.slicebeam.BuildConfig;
public class AppBoot {
private final static String TAG = "boot";
static ExecutorService executor = Executors.newCachedThreadPool();
static List<BootTask> tasks;
static List<Runnable> pendingMain = new ArrayList<>();
@@ -49,7 +53,9 @@ public class AppBoot {
pendingMain.removeAll(clone);
}
}
Log.d("boot", "Boot in " + (System.currentTimeMillis() - start) + "ms");
if (BuildConfig.DEBUG) {
Log.d(TAG, "Boot in " + (System.currentTimeMillis() - start) + "ms");
}
tryShutdown();
} catch (InterruptedException e) {
throw new RuntimeException(e);
@@ -70,34 +76,29 @@ public class AppBoot {
private static void tryRunTask(BootTask task, boolean fromMain, boolean isContinue) {
if (checkDependencies(task.dependencies)) {
Runnable r = () -> {
try {
task.run.run();
} catch (Exception e) {
Log.e(TAG, "Error while executing boot task", e);
}
completed.put(task.index, true);
if (BuildConfig.DEBUG) {
Log.d(TAG, "Finish " + task);
}
if (!task.nonCritical) {
latch.countDown();
} else {
tryShutdown();
}
if (!isContinue) {
continueTasks(fromMain);
}
};
if (task.workerThread) {
executor.submit(() -> {
task.run.run();
completed.put(task.index, true);
if (!task.nonCritical) {
latch.countDown();
} else {
tryShutdown();
}
if (!isContinue) {
continueTasks(fromMain);
}
});
executor.submit(r);
} else {
Runnable r = () -> {
task.run.run();
completed.put(task.index, true);
if (!task.nonCritical) {
latch.countDown();
} else {
tryShutdown();
}
if (!isContinue) {
continueTasks(fromMain);
}
};
if (fromMain) {
r.run();
} else {
@@ -6,6 +6,7 @@ import org.json.JSONObject;
import ru.ytkab0bp.slicebeam.BeamServerData;
import ru.ytkab0bp.slicebeam.SliceBeam;
import ru.ytkab0bp.slicebeam.utils.Prefs;
import ru.ytkab0bp.slicebeam.utils.ViewUtils;
public class BeamServerDataTask extends BootTask {
public BeamServerDataTask() {
@@ -16,7 +17,7 @@ public class BeamServerDataTask extends BootTask {
throw new RuntimeException(e);
}
if (System.currentTimeMillis() - Prefs.getLastCheckedInfo() >= 86400000L) {
BeamServerData.load();
ViewUtils.postOnMainThread(BeamServerData::load);
}
});
onWorker();
@@ -1,18 +1,30 @@
package ru.ytkab0bp.slicebeam.fragment;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Process;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.dynamicanimation.animation.FloatValueHolder;
import androidx.dynamicanimation.animation.SpringAnimation;
@@ -105,6 +117,10 @@ public class BedFragment extends Fragment {
private BedSwipeDownLayout swipeDownLayout;
private WebView panelWebView;
private LinearLayout panelWebViewError;
private ImageView webViewErrIcon;
private TextView webViewErrDescription;
private ProgressBar webViewProgressBar;
private static String tempFileName;
private static File tempExportingFile;
@@ -228,7 +244,15 @@ public class BedFragment extends Fragment {
if (!host.startsWith("http://")) {
host = "http://" + host;
}
webViewProgressBar.animate().alpha(1).setDuration(150).start();
panelWebView.setAlpha(0f);
panelWebView.loadUrl(host);
panelWebViewError.animate().alpha(0).setDuration(150).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
panelWebViewError.setVisibility(View.GONE);
}
}).start();
}
}
@@ -272,6 +296,44 @@ public class BedFragment extends Fragment {
swipeDownLayout = new BedSwipeDownLayout(ctx);
panelWebView = new WebView(ctx);
panelWebView.getSettings().setJavaScriptEnabled(true);
panelWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
webViewErrDescription.setText(description);
panelWebViewError.setVisibility(View.VISIBLE);
panelWebViewError.setAlpha(0f);
panelWebViewError.animate().alpha(1).setDuration(150).setListener(null).start();
webViewProgressBar.animate().alpha(0).setDuration(150).start();
}
@Override
public void onPageFinished(WebView view, String url) {
panelWebView.animate().alpha(0).setDuration(150).start();
webViewProgressBar.animate().alpha(0).setDuration(150).start();
}
});
FrameLayout wfl = new FrameLayout(ctx);
wfl.addView(panelWebView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
panelWebViewError = new LinearLayout(ctx);
panelWebViewError.setVisibility(View.GONE);
panelWebViewError.setOrientation(LinearLayout.VERTICAL);
panelWebViewError.setGravity(Gravity.CENTER);
panelWebViewError.setPadding(ViewUtils.dp(12), ViewUtils.dp(12), ViewUtils.dp(12), ViewUtils.dp(12));
webViewErrIcon = new ImageView(ctx);
webViewErrIcon.setImageResource(R.drawable.globe_cross_outline_28);
panelWebViewError.addView(webViewErrIcon, new LinearLayout.LayoutParams(ViewUtils.dp(28), ViewUtils.dp(28)) {{
bottomMargin = ViewUtils.dp(8);
}});
webViewErrDescription = new TextView(ctx);
webViewErrDescription.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
webViewErrDescription.setGravity(Gravity.CENTER);
panelWebViewError.addView(webViewErrDescription);
wfl.addView(panelWebViewError, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
webViewProgressBar = new ProgressBar(ctx);
webViewProgressBar.setAlpha(0f);
wfl.addView(webViewProgressBar, new FrameLayout.LayoutParams(ViewUtils.dp(36), ViewUtils.dp(36), Gravity.CENTER));
if (portrait) {
LinearLayout inner = new LinearLayout(ctx);
@@ -280,10 +342,10 @@ public class BedFragment extends Fragment {
inner.addView(glView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
swipeDownLayout.addView(inner);
swipeDownLayout.addView(panelWebView);
swipeDownLayout.addView(wfl);
} else {
swipeDownLayout.addView(glView);
swipeDownLayout.addView(panelWebView);
swipeDownLayout.addView(wfl);
ll.addView(swipeDownLayout, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1f));
}
@@ -536,6 +598,9 @@ public class BedFragment extends Fragment {
public void onApplyTheme() {
super.onApplyTheme();
webViewErrIcon.setImageTintList(ColorStateList.valueOf(ThemesRepo.getColor(android.R.attr.textColorSecondary)));
webViewErrDescription.setTextColor(ThemesRepo.getColor(android.R.attr.textColorSecondary));
webViewProgressBar.setIndeterminateTintList(ColorStateList.valueOf(ThemesRepo.getColor(android.R.attr.textColorSecondary)));
menuView.setBackgroundColor(ThemesRepo.getColor(android.R.attr.windowBackground));
for (int i = 0; i < MenuCategory.values().length; i++) {
if (i != currentMenuSlot) {
+1 -1
View File
@@ -820,7 +820,7 @@ extern "C" {
JNIEXPORT jboolean JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1is_1big_1object(JNIEnv* env, jclass, jlong ptr, jint i) {
ModelRef* model = (ModelRef*) (intptr_t) ptr;
ModelObject* obj = model->model.objects[i];
return obj->volumes.size() == 1 && obj->volumes.front()->mesh().its.indices.size() >= 100000;
return obj->volumes.size() == 1 && obj->volumes.front()->mesh().its.indices.size() >= 500000;
}
JNIEXPORT jint JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1get_1extruder(JNIEnv* env, jclass, jlong ptr, jint i) {
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M12.119,4.173a10.017,10.017 0,0 0,-6.835 4.92h4.58a20.109,20.109 0,0 1,2.255 -4.92ZM11.418,11.093h6.004a1,1 0,0 0,0.933 -1.36c-0.576,-1.922 -1.474,-3.927 -2.416,-5.55a10.024,10.024 0,0 1,7.41 6.231l0.012,0.035a1,1 0,1 0,1.87 -0.71l-0.016,-0.042c-1.73,-4.503 -6.095,-7.701 -11.21,-7.701C7.375,1.996 2,7.37 2,14c0,5.126 3.212,9.499 7.73,11.22a1,1 0,0 0,0.712 -1.868,10.04 10.04,0 0,1 -5.158,-4.445L9.5,18.907a1,1 0,1 0,0 -2L4.429,16.907A10.005,10.005 0,0 1,4 14c0,-1.011 0.15,-1.987 0.429,-2.907h4.95a17.64,17.64 0,0 0,-0.271 2.373l-0.004,0.083a1.192,1.192 0,0 0,0.003 0.145,1 1,0 1,0 1.997,-0.107l0.002,-0.029c0.039,-0.852 0.148,-1.675 0.312,-2.465ZM14.036,4.893a25.223,25.223 0,0 1,1.999 4.2h-4.071a18.207,18.207 0,0 1,2.072 -4.2ZM19.5,26.5a7,7 0,1 0,0 -14,7 7,0 0,0 0,14ZM22.957,17.457a1,1 0,0 0,-1.414 -1.414L19.5,18.086l-2.043,-2.043a1,1 0,0 0,-1.414 1.414l2.043,2.043 -2.043,2.043a1,1 0,0 0,1.414 1.414l2.043,-2.043 2.043,2.043a1,1 0,0 0,1.414 -1.414L20.914,19.5l2.043,-2.043Z"
android:fillColor="#000"
android:fillType="evenOdd"/>
</vector>
+1 -1
View File
@@ -13,7 +13,7 @@
<string name="MenuFileOpenFileLoaded">Файл загружен.</string>
<string name="MenuFileOpenFileFailed">Не удалось открыть модель</string>
<string name="MenuFileOpenFileFailedNullName">Не удалось определить имя файла.</string>
<string name="MenuFileOpenFileBigObject">Файл содержит более 100к треугольников. Нарезка может быть очень медленной.</string>
<string name="MenuFileOpenFileBigObject">Файл содержит более 500к треугольников. Нарезка может быть медленной.</string>
<string name="MenuFileOpenFileLoading">Загрузка файла…</string>
<string name="MenuFileDelete">Убрать модель</string>
<string name="MenuFileCalibrations">Калибров.</string>
+1 -1
View File
@@ -14,7 +14,7 @@
<string name="MenuFileOpenFileLoaded">File loaded.</string>
<string name="MenuFileOpenFileFailed">Failed to open model</string>
<string name="MenuFileOpenFileFailedNullName">Failed to resolve file name.</string>
<string name="MenuFileOpenFileBigObject">File has more than 100k triangles. Processing could be really slow.</string>
<string name="MenuFileOpenFileBigObject">File has more than 500k triangles. Processing could be slow.</string>
<string name="MenuFileOpenFileLoading">Loading file…</string>
<string name="MenuFileDelete">Remove model</string>
<string name="MenuFileCalibrations">Calibrat.</string>