help page

This commit is contained in:
Tungstend 2023-07-28 07:41:27 +08:00
parent 24839ee46a
commit 1766c34e10
9 changed files with 508 additions and 2 deletions

View File

@ -0,0 +1,65 @@
package com.tungsten.fcl.ui.setting;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tungsten.fcl.R;
import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import java.util.ArrayList;
public class ArticleAdapter extends FCLAdapter {
private final ArrayList<DocIndex.Item> list;
public ArticleAdapter(Context context, ArrayList<DocIndex.Item> list) {
super(context);
this.list = list;
}
private static class ViewHolder {
FCLLinearLayout parent;
FCLTextView title;
FCLTextView subtitle;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
view = LayoutInflater.from(getContext()).inflate(R.layout.item_article, null);
viewHolder.parent = view.findViewById(R.id.parent);
viewHolder.title = view.findViewById(R.id.title);
viewHolder.subtitle = view.findViewById(R.id.subtitle);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
DocIndex.Item item = list.get(i);
viewHolder.parent.setOnClickListener(v -> {
Uri uri = Uri.parse("https://fcl-team.github.io/pages/documentation.html?path=" + item.getPath());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
getContext().startActivity(intent);
});
viewHolder.title.setText(item.getTitle());
viewHolder.subtitle.setText(item.getSubtitle());
return view;
}
}

View File

