Skip to content
This repository was archived by the owner on Mar 12, 2026. It is now read-only.

Commit c0424fb

Browse files
authored
Merge pull request #53 from l3ger0j/master-fourth-path
Master fourth path
2 parents 7875a10 + 93e347d commit c0424fb

File tree

8 files changed

+122
-171
lines changed

8 files changed

+122
-171
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ android {
1010
applicationId "org.qp.android"
1111
minSdk 26
1212
targetSdk 34
13-
versionCode 202503
14-
versionName "3.25.3"
13+
versionCode 202504
14+
versionName "3.25.4"
1515
resourceConfigurations += ['en', 'ru']
1616
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1717
externalNativeBuild {

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns:android="http://schemas.android.com/apk/res/android"
44
xmlns:tools="http://schemas.android.com/tools">
55

6+
<uses-permission android:name="android.permission.BLUETOOTH" />
67
<uses-permission android:name="android.permission.INTERNET" />
78
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
89
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

app/src/main/java/org/qp/android/model/repository/LocalGame.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.qp.android.model.repository;
22

3+
import static org.qp.android.helpers.utils.DirUtil.MOD_DIR_NAME;
34
import static org.qp.android.helpers.utils.FileUtil.documentWrap;
45
import static org.qp.android.helpers.utils.FileUtil.findOrCreateFile;
56
import static org.qp.android.helpers.utils.FileUtil.forceCreateFile;
@@ -149,6 +150,20 @@ public boolean searchAndWriteFileInfo(DocumentFile rootDir, GameData data) {
149150
}
150151
});
151152

