Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Исправления и улучшения в quest player #47

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 43 additions & 13 deletions app/src/main/java/org/qp/android/model/archive/ArchiveUnpack.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

Expand Down Expand Up @@ -38,7 +39,26 @@ public class ArchiveUnpack {
private final Context context;
private final File targetArchive;
private File destFolder;
private String gameTitle;

public ArchiveUnpack(@NonNull Context context,
@NonNull File targetArchive,
@NonNull File destFolder,
String gameTitle) {
this.context = context;
this.targetArchive = targetArchive;
this.gameTitle =gameTitle;
if(gameTitle!=null) {
this.destFolder = findOrCreateFolder(context, destFolder, gameTitle);
this.unpackFolder=this.destFolder;
}
else this.destFolder = destFolder;
}
public ArchiveUnpack(@NonNull Context context,
@NonNull File targetArchive,
@NonNull File destFolder) {
this(context,targetArchive,destFolder,null);
}
@NonNull
private static int[] getPrimitiveLongArrayFromInt(Set<Integer> input) {
int[] ret = new int[input.size()];
Expand All @@ -49,14 +69,26 @@ private static int[] getPrimitiveLongArrayFromInt(Set<Integer> input) {
return ret;
}

public ArchiveUnpack(@NonNull Context context,
@NonNull File targetArchive,
@NonNull File destFolder) {
this.context = context;
this.targetArchive = targetArchive;
this.destFolder = destFolder;
private void expandFolderWithGame(File dir) {
File it = dir;
File rootDirForDeletion=null;
while (true) {
File[] files = it.listFiles();
if (files.length != 1 || !files[0].isDirectory()) {
break;
}
it = files[0];
if(rootDirForDeletion==null) rootDirForDeletion=files[0]; //Если уровень вложенности папок больше,чем один,мы должны удалить целую вложенную папку,а не только папку на последнем уровне вложенности.
}

if (it == dir) {
return;
}
for (File file : it.listFiles()) {
File dest = new File(dir.getAbsolutePath(), file.getName());
file.renameTo(dest);
}
rootDirForDeletion.delete();
}
public void extractArchiveEntries() {
assertNonUiThread();

Expand All @@ -67,18 +99,15 @@ public void extractArchiveEntries() {
var fileNames = new HashMap<Integer, String>();
for (int ind = 0; ind < itemCount; ind++) {
var fileName = inArchive.getStringProperty(ind, PropID.PATH);
if (fileName.endsWith(".qsp") || fileName.endsWith(".gam")) {
if (fileName.split("/").length == 1) {
//Прошлый код некоректно работал в игре 7.40,т.к там несколько qsp файлов. Вообще я не вижу смысла в этом коде и предлагаю использовать имя игры как название папки.
if (fileName.split("/").length == 1 &&gameTitle ==null &&(fileName.endsWith(".qsp") || fileName.endsWith(".gam"))) {
var archiveName = targetArchive.getName();
var pattern = Pattern.compile(".(?:r\\d\\d|r\\d\\d\\d|rar|zip|aqsp)");
var folderName = pattern.matcher(archiveName).replaceAll("");
if (fileName.split("/").length == 1) {
destFolder = findOrCreateFolder(context, destFolder, folderName);
unpackFolder = destFolder;
}
}
}
if (unpackFolder == null && ind == itemCount - 1) {
if (unpackFolder == null && ind == itemCount - 1) {
unpackFolder = new File(destFolder, fileName);
}
Log.d(TAG, "index: "+ind+"\nfilename: "+fileName+"\nitemCount: "+itemCount);
Expand All @@ -93,6 +122,7 @@ public void extractArchiveEntries() {
false,
new ArchiveExtractCallback(destFolder, inArchive)
);
expandFolderWithGame(destFolder);
} catch (IOException e) {
Log.e(TAG, "", e);
}
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/org/qp/android/ui/game/GameItemRecycler.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.qp.android.ui.game;

import android.graphics.Typeface;
import android.os.Bundle;
import android.text.Html;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.DiffUtil;
Expand Down Expand Up @@ -124,6 +128,14 @@ public static class ViewHolder extends RecyclerView.ViewHolder {
ViewHolder(ListGameItemBinding binding){
super(binding.getRoot());
this.listGameItemBinding = binding;
//Аналогично,как мы сделали для полки игр. Вообще,на мой взгляд,этот делегат можно вынести отдельно,чтобы избежать дублирования кода.
this.listGameItemBinding.relativeLayout.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean performAccessibilityAction(@NonNull View host, int action, @Nullable Bundle args) {
if(action== AccessibilityNodeInfo.ACTION_CLICK) return host.performClick(); else if(action==AccessibilityNodeInfo.ACTION_LONG_CLICK) return host.performLongClick();
return super.performAccessibilityAction(host, action, args);
}
});
}

public void listItemActionObjectBinding(LibListItem libListItem) {
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/java/org/qp/android/ui/stock/GamesListAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.DiffUtil;
Expand Down Expand Up @@ -122,7 +126,15 @@ public static class GameHolder extends RecyclerView.ViewHolder {
GameHolder(ListItemGameBinding listItemGameBinding){
super(listItemGameBinding.getRoot());
this.listItemGameBinding = listItemGameBinding;
}
//Если у родительской ноды одна дочерняя нода,то эта нода игнорируется и родительской нодой становится дочерняя нода. Так происходит до тех пор,пока у родительской ноды нее появятся дочерние ноды. В этом случае фреймворк отлавливает нажатие на эту ноду,или на дочерние ноды. Примерно так,на мой взгляд,это работает.
this.listItemGameBinding.relativeLayout.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean performAccessibilityAction(@NonNull View host, int action, @Nullable Bundle args) {
if(action== AccessibilityNodeInfo.ACTION_CLICK) return host.performClick(); else if(action==AccessibilityNodeInfo.ACTION_LONG_CLICK) return host.performLongClick();
return super.performAccessibilityAction(host, action, args);
}
});
}

public void listItemGameBinding(GameData gameData) {
listItemGameBinding.setGameData(gameData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All @@ -29,7 +28,7 @@ public View onCreateView(@NonNull LayoutInflater inflater ,
@Nullable Bundle savedInstanceState) {
var recyclerBinding = FragmentRecyclerBinding.inflate(inflater);
mRecyclerView = recyclerBinding.shareRecyclerView;
mRecyclerView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
//mRecyclerView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); //Не обязательная строка.
stockViewModel = new ViewModelProvider(requireActivity()).get(StockViewModel.class);

stockViewModel.getGameDataList().observe(getViewLifecycleOwner(), item -> {
Expand Down Expand Up @@ -88,17 +87,5 @@ public void onLongItemClick(View view, int position) {
stockViewModel.doOnShowActionMode();
}
}));
mRecyclerView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean performAccessibilityAction(@NonNull View host ,
int action ,
@Nullable Bundle args) {
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK -> host.performClick();
case AccessibilityNodeInfo.ACTION_LONG_CLICK -> host.performLongClick();
}
return super.performAccessibilityAction(host , action , args);
}
});
}
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/org/qp/android/ui/stock/StockViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,8 @@ public void postProcessingDownload() {
var archiveUnpack = new ArchiveUnpack(
getApplication(),
archive,
rootInDir
);
rootInDir,
getGameTitle());

CompletableFuture
.runAsync(archiveUnpack::extractArchiveEntries, executor)
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ recyclerview = "1.3.2"
retrofit = "2.11.0"
rxandroid = "3.0.2"
staxApi = "1.0-2"
storage = "1.5.5"
storage = "1.5.6"
webkit = "1.11.0"
woodstoxCore = "6.6.2"
workRuntime = "2.9.1"
Expand Down