@ -0,0 +1,82 @@
package com.tungsten.fcl.ui.setting;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import com.tungsten.fcl.R;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import com.tungsten.fcllibrary.util.ConvertUtils;
import java.util.ArrayList;
public class DocCategoryAdapter extends FCLAdapter {
private final ArrayList<DocIndex> list;
private final ObjectProperty<DocIndex> selectedIndexProperty = new SimpleObjectProperty<>(null);
public ObjectProperty<DocIndex> selectedIndexProperty() {
return selectedIndexProperty;
}
public DocIndex getSelectedIndex() {
return selectedIndexProperty.get();
}
public DocCategoryAdapter(Context context, ArrayList<DocIndex> list) {
super(context);
this.list = list;
if (list.size() > 0) {
selectedIndexProperty.set(list.get(0));
}
selectedIndexProperty.addListener(invalidate -> notifyDataSetChanged());
}
private static class ViewHolder {
FCLLinearLayout parent;
FCLTextView name;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
view = new FCLLinearLayout(getContext());
viewHolder.parent = new FCLLinearLayout(getContext());
viewHolder.name = new FCLTextView(getContext());
((FCLLinearLayout) view).addView(viewHolder.parent, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
int padding = ConvertUtils.dip2px(getContext(), 10);
viewHolder.parent.setPadding(padding, padding, padding, padding);
viewHolder.parent.setBackground(getContext().getDrawable(R.drawable.bg_container_transparent_clickable));
viewHolder.parent.addView(viewHolder.name, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
viewHolder.name.setSingleLine(true);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
DocIndex index = list.get(i);
viewHolder.parent.setBackground(index == getSelectedIndex() ? getContext().getDrawable(R.drawable.bg_container_transparent_selected) : getContext().getDrawable(R.drawable.bg_container_transparent_clickable));
viewHolder.parent.setOnClickListener(v -> selectedIndexProperty.set(index));
viewHolder.name.setText(index.getDisplayName(getContext()));
return view;
}
}

View File

@ -0,0 +1,110 @@
package com.tungsten.fcl.ui.setting;
import android.content.Context;
import com.tungsten.fcllibrary.util.LocaleUtils;
import java.util.ArrayList;
public class DocIndex {
private final String category;
private final boolean visible;
private final ArrayList<DisplayName> displayName;
private final ArrayList<Item> item;
public DocIndex(String category, boolean visible, ArrayList<DisplayName> displayName, ArrayList<Item> item) {
this.category = category;
this.visible = visible;
this.displayName = displayName;
this.item = item;
}
public String getCategory() {
return category;
}
public boolean isVisible() {
return visible;
}
public ArrayList<DisplayName> getDisplayName() {
return displayName;
}
public ArrayList<Item> getItem() {
return item;
}
public String getDisplayName(Context context) {
for (DisplayName name : displayName) {
if (name.getLang().equals(LocaleUtils.getLocale(LocaleUtils.getLanguage(context)).toString())) {
return name.getName();
}
}
return category;
}
public static class DisplayName {
private final String lang;
private final String name;
public DisplayName(String lang, String name) {
this.lang = lang;
this.name = name;
}
public String getLang() {
return lang;
}
public String getName() {
return name;
}
}
public static class Item {
private final String lang;
private final String title;
private final String subtitle;
private final String author;
private final String path;
public Item(String lang, String title, String subtitle, String author, String path) {
this.lang = lang;
this.title = title;
this.subtitle = subtitle;
this.author = author;
this.path = path;
}
public String getLang() {
return lang;
}
public String getTitle() {
return title;
}
public String getSubtitle() {
return subtitle;
}
public String getAuthor() {
return author;
}
public String getPath() {
return path;
}
public boolean isVisible(Context context) {
return lang.equals(LocaleUtils.getLocale(LocaleUtils.getLanguage(context)).toString());
}
}
}

View File

@ -1,18 +1,118 @@
package com.tungsten.fcl.ui.setting;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.ListView;
import com.google.gson.reflect.TypeToken;
import com.tungsten.fcl.R;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.gson.JsonUtils;
import com.tungsten.fclcore.util.io.NetworkUtils;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLImageButton;
import com.tungsten.fcllibrary.component.view.FCLProgressBar;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
public class HelpPage extends FCLCommonPage {
import java.util.ArrayList;
import java.util.stream.Collectors;
public class HelpPage extends FCLCommonPage implements View.OnClickListener {
public static final String DOC_INDEX_URL = "https://raw.githubusercontent.com/FCL-Team/FCL-Docs/main/index.json";
private ListView categoryListView;
private ListView listView;
private FCLProgressBar progressBar;
private FCLImageButton retry;
private FCLButton refresh;
private FCLButton website;
public HelpPage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
}
@Override
public void onCreate() {
super.onCreate();
categoryListView = findViewById(R.id.category_list);
listView = findViewById(R.id.list);
progressBar = findViewById(R.id.progress);
retry = findViewById(R.id.retry);
retry.setOnClickListener(this);
refresh = findViewById(R.id.refresh);
refresh.setOnClickListener(this);
website = findViewById(R.id.website);
website.setOnClickListener(this);
refresh();
}
private void setLoading(boolean loading, boolean... arg) {
Schedulers.androidUIThread().execute(() -> {
refresh.setEnabled(!loading);
retry.setEnabled(!loading);
progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
if (loading) {
retry.setVisibility(View.GONE);
categoryListView.setVisibility(View.GONE);
listView.setVisibility(View.GONE);
} else {
if (arg.length > 0) {
boolean success = arg[0];
retry.setVisibility(success ? View.GONE : View.VISIBLE);
categoryListView.setVisibility(success ? View.VISIBLE : View.GONE);
listView.setVisibility(success ? View.VISIBLE : View.GONE);
}
}
});
}
private void refresh() {
setLoading(true);
Task.supplyAsync(() -> {
String res = NetworkUtils.doGet(NetworkUtils.toURL(DOC_INDEX_URL));
return JsonUtils.GSON.fromJson(res, new TypeToken<ArrayList<DocIndex>>(){}.getType());
}).thenAcceptAsync(Schedulers.androidUIThread(), res -> {
ArrayList<DocIndex> indexes = (ArrayList<DocIndex>) res;
DocCategoryAdapter adapter = new DocCategoryAdapter(getContext(), indexes);
categoryListView.setAdapter(adapter);
showArticles(adapter.getSelectedIndex());
adapter.selectedIndexProperty().addListener(i -> showArticles(adapter.getSelectedIndex()));
}).whenComplete(Schedulers.androidUIThread(), e -> setLoading(false, e == null)).start();
}
private void showArticles(DocIndex index) {
Schedulers.androidUIThread().execute(() -> {
ArrayList<DocIndex.Item> items = new ArrayList<>();
if (index != null) {
items = (ArrayList<DocIndex.Item>) index.getItem().stream().filter(it -> it.isVisible(getContext())).collect(Collectors.toList());
}
ArticleAdapter adapter = new ArticleAdapter(getContext(), items);
listView.setAdapter(adapter);
});
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void onClick(View v) {
if (v == retry || v == refresh) {
refresh();
}
if (v == website) {
Uri uri = Uri.parse("https://fcl-team.github.io/pages/documentation.html");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
getContext().startActivity(intent);
}
}
}

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/parent"
android:layout_marginBottom="10dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:background="@drawable/bg_container_white_clickable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:auto_linear_background_tint="true">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:id="@+id/title"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:id="@+id/subtitle"
android:singleLine="true"
app:auto_text_tint="true"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_jump_24"
android:layout_gravity="center"
app:auto_src_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/ui_bg_color"
android:paddingStart="10dp"
android:paddingEnd="10dp"
@ -7,4 +8,93 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/left"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/help_category"
android:textSize="11sp" />
<View
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:id="@+id/category_list"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
android:id="@+id/refresh"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_refresh"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
android:id="@+id/website"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/help_website"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
app:layout_constraintStart_toEndOf="@+id/left"
app:layout_constraintEnd_toEndOf="parent">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:id="@+id/retry"
android:src="@drawable/ic_baseline_refresh_24"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -362,6 +362,8 @@
<string name="game_crash_title">游戏意外退出</string>
<string name="help">帮助</string>
<string name="help_category">类别</string>
<string name="help_website">网站</string>
<string name="input_hint_not_empty">必填</string>
<string name="input_hint_optional">选填</string>

View File

@ -375,6 +375,8 @@
<string name="game_crash_title">Game Crashed</string>
<string name="help">Help</string>
<string name="help_category">Category</string>
<string name="help_website">Website</string>
<string name="input_hint_not_empty">Required</string>
<string name="input_hint_optional">Optional</string>

View File

@ -49,7 +49,7 @@ public class LocaleUtils {
return context.createConfigurationContext(configuration);
}
private static Locale getLocale(int lang) {
public static Locale getLocale(int lang) {
switch (lang) {
case 1:
return Locale.ENGLISH;