153+
var modDir = fromRelPath(context, MOD_DIR_NAME, rootDir);
154+
if (isWritableDir(context, modDir)) {
155+
var modFiles = modDir.listFiles();
156+
if (modFiles != null || modFiles.length != 0) {
157+
Arrays.stream(modFiles).forEach(d -> {
158+
var dirExtension = documentWrap(d).getExtension();
159+
var lcName = dirExtension.toLowerCase(Locale.ROOT);
160+
if (lcName.endsWith("qsp") || lcName.endsWith("gam")) {
161+
gameFiles.add(d.getUri());
162+
}
163+
});
164+
}
165+
}
166+
152167
if (gameFiles.isEmpty()) {
153168
var allFiles = DocumentFileUtils.search(
154169
rootDir,

app/src/main/java/org/qp/android/model/service/HtmlProcessor.java

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.qp.android.model.service;
22

33
import static org.qp.android.helpers.utils.Base64Util.encodeBase64;
4-
import static org.qp.android.helpers.utils.FileUtil.fromRelPath;
54
import static org.qp.android.helpers.utils.StringUtil.isNotEmpty;
65
import static org.qp.android.helpers.utils.StringUtil.isNullOrEmpty;
76

@@ -17,7 +16,6 @@
1716
import org.qp.android.ui.settings.SettingsController;
1817

1918
import java.util.ArrayList;
20-
import java.util.concurrent.CompletableFuture;
2119
import java.util.concurrent.ExecutorService;
2220
import java.util.concurrent.Executors;
2321
import java.util.regex.Pattern;
@@ -176,64 +174,35 @@ private String lineBreaksInHTML(@NonNull String s) {
176174

177175
private void handleImagesInHtml(@NonNull Context context,
178176
@NonNull Element documentBody) {
179-
var dynBlackList = new ArrayList<String>();
180-
documentBody.select("a").forEach(element -> {
181-
if (element.attr("href").contains("exec:")) {
182-
dynBlackList.add(element.select("img").attr("src"));
183-
}
184-
});
177+
if (controller.isUseFullscreenImages) {
178+
var dynBlackList = new ArrayList<String>();
179+
documentBody.select("a").forEach(element -> {
180+
if (element.attr("href").contains("exec:")) {
181+
dynBlackList.add(element.select("img").attr("src"));
182+
}
183+
});
185184

186-
documentBody.select("img").forEach(img -> {
187-
if (controller.isUseFullscreenImages) {
185+
documentBody.select("img").forEach(img -> {
188186
if (!dynBlackList.contains(img.attr("src"))) {
189-
img.attr("onclick" , "img.onClickImage(this.src);");
187+
img.attr("onclick", "img.onClickImage(this.src);");
190188
}
191-
}
189+
});
190+
}
191+
192+
documentBody.select("img").forEach(img -> {
192193
if (controller.isUseAutoWidth && controller.isUseAutoHeight) {
193194
img.attr("style", "display: inline; height: auto; max-width: 100%;");
194-
}
195-
if (!controller.isUseAutoWidth) {
196-
shouldChangeWidth(context, img).thenAccept(aBoolean -> {
197-
if (!aBoolean) return;
195+
} else {
196+
if (!controller.isUseAutoWidth) {
198197
img.attr("style" , "max-width:" + controller.customWidthImage+";");
199-
});
200-
} else if (!controller.isUseAutoHeight) {
201-
shouldChangeHeight(context, img).thenAccept(aBoolean -> {
202-
if (!aBoolean) return;
203-
img.attr("style" , "max-height:" + controller.customHeightImage+";");
204-
});
198+
}
199+
if (!controller.isUseAutoHeight) {
200+
img.attr("style" , "max-height:" + controller.customHeightImage+";");
201+
}
205202
}
206203
});
207204
}
208205

209-
private CompletableFuture<Boolean> shouldChangeWidth(Context context,
210-
Element img) {
211-
var relPath = img.attr("src");
212-
return CompletableFuture
213-
.supplyAsync(() -> fromRelPath(context , relPath , curGameDir), executors)
214-
.thenApply(imageFile -> {
215-
if (imageFile == null) return false;
216-
var drawable = imageProvider.getDrawableFromPath(context , imageFile.getUri());
217-
if (drawable == null) return false;
218-
var widthPix = context.getResources().getDisplayMetrics().widthPixels;
219-
return drawable.getIntrinsicWidth() < widthPix;
220-
});
221-
}
222-
223-
private CompletableFuture<Boolean> shouldChangeHeight(Context context,
224-
Element img) {
225-
var relPath = img.attr("src");
226-
return CompletableFuture
227-
.supplyAsync(() -> fromRelPath(context , relPath , curGameDir), executors)
228-
.thenApply(imageFile -> {
229-
if (imageFile == null) return false;
230-
var drawable = imageProvider.getDrawableFromPath(context , imageFile.getUri());
231-
if (drawable == null) return false;
232-
var heightPix = context.getResources().getDisplayMetrics().heightPixels;
233-
return drawable.getIntrinsicHeight() < heightPix;
234-
});
235-
}
236-
237206
private void handleVideosInHtml(Element documentBody) {
238207
var videoElement = documentBody.select("video");
239208
videoElement.attr("style", "max-width:100%;");

app/src/main/java/org/qp/android/ui/game/GameItemRecycler.java renamed to app/src/main/java/org/qp/android/ui/game/GameItemAdapter.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.List;
2222
import java.util.Objects;
2323

24-
public class GameItemRecycler extends RecyclerView.Adapter<GameItemRecycler.ViewHolder> {
24+
public class GameItemAdapter extends RecyclerView.Adapter<GameItemAdapter.ViewHolder> {
2525

2626
private static final DiffUtil.ItemCallback<QSPLib.ListItem> DIFF_CALLBACK =
2727
new DiffUtil.ItemCallback<>() {
@@ -62,15 +62,15 @@ public void submitList(List<QSPLib.ListItem> gameData) {
6262

6363
@NonNull
6464
@Override
65-
public GameItemRecycler.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
66-
int viewType) {
65+
public GameItemAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
66+
int viewType) {
6767
var inflater = LayoutInflater.from(parent.getContext());
6868
var listGameItemBinding = ListGameItemBinding.inflate(inflater, parent, false);
69-
return new GameItemRecycler.ViewHolder(listGameItemBinding);
69+
return new GameItemAdapter.ViewHolder(listGameItemBinding);
7070
}
7171

7272
@Override
73-
public void onBindViewHolder(@NonNull GameItemRecycler.ViewHolder holder, int position) {
73+
public void onBindViewHolder(@NonNull GameItemAdapter.ViewHolder holder, int position) {
7474
var qpListItem = getItem(position);
7575

7676
final var itemImage = holder.listGameItemBinding.itemIcon;

app/src/main/java/org/qp/android/ui/game/GameMainFragment.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
public class GameMainFragment extends Fragment {
2626

27+
private final GameItemAdapter adapter = new GameItemAdapter();
2728
private GameViewModel viewModel;
2829
private ConstraintLayout layoutTop;
2930
private WebView mainDescView;
@@ -76,7 +77,7 @@ public void onClickImage(String src) {
7677
}
7778
}, "img");
7879
if (viewModel.getSettingsController().isUseAutoscroll) {
79-
mainDescView.postDelayed(onScroll, 300);
80+
mainDescView.post(onScroll);
8081
}
8182
viewModel.getMainDescObserver().observe(getViewLifecycleOwner(), desc ->
8283
mainDescView.loadDataWithBaseURL(
@@ -90,13 +91,20 @@ public void onClickImage(String src) {
9091
actionsView = gameMainBinding.actions;
9192
var manager = (LinearLayoutManager) actionsView.getLayoutManager();
9293
var dividerItemDecoration = new DividerItemDecoration(
93-
actionsView.getContext(),
94-
manager.getOrientation());
94+
actionsView.getContext(), manager.getOrientation());
9595
actionsView.addItemDecoration(dividerItemDecoration);
9696
actionsView.setOverScrollMode(View.OVER_SCROLL_NEVER);
97-
viewModel.getActionObserver().observe(getViewLifecycleOwner(), actions -> {
97+
actionsView.setBackgroundColor(viewModel.getBackgroundColor());
98+
actionsView.setAdapter(adapter);
99+
100+
viewModel.actsListLiveData.observe(getViewLifecycleOwner(), listItems -> {
98101
actionsView.setBackgroundColor(viewModel.getBackgroundColor());
99-
actionsView.setAdapter(actions);
102+
adapter.typeface = viewModel.getSettingsController().getTypeface();
103+
adapter.textSize = viewModel.getFontSize();
104+
adapter.textColor = viewModel.getTextColor();
105+
adapter.linkTextColor = viewModel.getLinkColor();
106+
adapter.backgroundColor = viewModel.getBackgroundColor();
107+
adapter.submitList(listItems);
100108
});
101109

102110
// Settings
@@ -118,6 +126,7 @@ public void onClickImage(String src) {
118126
actionsView.setBackgroundColor(viewModel.getBackgroundColor());
119127
gameMainBinding.getRoot().refreshDrawableState();
120128
});
129+
121130
return gameMainBinding.getRoot();
122131
}
123132

app/src/main/java/org/qp/android/ui/game/GameObjectFragment.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
public class GameObjectFragment extends Fragment {
2020

21+
private final GameItemAdapter adapter = new GameItemAdapter();
2122
private FragmentRecyclerBinding recyclerBinding;
2223
private GameViewModel viewModel;
2324
private RecyclerView objectView;
@@ -38,16 +39,25 @@ public View onCreateView(@NonNull LayoutInflater inflater,
3839
manager.getOrientation());
3940
objectView.addItemDecoration(dividerItemDecoration);
4041
objectView.setOverScrollMode(View.OVER_SCROLL_NEVER);
41-
viewModel.getObjectsObserver().observe(getViewLifecycleOwner(), gameItemRecycler -> {
42+
objectView.setBackgroundColor(viewModel.getBackgroundColor());
43+
objectView.setAdapter(adapter);
44+
45+
viewModel.objsListLiveData.observe(getViewLifecycleOwner(), listItems -> {
4246
objectView.setBackgroundColor(viewModel.getBackgroundColor());
43-
recyclerBinding.shareRecyclerView.setAdapter(gameItemRecycler);
47+
adapter.typeface = viewModel.getSettingsController().getTypeface();
48+
adapter.textSize = viewModel.getFontSize();
49+
adapter.textColor = viewModel.getTextColor();
50+
adapter.linkTextColor = viewModel.getLinkColor();
51+
adapter.backgroundColor = viewModel.getBackgroundColor();
52+
adapter.submitList(listItems);
4453
});
4554

4655
// Settings
4756
viewModel.getControllerObserver().observe(getViewLifecycleOwner(), settingsController -> {
4857
objectView.setBackgroundColor(viewModel.getBackgroundColor());
4958
recyclerBinding.getRoot().refreshDrawableState();
5059
});
60+
5161
return recyclerBinding.getRoot();
5262
}
5363

0 commit comments

Comments
 (0)