Commit 8336ab66 authored by fallenstardust's avatar fallenstardust Committed by GitHub

Merge pull request #190 from zhuhongbozhuhongbo/master

卡组广场并入主项目
parents 3f43b00a 3c2f770b
上传新卡组调用api:
首先获得卡组id:
【get] http://rarnu.xyz:38383/api/mdpro3/deck/deckId
将获得的卡组id作为json body的一部分,上传到服务器:
http://rarnu.xyz:38383/api/mdpro3/sync/single
json body格式如下:
{
"deckContributor": "zhb_con",
"userId": 795610,
"deck": {
"deckId": "0007b1ad19",
"deckName": "zhb_test_deck2",
"deckCoverCard1": 0,
"deckCoverCard2": 0,
"deckCoverCard3": 0,
"deckCase": 0,
"deckProtector": 0,
"deckYdk": "#created by
mdpro3\r\n#main\r\n89943723\r\n89943724\r\n89943724\r\n79856792\r\n58153103\r\n83965310\r\n14124483\r\n13256226\r\n13256226\r\n9411399\r\n9411399\r\n18094166\r\n18094166\r\n40044918\r\n40044918\r\n59392529\r\n63060238\r\n50720316\r\n50720316\r\n27780618\r\n27780618\r\n16605586\r\n16605586\r\n43237273\r\n80344569\r\n22865492\r\n22865492\r\n17955766\r\n14558127\r\n14558127\r\n14558127\r\n23434538\r\n23434538\r\n23434538\r\n40740224\r\n6186304\r\n18144506\r\n213326\r\n213326\r\n8949584\r\n8949584\r\n10186633\r\n32807848\r\n21143940\r\n21143940\r\n80170678\r\n52947044\r\n45906428\r\n45906428\r\n24094653\r\n24094653\r\n14088859\r\n14088859\r\n24224830\r\n24224830\r\n65681983\r\n24299458\r\n75047173\r\n10045474\r\n75047173\r\n#extra\r\n90050480\r\n86346643\r\n31817415\r\n32828466\r\n40080312\r\n56733747\r\n29095552\r\n40854197\r\n46759931\r\n60461804\r\n93347961\r\n64655485\r\n22908820\r\n58481572\r\n58004362\r\n!
side\r\n27204311\r\n27204311\r\n83965311\r\n59438930\r\n59438930\r\n24508238\r\n24508238\r\n94145021\r\n94145021\r\n26964762\r\n90846359\r\n83326048\r\n83326048\r\n83326048\r\n#pickup\r\n#case\r\n1081008#\r\n#protector\r\n1070008#\r\n#field\r\n1090009#\r\n#grave\r\n1100009#\r\n#stand\r\n1110001#\r\n#mate\r\n1000007#\r\n##\r\n###",
"isDelete": false
}
}
注意:deckId字段为[get]方法获得的id,deckName字段对应于卡组名称,服务端会检查该字段,不允许同一卡组名称上传多次(如果第二次上传某个卡组名,会返回false,上传失败)
上传成功后,服务器响应为:
{
"code": 0,
"message": "",
"data": true
}
上传失败后,服务器响应为:
更新已在云上存在的卡组:
仍然用上述body,但是其中deckId、deckName必须与云上的记录严格对应。
示例:
[1]云上存在卡组deckId=111,deckName=双打水产。
上传json中,deckId=111,deckName=双打水产,代表更新云上的该卡组的内容。
[2]云上存在卡组deckId=111,deckName=双打水产,
上传json中,deckId=110,deckName=双打水产,服务端会返回错误,本次上传失败。
即,如果服务器上已存在卡组名称XXX,则再上传“卡组名为XXX,卡组id不同”的卡组,会返回错误
[3]云上存在卡组deckId=111,deckName=双打水产,
上传json中,deckId=111,deckName=双打水产B,代表更新卡组名称,本次上传成功。
总结:
将对应于deckId、deckName的卡组内容json推送到服务器。
如果在服务器上不存在deckId、deckName对应的记录,则创建新卡组
如果在服务器存在deckId相同的记录,则更新卡组,deckName会覆盖服务器上的卡组名
如果在服务器存在deckName相同、deckId不同的记录,则更新失败
\ No newline at end of file
...@@ -19,8 +19,8 @@ android { ...@@ -19,8 +19,8 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_11
} }
productFlavors { productFlavors {
cn { cn {
...@@ -68,6 +68,9 @@ android { ...@@ -68,6 +68,9 @@ android {
noCompress 'dll', 'config' noCompress 'dll', 'config'
} }
namespace 'cn.garymb.ygomobile.lite' namespace 'cn.garymb.ygomobile.lite'
buildFeatures {
viewBinding true
}
// buildToolsVersion '28.0.3' // buildToolsVersion '28.0.3'
} }
...@@ -89,6 +92,7 @@ dependencies { ...@@ -89,6 +92,7 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.12.0' implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'androidx.navigation:navigation-fragment:2.8.1' implementation 'androidx.navigation:navigation-fragment:2.8.1'
implementation 'androidx.navigation:navigation-ui:2.8.1' implementation 'androidx.navigation:navigation-ui:2.8.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation('com.github.chrisbanes.photoview:library:1.2.4') { implementation('com.github.chrisbanes.photoview:library:1.2.4') {
implementation 'com.github.chrisbanes.photoview:library:1.2.4' implementation 'com.github.chrisbanes.photoview:library:1.2.4'
......
...@@ -21,11 +21,12 @@ ...@@ -21,11 +21,12 @@
android:name="cn.garymb.ygomobile.ui.activities.LogoActivity" android:name="cn.garymb.ygomobile.ui.activities.LogoActivity"
android:excludeFromRecents="false" android:excludeFromRecents="false"
android:theme="@style/TranslucentTheme"> android:theme="@style/TranslucentTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<!--meta-data <!--meta-data
android:name="android.app.shortcuts" android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" /--> android:resource="@xml/shortcuts" /-->
...@@ -158,14 +159,14 @@ ...@@ -158,14 +159,14 @@
<!-- android:screenOrientation="landscape"--> <!-- android:screenOrientation="landscape"-->
<activity <activity
android:name="cn.garymb.ygomobile.ex_card.ExCardActivity" android:name="cn.garymb.ygomobile.ex_card.ExCardActivity"
android:theme="@style/AppTheme.Mycard"
android:launchMode="singleTop" android:launchMode="singleTop"
/> android:theme="@style/AppTheme.Mycard" />
<service <service
android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService" android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
android:label="dexopt" android:label="dexopt"
android:process=":dexopt" > android:process=":dexopt"></service>
</service>
<!-- 如果已经安装过原版YGOMobile,请注释掉或修改成其他,否则会导致无法安装 --> <!-- 如果已经安装过原版YGOMobile,请注释掉或修改成其他,否则会导致无法安装 -->
<provider <provider
android:name="cn.garymb.ygomobile.ui.settings.YGOPreferencesProvider" android:name="cn.garymb.ygomobile.ui.settings.YGOPreferencesProvider"
......
package androidx.appcompat.widget; package androidx.recyclerview.widget;
import android.view.GestureDetector; import android.view.GestureDetector;
...@@ -6,7 +6,6 @@ import android.view.MotionEvent; ...@@ -6,7 +6,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import androidx.core.view.GestureDetectorCompat; import androidx.core.view.GestureDetectorCompat;
import androidx.recyclerview.widget.RecyclerView;
public class RecyclerViewItemListener extends RecyclerView.SimpleOnItemTouchListener { public class RecyclerViewItemListener extends RecyclerView.SimpleOnItemTouchListener {
private final GestureDetectorCompat gestureDetector; private final GestureDetectorCompat gestureDetector;
......
...@@ -19,9 +19,9 @@ import static cn.garymb.ygomobile.Constants.DEF_PREF_KEEP_SCALE; ...@@ -19,9 +19,9 @@ import static cn.garymb.ygomobile.Constants.DEF_PREF_KEEP_SCALE;
import static cn.garymb.ygomobile.Constants.DEF_PREF_NOTCH_HEIGHT; import static cn.garymb.ygomobile.Constants.DEF_PREF_NOTCH_HEIGHT;
import static cn.garymb.ygomobile.Constants.DEF_PREF_ONLY_GAME; import static cn.garymb.ygomobile.Constants.DEF_PREF_ONLY_GAME;
import static cn.garymb.ygomobile.Constants.DEF_PREF_READ_EX; import static cn.garymb.ygomobile.Constants.DEF_PREF_READ_EX;
import static cn.garymb.ygomobile.Constants.PREF_DEF_KEY_WORDS_SPLIT;
import static cn.garymb.ygomobile.Constants.PREF_DEF_DATA_LANGUAGE; import static cn.garymb.ygomobile.Constants.PREF_DEF_DATA_LANGUAGE;
import static cn.garymb.ygomobile.Constants.PREF_DEF_IMMERSIVE_MODE; import static cn.garymb.ygomobile.Constants.PREF_DEF_IMMERSIVE_MODE;
import static cn.garymb.ygomobile.Constants.PREF_DEF_KEY_WORDS_SPLIT;
import static cn.garymb.ygomobile.Constants.PREF_DEF_SENSOR_REFRESH; import static cn.garymb.ygomobile.Constants.PREF_DEF_SENSOR_REFRESH;
import static cn.garymb.ygomobile.Constants.PREF_FONT_SIZE; import static cn.garymb.ygomobile.Constants.PREF_FONT_SIZE;
import static cn.garymb.ygomobile.Constants.PREF_IMMERSIVE_MODE; import static cn.garymb.ygomobile.Constants.PREF_IMMERSIVE_MODE;
...@@ -499,6 +499,7 @@ public class AppsSettings { ...@@ -499,6 +499,7 @@ public class AppsSettings {
public String getCoreSkinPath() { public String getCoreSkinPath() {
return new File(getResourcePath(), Constants.CORE_SKIN_PATH).getAbsolutePath(); return new File(getResourcePath(), Constants.CORE_SKIN_PATH).getAbsolutePath();
} }
public String getAvatarPath() { public String getAvatarPath() {
return new File(getResourcePath(), Constants.CORE_AVATAR_PATH).getAbsolutePath(); return new File(getResourcePath(), Constants.CORE_AVATAR_PATH).getAbsolutePath();
} }
...@@ -510,6 +511,7 @@ public class AppsSettings { ...@@ -510,6 +511,7 @@ public class AppsSettings {
public String getBgPath() { public String getBgPath() {
return new File(getResourcePath(), Constants.CORE_BG_PATH).getAbsolutePath(); return new File(getResourcePath(), Constants.CORE_BG_PATH).getAbsolutePath();
} }
/*** /***
* 字体路径 * 字体路径
*/ */
...@@ -613,7 +615,12 @@ public class AppsSettings { ...@@ -613,7 +615,12 @@ public class AppsSettings {
return mSharedPreferences.getString(Constants.PREF_DEF_LAST_YDK, null); return mSharedPreferences.getString(Constants.PREF_DEF_LAST_YDK, null);
} }
//获得最后卡组绝对路径 /**
* 获得(最后)上次打开的卡组的绝对路径
* setCurDeck()方法负责设置上次打开的卡组的路径
*
* @return
*/
public @Nullable public @Nullable
String getLastDeckPath() { String getLastDeckPath() {
String path; String path;
...@@ -804,7 +811,7 @@ public class AppsSettings { ...@@ -804,7 +811,7 @@ public class AppsSettings {
Korean(1, "ko"), Korean(1, "ko"),
English(2, "en"), English(2, "en"),
Spanish(3, "es"), Spanish(3, "es"),
Japanese(4,"jp"), Japanese(4, "jp"),
Portuguese(5, "pt"); Portuguese(5, "pt");
public Integer code; public Integer code;
...@@ -913,7 +920,7 @@ public class AppsSettings { ...@@ -913,7 +920,7 @@ public class AppsSettings {
setDataLanguage(languageEnum.Portuguese.code); setDataLanguage(languageEnum.Portuguese.code);
} }
private void replaceLineFeed(){ private void replaceLineFeed() {
//替换换行符 //替换换行符
String stringConfPath = new File(getResourcePath(), CORE_STRING_PATH).getAbsolutePath(); String stringConfPath = new File(getResourcePath(), CORE_STRING_PATH).getAbsolutePath();
String botConfPath = new File(getResourcePath(), BOT_CONF).getAbsolutePath(); String botConfPath = new File(getResourcePath(), BOT_CONF).getAbsolutePath();
......
...@@ -25,7 +25,7 @@ public class DeckInfo { ...@@ -25,7 +25,7 @@ public class DeckInfo {
private final List<Card> sideCards; private final List<Card> sideCards;
private final List<Card> allCards; private final List<Card> allCards;
public File source; public File source;//当前打开的ydk文件的file
private int mainCount, extraCount, sideCount; private int mainCount, extraCount, sideCount;
......
package cn.garymb.ygomobile.bean; package cn.garymb.ygomobile.bean;
public class DeckType extends TextSelect { public class DeckType extends TextSelect {
public enum ServerType {
LOCAL,//本地卡组
SQUARE_DECK,//卡组广场上的卡组
MY_SQUARE,//本用户在云上的卡组
}
private String name; private String name;
private String path; private String path;
private ServerType onServer;//true代表云端卡组,false代表本地卡组
public DeckType(String name, String path) { public DeckType(String name, String path) {
this.name = name; this.name = name;
this.path = path; this.path = path;
onServer = ServerType.LOCAL;
super.setName(name); super.setName(name);
setObject(this); setObject(this);
} }
public DeckType(String name, String path, ServerType onServer) {
this.name = name;
this.path = path;
this.onServer = onServer;
setObject(this);
}
public String getName() { public String getName() {
return name; return name;
} }
...@@ -27,4 +42,16 @@ public class DeckType extends TextSelect { ...@@ -27,4 +42,16 @@ public class DeckType extends TextSelect {
this.path = path; this.path = path;
} }
public ServerType getOnServer() {
return onServer;
}
public void setOnServer(ServerType onServer) {
this.onServer = onServer;
}
//true代表卡组位于本地
public boolean isLocal() {
return (this.onServer == ServerType.LOCAL);
}
} }
...@@ -2,27 +2,54 @@ package cn.garymb.ygomobile.bean.events; ...@@ -2,27 +2,54 @@ package cn.garymb.ygomobile.bean.events;
import java.io.File; import java.io.File;
import cn.garymb.ygomobile.bean.DeckType;
import cn.garymb.ygomobile.bean.TextSelect; import cn.garymb.ygomobile.bean.TextSelect;
import cn.garymb.ygomobile.utils.DeckUtil; import cn.garymb.ygomobile.utils.DeckUtil;
public class DeckFile extends TextSelect { public class DeckFile extends TextSelect {
private File path;
private final File path; private String fileFullName;//本地文件对应的名称,仅在onServer为false时有效
private final String fullName; // private final File path;
// private final String fullName;
//分类 //分类
private String typeName; private String typeName;//可取值包括cacheDeck,Pack
private int firstCode; private int firstCode;
private DeckType.ServerType onServer;//true代表云端卡组,false代表本地卡组
private String deckId;//如果onServer为true,代表该卡组存储在云上,deckId是唯一id
// public DeckFile(boolean onServer) {
// this.onServer = onServer;
// }
public DeckFile(String deckId, DeckType.ServerType onServer) {
this.deckId = deckId;
this.onServer = onServer;
}
public DeckFile(String name, String typeName, DeckType.ServerType onServer, String deckId) {
this.typeName = typeName;
this.onServer = onServer;
this.deckId = deckId;
this.setName(name);
this.fileFullName = null;
this.path = null;
this.firstCode = -1;
setObject(this);
}
public DeckFile(String path) { public DeckFile(String path) {
this(new File(path)); this(new File(path));
} }
public DeckFile(File file) { public DeckFile(File file) {
this.onServer = DeckType.ServerType.LOCAL;
this.deckId = null;
path = file; path = file;
fullName = file.getName(); fileFullName = file.getName();
String name = fullName; String name = fileFullName;
int index = name.lastIndexOf("."); int index = name.lastIndexOf(".");
if(index > 0) { if (index > 0) {
name = name.substring(0, index); name = name.substring(0, index);
} }
typeName = DeckUtil.getDeckTypeName(path.getAbsolutePath()); typeName = DeckUtil.getDeckTypeName(path.getAbsolutePath());
...@@ -32,7 +59,7 @@ public class DeckFile extends TextSelect { ...@@ -32,7 +59,7 @@ public class DeckFile extends TextSelect {
} }
public int getFirstCode() { public Integer getFirstCode() {
return firstCode; return firstCode;
} }
...@@ -49,7 +76,7 @@ public class DeckFile extends TextSelect { ...@@ -49,7 +76,7 @@ public class DeckFile extends TextSelect {
} }
public String getFileName() { public String getFileName() {
return fullName; return fileFullName;
} }
public File getPathFile() { public File getPathFile() {
...@@ -64,4 +91,38 @@ public class DeckFile extends TextSelect { ...@@ -64,4 +91,38 @@ public class DeckFile extends TextSelect {
return path.lastModified(); return path.lastModified();
} }
public DeckType.ServerType getOnServer() {
return onServer;
}
public void setOnServer(DeckType.ServerType onServer) {
this.onServer = onServer;
}
//true代表卡组位于本地
public boolean isLocal() {
return (this.onServer == DeckType.ServerType.LOCAL);
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
@Override
public String toString() {
return "DeckFile{" +
"path=" + path +
", fileFullName='" + fileFullName + '\'' +
", typeName='" + typeName + '\'' +
", firstCode=" + firstCode +
", onServer=" + onServer +
", deckId='" + deckId + '\'' +
'}';
}
} }
package cn.garymb.ygomobile.deck_square;
import android.os.Parcel;
import android.os.Parcelable;
public class DeckInfo implements Parcelable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected DeckInfo(Parcel in) {
name = in.readString();
}
public static final Creator<DeckInfo> CREATOR = new Creator<DeckInfo>() {
@Override
public DeckInfo createFromParcel(Parcel in) {
return new DeckInfo(in);
}
@Override
public DeckInfo[] newArray(int size) {
return new DeckInfo[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
}
}
package cn.garymb.ygomobile.deck_square;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.utils.YGODeckDialogUtil;
public class DeckManageDialog extends DialogFragment implements YGODeckDialogUtil.OnDeckDialogListener {
public void onDismiss() {
dismiss();
}
public void onShow() {
//todo
}
private YGODeckDialogUtil.OnDeckMenuListener mOnDeckMenuListener;
public DeckManageDialog(YGODeckDialogUtil.OnDeckMenuListener onDeckMenuListener) {
super();
mOnDeckMenuListener = onDeckMenuListener;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dialog_deck_manager, container, false);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager2 viewPager = view.findViewById(R.id.deck_view_pager);
TabLayout tabLayout = view.findViewById(R.id.deck_manager_tab_layout);
// Setup adapter
ViewPagerAdapter adapter = new ViewPagerAdapter(this, mOnDeckMenuListener, this);
viewPager.setAdapter(adapter);
// Connect TabLayout with ViewPager
new TabLayoutMediator(tabLayout, viewPager,
new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
//tab.setText("Tab " + (position + 1));
switch (position) {
case 0:
tab.setIcon(R.drawable.ic_deck_box);
tab.setText(R.string.local_deck);
break;
case 1:
tab.setIcon(R.drawable.ic_deck_square);
tab.setText(R.string.deck_square);
break;
case 2:
tab.setIcon(R.drawable.my_deck_square);
tab.setText(R.string.my_deck_online);
break;
}
}
}).attach();
}
@Override
public void onStart() {
super.onStart();
// Set dialog dimensions
Window window = getDialog().getWindow();
if (window != null) {
window.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
}
}
private static class ViewPagerAdapter extends FragmentStateAdapter {
private YGODeckDialogUtil.OnDeckMenuListener mOnDeckMenuListener;
private YGODeckDialogUtil.OnDeckDialogListener onDeckDialogListener;
public ViewPagerAdapter(@NonNull Fragment fragment, YGODeckDialogUtil.OnDeckMenuListener listener, YGODeckDialogUtil.OnDeckDialogListener dialogListener) {
super(fragment);
mOnDeckMenuListener = listener;
onDeckDialogListener = dialogListener;
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new DeckSelectFragment(mOnDeckMenuListener, onDeckDialogListener);
case 1:
return new DeckSquareFragment(mOnDeckMenuListener, onDeckDialogListener);
case 2:
return new DeckSquareMyDeckFragment(mOnDeckMenuListener, onDeckDialogListener);
default:
throw new IllegalArgumentException();
}
}
@Override
public int getItemCount() {
return 3;
}
}
}
\ No newline at end of file
package cn.garymb.ygomobile.deck_square;
import java.util.List;
public class DeckResponseJson {
int code;
String message;
String name;
List<DeckInfo> hobbies;
}
\ No newline at end of file
package cn.garymb.ygomobile.deck_square;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import cn.garymb.ygomobile.AppsSettings;
import cn.garymb.ygomobile.Constants;
import cn.garymb.ygomobile.utils.IOUtils;
import cn.garymb.ygomobile.utils.LogUtil;
import ocgcore.CardManager;
import ocgcore.DataManager;
import ocgcore.data.Card;
public class DeckSquareFileUtil {
//
private static final String TAG = DeckSquareListAdapter.class.getSimpleName();
// public static List<String> readLastLinesWithNIO(File file, int numLines) {
// try {
// List<String> lines = Files.readAllLines(file);
// int fromIndex = Math.max(0, lines.size() - numLines);
// return lines.subList(fromIndex, lines.size());
// } catch (IOException e) {
// e.printStackTrace();
// return Collections.emptyList();
// }
// }
//
// 使用示例
// Path logPath = Paths.get(context.getFilesDir().getAbsolutePath(), "log.txt");
// List<String> lastTwo = readLastLinesWithNIO(logPath, 2);
//读取file指定的ydk文件,返回其内包含的deckId。如果不包含deckId,返回null
public static String getId(File file) {
String deckId = null;
Integer userId = null;
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
InputStreamReader in = null;
in = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(in);
String line = null;
while ((line = reader.readLine()) != null) {
LogUtil.i(TAG, line);
if (line.startsWith("###")) {//注意,先判断###,后判断##。因为###会包括##的情况
try {
String data = line.replace("#", "");
if (!data.isEmpty()) {
userId = Integer.parseInt(data);
}
// userId = Integer.parseInt(line.replaceAll("###", ""));
} catch (NumberFormatException e) {
LogUtil.e(TAG, "integer" + line + "parse error" + e.toString());
}
} else if (line.startsWith("##")) {
line = line.replace("#", "");
deckId = line;
}
}
} catch (IOException e) {
LogUtil.e(TAG, "read 1", e);
} finally {
IOUtils.close(inputStream);
}
return deckId;
}
//查询卡组目录下的所有ydk文件,返回File[]
public static File[] getAllYdk() {
File dir = new File(AppsSettings.get().getResourcePath(), Constants.CORE_DECK_PATH);
File[] files = dir.listFiles((file, s) -> s.toLowerCase(Locale.US).endsWith(Constants.YDK_FILE_EX));
return files;
}
//读取卡组目录下的所有ydk文件,解析ydk文件(包括从ydk文件内容中读取deckId),生成List<MyDeckItem>解析结果
public static List<MyDeckItem> getMyDeckItem() {
List<MyDeckItem> result = new ArrayList<>();
File[] files = getAllYdk();
for (File file : files) {
String deckId = getId(file);
MyDeckItem item = new MyDeckItem();
item.deckName = file.getName();
item.setDeckSouce(0);
item.setDeckPath(file.getPath());
if (deckId != null) {
item.deckId = deckId;
item.idUploaded = 2;
} else {
item.idUploaded = 0;
}
result.add(item);
}
return result;
}
// 读取deckPath对应的卡组文件到string,将卡组id、用户id设置到string中
//注意,不更改ydk文件内容
//下载卡组后,保存卡组之前
//上传卡组前,对于未存在卡组id的卡组,自动填入新的卡组id、用户id
public static String setDeckId(String deckPath, Integer userId, String deckId) {
StringBuilder contentBuilder = new StringBuilder();
boolean userIdFlag = false;
boolean deckIdFlag = false;
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(deckPath);
InputStreamReader in = null;
in = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(in);
String line = null;
while ((line = reader.readLine()) != null) {
/* 如果文件中已经存在deckId,则将其替换 */
if (line.contains("##") && !line.contains("###")) {
deckIdFlag = true;
line = "##" + deckId;
} else if (line.contains("###")) {//存在userId,将其替换
userIdFlag = true;
line = "###" + userId;
}
contentBuilder.append(line);
contentBuilder.append('\n'); // Add line break
}
} catch (Exception e) {
LogUtil.e(TAG, "read 1", e);
} finally {
IOUtils.close(inputStream);
}
if (!userIdFlag) {//原始ydk中不存在userId,添加userId行
contentBuilder.append("\n");
contentBuilder.append("##" + userId);
}
if (!deckIdFlag) {//原始ydk中不存在deckId,添加deckId行
contentBuilder.append("\n");
contentBuilder.append("###" + deckId);
}
String content = contentBuilder.toString();
return content;
}
public static boolean saveFileToPath(String path, String fileName, String content) {
try {
// Create file object
File file = new File(path, fileName);
// Create file output stream
FileOutputStream fos = new FileOutputStream(file);
// Write content
fos.write(content.getBytes());
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public static List<Card> convertTempDeckYdk(String deckYdk) {
String[] deckLine = deckYdk.split("\r\n|\r|\n");
List<Integer> tempDeck = new ArrayList<>();//存储当前卡组的基本内容
List<Card> cardList = new ArrayList<>();
CardManager mCardManager = DataManager.get().getCardManager();
for (String line : deckLine) {
if (!line.contains("#") && !line.contains("!")) {
//line.to
try {
Integer cardId = Integer.parseInt(line);
tempDeck.add(cardId);
Card card = mCardManager.getCard(cardId);
cardList.add(card);
} catch (NumberFormatException e) {
LogUtil.i(TAG, "cannot parse Interget" + line + e.getMessage());
}
}
}
return cardList;
}
}
package cn.garymb.ygomobile.deck_square;
import android.util.Log;
import android.widget.ImageView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import java.util.List;
import cn.garymb.ygomobile.deck_square.api_response.GetSquareDeckCondition;
import cn.garymb.ygomobile.deck_square.api_response.OnlineDeckDetail;
import cn.garymb.ygomobile.deck_square.api_response.SquareDeckResponse;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.ImageLoader;
import cn.garymb.ygomobile.ui.plus.DialogPlus;
import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.LogUtil;
//提供recyclerview的数据
public class DeckSquareListAdapter extends BaseQuickAdapter<OnlineDeckDetail, BaseViewHolder> {
private static final String TAG = DeckSquareListAdapter.class.getSimpleName();
private ImageLoader imageLoader;
public DeckSquareListAdapter(int layoutResId) {
super(layoutResId);
imageLoader = new ImageLoader();
}
public void loadData() {
loadData(1, 30, "", false, false, "");
}
public void loadData(Integer page, Integer size, String keyWord, Boolean sortLike, Boolean sortRank, String contributor) {
final DialogPlus dialog_read_ex = DialogPlus.show(getContext(), null, getContext().getString(R.string.fetch_online_deck));
VUiKit.defer().when(() -> {
SquareDeckResponse result = DeckSquareApiUtil.getSquareDecks(new GetSquareDeckCondition(page, size, keyWord, sortLike, sortRank, contributor));
if (result == null) {
return null;
} else {
return result.getData().getRecords();
}
}).fail((e) -> {
Log.e(TAG, e + "");
if (dialog_read_ex.isShowing()) {//关闭异常
try {
dialog_read_ex.dismiss();
} catch (Exception ex) {
}
}
LogUtil.i(TAG, "Get square deck fail");
}).done((result) -> {
if (result != null) {
LogUtil.i(TAG, "Get square deck success");
getData().clear();
addData(result);
notifyDataSetChanged();
}
if (dialog_read_ex.isShowing()) {
try {
dialog_read_ex.dismiss();
} catch (Exception ex) {
}
}
});
}
@Override
protected void convert(BaseViewHolder helper, OnlineDeckDetail item) {
helper.setText(R.id.deck_info_name, item.getDeckName());
helper.setText(R.id.deck_contributor, item.getDeckContributor());
helper.setText(R.id.deck_last_date, item.getLastDate());
helper.setText(R.id.like_count, item.getDeckLike()+"");
ImageView cardImage = helper.getView(R.id.deck_info_image);
long code = item.getDeckCoverCard1();
LogUtil.i(TAG, code + " " + item.getDeckName());
if (code != 0) {
imageLoader.bindImage(cardImage, code, null, ImageLoader.Type.small);
} else {
imageLoader.bindImage(cardImage, -1, null, ImageLoader.Type.small);
}
// ImageView imageview = helper.getView(R.id.ex_card_image);
//the function cn.garymb.ygomobile.loader.ImageLoader.bindT(...)
//cn.garymb.ygomobile.loader.ImageLoader.setDefaults(...)
//is a private function,so I copied the content of it to here
/* 如果查不到版本号,则不显示图片 */
/* 如果能查到版本号,则显示图片,利用glide的signature,将版本号和url作为signature,由glide判断是否使用缓存 */
}
}
\ No newline at end of file
package cn.garymb.ygomobile.deck_square;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import cn.garymb.ygomobile.deck_square.api_response.LoginResponse;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.lite.databinding.FragmentDeckSquareMyDeckBinding;
import cn.garymb.ygomobile.ui.activities.WebActivity;
import cn.garymb.ygomobile.ui.mycard.MyCard;
import cn.garymb.ygomobile.ui.mycard.bean.McUser;
import cn.garymb.ygomobile.ui.mycard.mcchat.ChatMessage;
import cn.garymb.ygomobile.ui.mycard.mcchat.management.UserManagement;
import cn.garymb.ygomobile.ui.plus.DialogPlus;
import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.SharedPreferenceUtil;
import cn.garymb.ygomobile.utils.YGODeckDialogUtil;
import cn.garymb.ygomobile.utils.YGOUtil;
import cn.garymb.ygomobile.utils.glide.GlideCompat;
//打开页面后,先扫描本地的卡组,读取其是否包含deckId,是的话代表平台上可能有
//之后读取平台上的卡组,与本地卡组列表做比较。
public class DeckSquareMyDeckFragment extends Fragment {
private static final String TAG = DeckSquareListAdapter.class.getSimpleName();
private FragmentDeckSquareMyDeckBinding binding;
private MyDeckListAdapter deckListAdapter;
private String keyWord;
private YGODeckDialogUtil.OnDeckMenuListener onDeckMenuListener;//通知外部调用方,(如调用本fragment的activity)
private YGODeckDialogUtil.OnDeckDialogListener mDialogListener;
public DeckSquareMyDeckFragment(YGODeckDialogUtil.OnDeckMenuListener onDeckMenuListener, YGODeckDialogUtil.OnDeckDialogListener mDialogListener) {
this.onDeckMenuListener = onDeckMenuListener;
this.mDialogListener = mDialogListener;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentDeckSquareMyDeckBinding.inflate(inflater, container, false);
if (SharedPreferenceUtil.getServerToken() == null) {
binding.llMainUi.setVisibility(View.GONE);
binding.llDialogLogin.setVisibility(View.VISIBLE);
} else {
binding.llMainUi.setVisibility(View.VISIBLE);
binding.llDialogLogin.setVisibility(View.GONE);
binding.tvMycardUserName.setText(SharedPreferenceUtil.getMyCardUserName());
GlideCompat.with(getActivity()).load(ChatMessage.getAvatarUrl(SharedPreferenceUtil.getMyCardUserName())).into(binding.myDeckAvatar);//刷新头像图片
}
binding.btnLogin.setOnClickListener(v -> attemptLogin());
binding.btnRegister.setOnClickListener(v -> WebActivity.open(getContext(), getString(R.string.register), MyCard.URL_MC_SIGN_UP));
deckListAdapter = new MyDeckListAdapter(R.layout.item_my_deck);
GridLayoutManager linearLayoutManager = new GridLayoutManager(getContext(), 3);
binding.listMyDeckInfo.setLayoutManager(linearLayoutManager);
binding.listMyDeckInfo.setAdapter(deckListAdapter);
deckListAdapter.loadData();
//其实仅仅是清除掉本机的token
binding.llMcLogout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogPlus dialogPlus = new DialogPlus(getContext());
dialogPlus.setMessage(R.string.logout_mycard);
dialogPlus.setMessageGravity(Gravity.CENTER);
dialogPlus.setLeftButtonListener((dlg, s) -> {
SharedPreferenceUtil.deleteServerToken();
binding.llMainUi.setVisibility(View.GONE);
binding.llDialogLogin.setVisibility(View.VISIBLE);
dialogPlus.dismiss();
});
dialogPlus.setRightButtonListener((dlg, s) -> {
dialogPlus.dismiss();
});
dialogPlus.show();
}
});
//查询卡组名称
binding.etMyDeckInputDeckName.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
keyWord = v.getText().toString();
//直接过滤列表中的item名称,而不是像卡组广场那样重新查询
deckListAdapter.filter(keyWord);
return true;
}
return false;
});
// 添加文本变化监听器
binding.etMyDeckInputDeckName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
deckListAdapter.filter(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
// 当输入框内容为空时
if (s.toString().isEmpty()) {
deckListAdapter.loadData();//悄悄留一个刷新我的云备份的方式,方便
} else {
deckListAdapter.filter(s.toString());
}
}
});
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
private void attemptLogin() {
String username = binding.etUsername.getText().toString().trim();
String password = binding.etPassword.getText().toString().trim();
if (username.isEmpty()) {
binding.tvAccountWarning.setVisibility(View.VISIBLE);
return;
} else {
binding.tvAccountWarning.setVisibility(View.GONE);
}
if (password.isEmpty()) {
binding.tvPwdWarning.setVisibility(View.VISIBLE);
return;
} else {
binding.tvPwdWarning.setVisibility(View.GONE);
}
binding.progressBar.setVisibility(View.VISIBLE);
binding.btnLogin.setEnabled(false);
VUiKit.defer().when(() -> {
LoginResponse result = DeckSquareApiUtil.login(username, password);//执行登录
SharedPreferenceUtil.setServerToken(result.token);
SharedPreferenceUtil.setServerUserId(result.user.id);
SharedPreferenceUtil.setMyCardUserName(result.user.username);
return result;
}).fail((e) -> {
YGOUtil.showTextToast(R.string.logining_failed);
binding.llMainUi.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.GONE);
binding.btnLogin.setEnabled(true);
}).done((result) -> {
if (result != null) {
binding.llMainUi.setVisibility(View.VISIBLE);
deckListAdapter.loadData();
binding.llDialogLogin.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.GONE);
binding.btnLogin.setEnabled(true);
//储存信息
String userName = result.user.username;
binding.tvMycardUserName.setText(userName);
McUser mcUser = new McUser();
mcUser.setUsername(userName);
mcUser.setExternal_id(result.user.id);
mcUser.setAvatar_url(ChatMessage.getAvatarUrl(userName));
mcUser.setToken(result.token);
GlideCompat.with(getActivity()).load(mcUser.getAvatar_url()).into(binding.myDeckAvatar);//刷新头像图片
UserManagement.getDx().setMcUser(mcUser);
YGOUtil.showTextToast(R.string.login_succeed);
} else {
YGOUtil.showTextToast(R.string.logining_failed);
binding.llMainUi.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.GONE);
binding.btnLogin.setEnabled(true);
}
});
}
}
package cn.garymb.ygomobile.deck_square;
public class MyDeckItem {
//0代表未推到服务器,3代表包含deckId,1代表服务器存在可下载到本地,2代表已同步
public int idUploaded;
public int userId;
public String deckName;
public String deckId;
public String updateDate;
public int deckSouce;//卡组来源,0代表来自本地,1代表来自服务器
public String deckPath;//本地卡组时,存储卡组路径
public int deckCoverCard1;
public Boolean isPublic;
public int getIdUploaded() {
return idUploaded;
}
public void setIdUploaded(int idUploaded) {
this.idUploaded = idUploaded;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getDeckName() {
return deckName;
}
public void setDeckName(String deckName) {
this.deckName = deckName;
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
public String getUpdateDate() {
return updateDate;
}
public void setUpdateDate(String updateDate) {
this.updateDate = updateDate;
}
public int getDeckSouce() {
return deckSouce;
}
public void setDeckSouce(int deckSouce) {
this.deckSouce = deckSouce;
}
public int getDeckCoverCard1() {
return deckCoverCard1;
}
public void setDeckCoverCard1(int deckCoverCard1) {
this.deckCoverCard1 = deckCoverCard1;
}
public String getDeckPath() {
return deckPath;
}
public void setDeckPath(String deckPath) {
this.deckPath = deckPath;
}
public Boolean getPublic() {
return isPublic;
}
public void setPublic(Boolean aPublic) {
isPublic = aPublic;
}
@Override
public String toString() {
return "MyDeckItem{" +
"idUploaded=" + idUploaded +
", userId=" + userId +
", deckName='" + deckName + '\'' +
", deckId='" + deckId + '\'' +
", updateDate='" + updateDate + '\'' +
", deckSouce=" + deckSouce +
", deckPath='" + deckPath + '\'' +
", deckCoverCard1=" + deckCoverCard1 +
", isPublic=" + isPublic +
'}';
}
}
package cn.garymb.ygomobile.deck_square;
import android.util.Log;
import android.widget.ImageView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import java.util.ArrayList;
import java.util.List;
import cn.garymb.ygomobile.bean.DeckType;
import cn.garymb.ygomobile.bean.events.DeckFile;
import cn.garymb.ygomobile.deck_square.api_response.BasicResponse;
import cn.garymb.ygomobile.deck_square.api_response.LoginToken;
import cn.garymb.ygomobile.deck_square.api_response.MyDeckResponse;
import cn.garymb.ygomobile.deck_square.api_response.MyOnlineDeckDetail;
import cn.garymb.ygomobile.deck_square.api_response.PushDeckResponse;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.ImageLoader;
import cn.garymb.ygomobile.ui.plus.DialogPlus;
import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.LogUtil;
import cn.garymb.ygomobile.utils.YGOUtil;
//提供“我的”卡组数据,打开后先从sharePreference查询,没有则从服务器查询,然后缓存到sharePreference
public class MyDeckListAdapter extends BaseQuickAdapter<MyDeckItem, BaseViewHolder> {
private static final String TAG = DeckSquareListAdapter.class.getSimpleName();
private ImageLoader imageLoader;
private List<MyDeckItem> originalData; // 保存原始数据
public MyDeckListAdapter(int layoutResId) {
super(layoutResId);
originalData = new ArrayList<>();
imageLoader = new ImageLoader();
}
public void loadData() {
List<MyDeckItem> myOnlineDecks = new ArrayList<>();
LoginToken loginToken = DeckSquareApiUtil.getLoginData();
if (loginToken == null) {
return;
}
final DialogPlus dialog_read_ex = DialogPlus.show(getContext(), null, getContext().getString(R.string.fetch_online_deck));
VUiKit.defer().when(() -> {
MyDeckResponse result = DeckSquareApiUtil.getUserDecks(loginToken);
if (result == null) {
return null;
} else {
return result.getData();
}
}).fail((e) -> {
Log.e(TAG, e + "");
if (dialog_read_ex.isShowing()) {//关闭异常
try {
dialog_read_ex.dismiss();
} catch (Exception ex) {
}
}
LogUtil.i(TAG, "load mycard from server fail");
}).done((serverDecks) -> {
if (serverDecks != null) {//将服务端的卡组也放到LocalDecks中
for (MyOnlineDeckDetail detail : serverDecks) {
MyDeckItem item = new MyDeckItem();
item.setDeckName(detail.getDeckName());
item.setDeckSouce(1);
item.setDeckId(detail.getDeckId());
item.setUserId(detail.getUserId());
item.setDeckCoverCard1(detail.getDeckCoverCard1());
item.setUpdateDate(detail.getDeckUpdateDate());
item.setPublic(detail.isPublic());
myOnlineDecks.add(item);
}
}
LogUtil.i(TAG, "load mycard from server done");
originalData.clear();
originalData.addAll(myOnlineDecks); // 保存原始数据
getData().clear();
addData(myOnlineDecks);
notifyDataSetChanged();
if (dialog_read_ex.isShowing()) {
try {
dialog_read_ex.dismiss();
} catch (Exception ex) {
}
}
});
}
// 筛选函数
public void filter(String keyword) {
List<MyDeckItem> filteredList = new ArrayList<>();
if (keyword.isEmpty()) {
// 如果关键词为空,则显示所有数据
filteredList.addAll(originalData);
} else {
// 遍历原始数据,筛选出包含关键词的item
for (MyDeckItem item : originalData) {
if (item.getDeckName().contains(keyword)) {
filteredList.add(item);
}
}
}
// 更新显示的数据
getData().clear();
addData(filteredList);
notifyDataSetChanged();
}
private void deleteMyDeckOnLine(MyDeckItem item) {
if (item != null) {
LoginToken loginToken = DeckSquareApiUtil.getLoginData();
if (loginToken == null) {
return;
}
VUiKit.defer().when(() -> {
PushDeckResponse result = DeckSquareApiUtil.deleteDeck(item.getDeckId(), loginToken);
return result;
}).fail(e -> {
LogUtil.i(TAG, "square deck detail fail" + e.getMessage());
}).done(data -> {
if (data.isData()) {
remove(item);
} else {
YGOUtil.showTextToast("delete fail " + data.getMessage());
}
});
}
}
/**
* 注意,更新卡组状态要过很久才生效(实测延迟偶尔达5s)
* @param item
*/
private void changeDeckPublicState(MyDeckItem item) {
if (item != null) {
LoginToken loginToken = DeckSquareApiUtil.getLoginData();
if (loginToken == null) {
return;
}
VUiKit.defer().when(() -> {
BasicResponse result = DeckSquareApiUtil.setDeckPublic(item.getDeckId(), loginToken, !item.getPublic());
return result;
}).fail(e -> {
LogUtil.i(TAG, "square deck detail fail" + e.getMessage());
}).done(data -> {
});
}
}
@Override
protected void convert(BaseViewHolder helper, MyDeckItem item) {
helper.setText(R.id.my_deck_name, item.getDeckName());
helper.setText(R.id.deck_update_date, item.getUpdateDate());
ImageView cardImage = helper.getView(R.id.deck_info_image);
long code = item.getDeckCoverCard1();
if (item.getPublic()) {
helper.setText(R.id.change_show_or_hide, R.string.in_public);
helper.getView(R.id.show_on_deck_square).setBackgroundResource(R.drawable.baseline_remove_red_eye_24);
helper.getView(R.id.ll_switch_show).setBackgroundResource(R.drawable.button_radius_red);
} else {
helper.setText(R.id.change_show_or_hide, R.string.in_personal_use);
helper.getView(R.id.show_on_deck_square).setBackgroundResource(R.drawable.closed_eyes_24);
helper.getView(R.id.ll_switch_show).setBackgroundResource(R.drawable.button_radius_n);
}
LogUtil.i(TAG, code + " " + item.getDeckName());
if (code != 0) {
imageLoader.bindImage(cardImage, code, null, ImageLoader.Type.small);
} else {
imageLoader.bindImage(cardImage, -1, null, ImageLoader.Type.small);
}
helper.getView(R.id.delete_my_online_deck_btn).setOnClickListener(view -> {
deleteMyDeckOnLine(item);
});
helper.getView(R.id.ll_switch_show).setOnClickListener(view -> {
if (item.getPublic()) {
helper.setText(R.id.change_show_or_hide, R.string.in_personal_use);
helper.getView(R.id.show_on_deck_square).setBackgroundResource(R.drawable.closed_eyes_24);
helper.getView(R.id.ll_switch_show).setBackgroundResource(R.drawable.button_radius_n);
item.setPublic(false);
} else {
helper.setText(R.id.change_show_or_hide, R.string.in_public);
helper.getView(R.id.show_on_deck_square).setBackgroundResource(R.drawable.baseline_remove_red_eye_24);
helper.getView(R.id.ll_switch_show).setBackgroundResource(R.drawable.button_radius_red);
item.setPublic(true);
}
LogUtil.i(TAG, "current " + item.toString());
changeDeckPublicState(item);
});
helper.getView(R.id.ll_download).setOnClickListener(view -> {
//TODO
//点击“我的卡组”中的某个卡组后,弹出dialog,dialog根据卡组的同步情况自动显示对应的下载/上传按钮
DeckFile deckFile = new DeckFile(item.getDeckId(), DeckType.ServerType.MY_SQUARE);
});
}
}
\ No newline at end of file
package cn.garymb.ygomobile.deck_square;
import java.util.List;
public class UserDeckIds {
public List<String> deckId;
}
package cn.garymb.ygomobile.deck_square.api_response;
public class BasicResponse {
private Integer code;
private String message;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 后端设计的有点怪,接口成功时,message的内容为“true”
* @return
*/
public boolean isMessageTrue(){
return message.equals("true");
}
}
package cn.garymb.ygomobile.deck_square.api_response;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class DeckIdResponse {
@Expose
public int code;
@Expose
public String message;
@Expose
@SerializedName("data")
public String deckId;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
@Override
public String toString() {
return "DeckIdResponse{" +
"code=" + code +
", message='" + message + '\'' +
", deckId='" + deckId + '\'' +
'}';
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class DeleteCardJson {
private String deckContributor;
private Integer userId;
private DeckData deck;
public String getDeckContributor() {
return deckContributor;
}
public void setDeckContributor(String deckContributor) {
this.deckContributor = deckContributor;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public DeckData getDeck() {
return deck;
}
public void setDeck(DeckData deck) {
this.deck = deck;
}
public static class DeckData {
private boolean isDelete = false;
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean delete) {
isDelete = delete;
}
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class DownloadDeckResponse {
private Integer code;
private String message;
private MyOnlineDeckDetail data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MyOnlineDeckDetail getData() {
return data;
}
public void setData(MyOnlineDeckDetail data) {
this.data = data;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class GetSquareDeckCondition {
Integer page;
Integer size;
String keyWord;
Boolean sortLike;
Boolean sortRank;
String contributor;
public GetSquareDeckCondition() {
}
public GetSquareDeckCondition(Integer page, Integer size, String keyWord, Boolean sortLike, Boolean sortRank, String contributor) {
this.page = page;
this.size = size;
this.keyWord = keyWord;
this.sortLike = sortLike;
this.sortRank = sortRank;
this.contributor = contributor;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public String getKeyWord() {
return keyWord;
}
public void setKeyWord(String keyWord) {
this.keyWord = keyWord;
}
public Boolean getSortLike() {
return sortLike;
}
public void setSortLike(Boolean sortLike) {
this.sortLike = sortLike;
}
public Boolean getSortRank() {
return sortRank;
}
public void setSortRank(Boolean sortRank) {
this.sortRank = sortRank;
}
public String getContributor() {
return contributor;
}
public void setContributor(String contributor) {
this.contributor = contributor;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class LoginRequest {
public String account;
public String password;
public LoginRequest(String account, String password) {
this.account = account;
this.password = password;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class LoginResponse {
public String token;
public Boolean success;
public User user;
public static class User {
public int id;
public String username;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class LoginToken {
Integer userId;
String serverToken;
public LoginToken(Integer userId, String serverToken) {
this.userId = userId;
this.serverToken = serverToken;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getServerToken() {
return serverToken;
}
public void setServerToken(String serverToken) {
this.serverToken = serverToken;
}
@Override
public String toString() {
return "LoginToken{" +
"userId=" + userId +
", serverToken='" + serverToken + '\'' +
'}';
}
}
package cn.garymb.ygomobile.deck_square.api_response;
import java.util.List;
public class MyDeckResponse {
public Integer code;
public String message;
public List<MyOnlineDeckDetail> data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<MyOnlineDeckDetail> getData() {
return data;
}
public void setData(List<MyOnlineDeckDetail> data) {
this.data = data;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
public class MyOnlineDeckDetail implements Parcelable {
private String deckId;
private String deckContributor;
private String deckName;
private String deckRank;
private String deckLike;
private String deckUploadDate;
private String deckUpdateDate;
private int deckCoverCard1;
private int deckCoverCard2;
private int deckCoverCard3;
private String deckCase;
private String deckProtector;
private String deckMainSerial;
private String deckYdk;
private Integer userId;
private boolean isPublic;
private boolean isDelete;
protected MyOnlineDeckDetail(Parcel in) {
deckId = in.readString();
deckContributor = in.readString();
deckName = in.readString();
deckRank = in.readString();
deckLike = in.readString();
deckUploadDate = in.readString();
deckUpdateDate = in.readString();
deckCoverCard1 = in.readInt();
deckCoverCard2 = in.readInt();
deckCoverCard3 = in.readInt();
deckCase = in.readString();
deckProtector = in.readString();
deckMainSerial = in.readString();
deckYdk = in.readString();
userId = in.readInt();
isPublic = (in.readByte() != 0);
isDelete = (in.readByte() != 0);
}
public static final Creator<MyOnlineDeckDetail> CREATOR = new Creator<MyOnlineDeckDetail>() {
@Override
public MyOnlineDeckDetail createFromParcel(Parcel in) {
return new MyOnlineDeckDetail(in);
}
@Override
public MyOnlineDeckDetail[] newArray(int size) {
return new MyOnlineDeckDetail[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(deckId);
dest.writeString(deckContributor);
dest.writeString(deckName);
dest.writeString(deckRank);
dest.writeString(deckLike);
dest.writeString(deckUploadDate);
dest.writeString(deckUpdateDate);
dest.writeInt(deckCoverCard1);
dest.writeInt(deckCoverCard2);
dest.writeInt(deckCoverCard3);
dest.writeString(deckCase);
dest.writeString(deckProtector);
dest.writeString(deckMainSerial);
dest.writeString(deckYdk);
dest.writeInt(userId);
dest.writeByte((byte) (isPublic ? 1 : 0));
dest.writeByte((byte) (isDelete ? 1 : 0));
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
public String getDeckContributor() {
return deckContributor;
}
public void setDeckContributor(String deckContributor) {
this.deckContributor = deckContributor;
}
public String getDeckName() {
return deckName;
}
public void setDeckName(String deckName) {
this.deckName = deckName;
}
public String getDeckRank() {
return deckRank;
}
public void setDeckRank(String deckRank) {
this.deckRank = deckRank;
}
public String getDeckLike() {
return deckLike;
}
public void setDeckLike(String deckLike) {
this.deckLike = deckLike;
}
public String getDeckUploadDate() {
return deckUploadDate;
}
public void setDeckUploadDate(String deckUploadDate) {
this.deckUploadDate = deckUploadDate;
}
public String getDeckUpdateDate() {
return deckUpdateDate;
}
public void setDeckUpdateDate(String deckUpdateDate) {
this.deckUpdateDate = deckUpdateDate;
}
public int getDeckCoverCard1() {
return deckCoverCard1;
}
public void setDeckCoverCard1(int deckCoverCard1) {
this.deckCoverCard1 = deckCoverCard1;
}
public int getDeckCoverCard2() {
return deckCoverCard2;
}
public void setDeckCoverCard2(int deckCoverCard2) {
this.deckCoverCard2 = deckCoverCard2;
}
public int getDeckCoverCard3() {
return deckCoverCard3;
}
public void setDeckCoverCard3(int deckCoverCard3) {
this.deckCoverCard3 = deckCoverCard3;
}
public String getDeckCase() {
return deckCase;
}
public void setDeckCase(String deckCase) {
this.deckCase = deckCase;
}
public String getDeckProtector() {
return deckProtector;
}
public void setDeckProtector(String deckProtector) {
this.deckProtector = deckProtector;
}
public String getDeckMainSerial() {
return deckMainSerial;
}
public void setDeckMainSerial(String deckMainSerial) {
this.deckMainSerial = deckMainSerial;
}
public String getDeckYdk() {
return deckYdk;
}
public void setDeckYdk(String deckYdk) {
this.deckYdk = deckYdk;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public boolean isPublic() {
return isPublic;
}
public void setPublic(boolean aPublic) {
isPublic = aPublic;
}
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean delete) {
isDelete = delete;
}
}
\ No newline at end of file
package cn.garymb.ygomobile.deck_square.api_response;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
public class OnlineDeckDetail implements Parcelable {
private String deckId;
private String deckContributor;
private String deckName;
private int deckLike;
private int deckCoverCard1;
private int deckCoverCard2;
private int deckCoverCard3;
private int deckCase;
private int deckProtector;
private String lastDate;
private int userId;
protected OnlineDeckDetail(Parcel in) {
deckId = in.readString();
deckContributor = in.readString();
deckName = in.readString();
deckLike = in.readInt();
deckCoverCard1 = in.readInt();
deckCoverCard2 = in.readInt();
deckCoverCard3 = in.readInt();
deckCase = in.readInt();
deckProtector = in.readInt();
lastDate = in.readString();
userId = in.readInt();
}
public static final Creator<OnlineDeckDetail> CREATOR = new Creator<OnlineDeckDetail>() {
@Override
public OnlineDeckDetail createFromParcel(Parcel in) {
return new OnlineDeckDetail(in);
}
@Override
public OnlineDeckDetail[] newArray(int size) {
return new OnlineDeckDetail[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(deckId);
dest.writeString(deckContributor);
dest.writeString(deckName);
dest.writeInt(deckLike);
dest.writeInt(deckCoverCard1);
dest.writeInt(deckCoverCard2);
dest.writeInt(deckCoverCard3);
dest.writeInt(deckCase);
dest.writeInt(deckProtector);
dest.writeString(lastDate);
dest.writeInt(userId);
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
public String getDeckContributor() {
return deckContributor;
}
public void setDeckContributor(String deckContributor) {
this.deckContributor = deckContributor;
}
public String getDeckName() {
return deckName;
}
public void setDeckName(String deckName) {
this.deckName = deckName;
}
public int getDeckLike() {
return deckLike;
}
public void setDeckLike(int deckLike) {
this.deckLike = deckLike;
}
public int getDeckCoverCard1() {
return deckCoverCard1;
}
public void setDeckCoverCard1(int deckCoverCard1) {
this.deckCoverCard1 = deckCoverCard1;
}
public int getDeckCoverCard2() {
return deckCoverCard2;
}
public void setDeckCoverCard2(int deckCoverCard2) {
this.deckCoverCard2 = deckCoverCard2;
}
public int getDeckCoverCard3() {
return deckCoverCard3;
}
public void setDeckCoverCard3(int deckCoverCard3) {
this.deckCoverCard3 = deckCoverCard3;
}
public int getDeckCase() {
return deckCase;
}
public void setDeckCase(int deckCase) {
this.deckCase = deckCase;
}
public int getDeckProtector() {
return deckProtector;
}
public void setDeckProtector(int deckProtector) {
this.deckProtector = deckProtector;
}
public String getLastDate() {
return lastDate;
}
public void setLastDate(String lastDate) {
this.lastDate = lastDate;
}
public Integer getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class PushCardJson {
private String deckContributor;
private Integer userId;
private DeckData deck;
public String getDeckContributor() {
return deckContributor;
}
public void setDeckContributor(String deckContributor) {
this.deckContributor = deckContributor;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public DeckData getDeck() {
return deck;
}
public void setDeck(DeckData deck) {
this.deck = deck;
}
public static class DeckData {
private String deckId;
private String deckName;
private Integer deckCoverCard1 = 0;
private Integer deckCoverCard2 = 0;
private Integer deckCoverCard3 = 0;
private Integer deckCase = 0;
private Integer deckProtector = 0;
private String deckYdk;
private boolean isDelete = false;
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
public String getDeckName() {
return deckName;
}
public void setDeckName(String deckName) {
this.deckName = deckName;
}
public Integer getDeckCoverCard1(Integer firstCode) {
return deckCoverCard1;
}
public void setDeckCoverCard1(Integer deckCoverCard1) {
this.deckCoverCard1 = deckCoverCard1;
}
public Integer getDeckCoverCard2() {
return deckCoverCard2;
}
public void setDeckCoverCard2(Integer deckCoverCard2) {
this.deckCoverCard2 = deckCoverCard2;
}
public Integer getDeckCoverCard3() {
return deckCoverCard3;
}
public void setDeckCoverCard3(Integer deckCoverCard3) {
this.deckCoverCard3 = deckCoverCard3;
}
public Integer getDeckCase() {
return deckCase;
}
public void setDeckCase(Integer deckCase) {
this.deckCase = deckCase;
}
public Integer getDeckProtector() {
return deckProtector;
}
public void setDeckProtector(Integer deckProtector) {
this.deckProtector = deckProtector;
}
public String getDeckYdk() {
return deckYdk;
}
public void setDeckYdk(String deckYdk) {
this.deckYdk = deckYdk;
}
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean delete) {
isDelete = delete;
}
}
}
package cn.garymb.ygomobile.deck_square.api_response;
public class PushDeckPublicState {
private Integer userId;
private String deckId;
private boolean isPublic;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getDeckId() {
return deckId;
}
public void setDeckId(String deckId) {
this.deckId = deckId;
}
public boolean isPublic() {
return isPublic;
}
public void setPublic(boolean aPublic) {
isPublic = aPublic;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
//将卡组上传后,返回的响应
//对应接口http://rarnu.xyz:38383/api/mdpro3/sync/single
public class PushDeckResponse {
private Integer code;
private String message;
private boolean data;//服务器的执行结果,true代表卡组上传成功。false代表卡组上传失败
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public boolean isData() {
return data;
}
public void setData(boolean data) {
this.data = data;
}
}
package cn.garymb.ygomobile.deck_square.api_response;
import java.util.List;
public class SquareDeckResponse {
private Integer code;
private String message;
private ApiData data;
public static class ApiData {
private int current;
private int size;
private int total;
private int pages;
private List<OnlineDeckDetail> records;
// Getters and setters
public int getCurrent() {
return current;
}
public int getSize() {
return size;
}
public int getTotal() {
return total;
}
public int getPages() {
return pages;
}
public List<OnlineDeckDetail> getRecords() {
return records;
}
}
// Getters and setters
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public ApiData getData() {
return data;
}
}
...@@ -29,7 +29,6 @@ import okhttp3.Response; ...@@ -29,7 +29,6 @@ import okhttp3.Response;
public class ExCardListAdapter extends BaseQuickAdapter<ExCardData, BaseViewHolder> { public class ExCardListAdapter extends BaseQuickAdapter<ExCardData, BaseViewHolder> {
private static final String TAG = ExCardListAdapter.class.getSimpleName(); private static final String TAG = ExCardListAdapter.class.getSimpleName();
private ImageLoader imageLoader;
public ExCardListAdapter(int layoutResId) { public ExCardListAdapter(int layoutResId) {
super(layoutResId); super(layoutResId);
......
...@@ -185,7 +185,9 @@ public class ExCardListFragment extends Fragment { ...@@ -185,7 +185,9 @@ public class ExCardListFragment extends Fragment {
enum DownloadState { enum DownloadState {
DOWNLOAD_ING, DOWNLOAD_ING,
NO_DOWNLOAD NO_DOWNLOAD
} @SuppressLint("HandlerLeak") }
@SuppressLint("HandlerLeak")
Handler handler = new Handler() { Handler handler = new Handler() {
@Override @Override
...@@ -209,7 +211,8 @@ public class ExCardListFragment extends Fragment { ...@@ -209,7 +211,8 @@ public class ExCardListFragment extends Fragment {
// break; // break;
case DownloadUtil.TYPE_DOWNLOAD_OK: case DownloadUtil.TYPE_DOWNLOAD_OK:
downloadState = DownloadState.NO_DOWNLOAD; downloadState = DownloadState.NO_DOWNLOAD;
AddServer(getActivity(), context.getString(R.string.Pre_Server_Name), context.getString(R.string.tip_superpre_desc), Constants.URL_Mycard_Super_Pre_Server, Constants.PORT_Mycard_Super_Pre_Server, "Knight of Hanoi"); AddServer(getActivity(), context.getString(R.string.Pre_Server_Name), context.getString(R.string.tip_superpre_desc),
Constants.URL_Mycard_Super_Pre_Server, Constants.PORT_Mycard_Super_Pre_Server, "Knight of Hanoi");
//changeDownloadButton();在下载完成后,通过EventBus通知下载完成(加入用户点击下载后临时切出本fragment,又在下载完成后切回,通过eventbus能保证按钮样式正确更新 //changeDownloadButton();在下载完成后,通过EventBus通知下载完成(加入用户点击下载后临时切出本fragment,又在下载完成后切回,通过eventbus能保证按钮样式正确更新
/* 注意,要先更新版本号 */ /* 注意,要先更新版本号 */
SharedPreferenceUtil.setExpansionDataVer(ServerUtil.serverExCardVersion); SharedPreferenceUtil.setExpansionDataVer(ServerUtil.serverExCardVersion);
...@@ -237,6 +240,4 @@ public class ExCardListFragment extends Fragment { ...@@ -237,6 +240,4 @@ public class ExCardListFragment extends Fragment {
}; };
} }
\ No newline at end of file
package cn.garymb.ygomobile.loader; package cn.garymb.ygomobile.loader;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
...@@ -13,8 +12,6 @@ import java.util.Comparator; ...@@ -13,8 +12,6 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import cn.garymb.ygomobile.Constants; import cn.garymb.ygomobile.Constants;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.ui.plus.DialogPlus;
import cn.garymb.ygomobile.ui.plus.VUiKit; import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.CardSort; import cn.garymb.ygomobile.utils.CardSort;
import cn.garymb.ygomobile.utils.LogUtil; import cn.garymb.ygomobile.utils.LogUtil;
...@@ -27,9 +24,9 @@ import ocgcore.enums.LimitType; ...@@ -27,9 +24,9 @@ import ocgcore.enums.LimitType;
/** /**
* 包括LimitManager、CardManager、LimitList * 包括LimitManager、CardManager、LimitList
* <p>
* LimitList负责判断禁止卡等 * LimitList负责判断禁止卡等
* field包括LimitManager、CardManager * LimitManager、CardManager已封装成单例,使用时不需要构造实例
* 未封装成单例,使用时要构造实例
*/ */
public class CardLoader implements ICardSearcher { public class CardLoader implements ICardSearcher {
private final LimitManager mLimitManager; private final LimitManager mLimitManager;
......
...@@ -20,9 +20,11 @@ import java.nio.charset.StandardCharsets; ...@@ -20,9 +20,11 @@ import java.nio.charset.StandardCharsets;
import cn.garymb.ygomobile.Constants; import cn.garymb.ygomobile.Constants;
import cn.garymb.ygomobile.bean.Deck; import cn.garymb.ygomobile.bean.Deck;
import cn.garymb.ygomobile.bean.DeckInfo; import cn.garymb.ygomobile.bean.DeckInfo;
import cn.garymb.ygomobile.deck_square.DeckSquareListAdapter;
import cn.garymb.ygomobile.ui.cards.deck.DeckItemType; import cn.garymb.ygomobile.ui.cards.deck.DeckItemType;
import cn.garymb.ygomobile.ui.cards.deck.DeckUtils; import cn.garymb.ygomobile.ui.cards.deck.DeckUtils;
import cn.garymb.ygomobile.utils.IOUtils; import cn.garymb.ygomobile.utils.IOUtils;
import cn.garymb.ygomobile.utils.LogUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import ocgcore.data.Card; import ocgcore.data.Card;
import ocgcore.data.LimitList; import ocgcore.data.LimitList;
...@@ -30,12 +32,12 @@ import ocgcore.data.LimitList; ...@@ -30,12 +32,12 @@ import ocgcore.data.LimitList;
public class DeckLoader { public class DeckLoader {
private static Boolean isChanged; private static Boolean isChanged;
public static DeckInfo readDeck(CardLoader cardLoader, File file, LimitList limitList) { public static DeckInfo readDeck(CardLoader cardLoader, File file) {
DeckInfo deckInfo = null; DeckInfo deckInfo = null;
FileInputStream fileinputStream = null; FileInputStream fileinputStream = null;
try { try {
fileinputStream = new FileInputStream(file); fileinputStream = new FileInputStream(file);
deckInfo = readDeck(cardLoader, fileinputStream, limitList); deckInfo = readDeck(cardLoader, fileinputStream);
if (deckInfo != null) { if (deckInfo != null) {
deckInfo.source = file; deckInfo.source = file;
if (isChanged) { if (isChanged) {
...@@ -51,7 +53,7 @@ public class DeckLoader { ...@@ -51,7 +53,7 @@ public class DeckLoader {
return deckInfo; return deckInfo;
} }
private static DeckInfo readDeck(CardLoader cardLoader, InputStream inputStream, LimitList limitList) { private static DeckInfo readDeck(CardLoader cardLoader, InputStream inputStream) {
Deck deck = new Deck(); Deck deck = new Deck();
SparseArray<Integer> mIds = new SparseArray<>(); SparseArray<Integer> mIds = new SparseArray<>();
InputStreamReader in = null; InputStreamReader in = null;
...@@ -60,6 +62,7 @@ public class DeckLoader { ...@@ -60,6 +62,7 @@ public class DeckLoader {
in = new InputStreamReader(inputStream, StandardCharsets.UTF_8); in = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(in); BufferedReader reader = new BufferedReader(in);
String line = null; String line = null;
//按行读取ydk文件
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
if (line.startsWith("!side")) { if (line.startsWith("!side")) {
type = DeckItemType.SideCard; type = DeckItemType.SideCard;
......
...@@ -5,6 +5,7 @@ import android.content.Context; ...@@ -5,6 +5,7 @@ import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build; import android.os.Build;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
...@@ -15,14 +16,22 @@ import com.chad.library.adapter.base.listener.OnItemClickListener; ...@@ -15,14 +16,22 @@ import com.chad.library.adapter.base.listener.OnItemClickListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import cn.garymb.ygomobile.Constants;
import cn.garymb.ygomobile.bean.Deck; import cn.garymb.ygomobile.bean.Deck;
import cn.garymb.ygomobile.bean.DeckInfo; import cn.garymb.ygomobile.bean.DeckInfo;
import cn.garymb.ygomobile.bean.TextSelect; import cn.garymb.ygomobile.bean.TextSelect;
import cn.garymb.ygomobile.bean.events.DeckFile; import cn.garymb.ygomobile.bean.events.DeckFile;
import cn.garymb.ygomobile.deck_square.DeckSquareApiUtil;
import cn.garymb.ygomobile.deck_square.DeckSquareListAdapter;
import cn.garymb.ygomobile.deck_square.api_response.LoginToken;
import cn.garymb.ygomobile.deck_square.api_response.PushDeckResponse;
import cn.garymb.ygomobile.lite.R; import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.CardLoader; import cn.garymb.ygomobile.loader.CardLoader;
import cn.garymb.ygomobile.loader.DeckLoader; import cn.garymb.ygomobile.loader.DeckLoader;
import cn.garymb.ygomobile.loader.ImageLoader; import cn.garymb.ygomobile.loader.ImageLoader;
import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.LogUtil;
import cn.garymb.ygomobile.utils.SharedPreferenceUtil;
import cn.garymb.ygomobile.utils.YGOUtil; import cn.garymb.ygomobile.utils.YGOUtil;
import ocgcore.DataManager; import ocgcore.DataManager;
import ocgcore.data.LimitList; import ocgcore.data.LimitList;
...@@ -38,9 +47,11 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -38,9 +47,11 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
private OnItemSelectListener onItemSelectListener; private OnItemSelectListener onItemSelectListener;
private int selectPosition; private int selectPosition;
private final boolean isSelect; private final boolean isSelect;
private boolean isManySelect; private boolean isManySelect;//标志位,是否选中多个卡组
private final List<T> selectList; private final List<T> selectList;
private static final String TAG = DeckSquareListAdapter.class.getSimpleName();
public DeckListAdapter(Context context, List<T> data, int select) { public DeckListAdapter(Context context, List<T> data, int select) {
super(R.layout.item_deck_list_swipe, data); super(R.layout.item_deck_list_swipe, data);
this.selectPosition = select; this.selectPosition = select;
...@@ -66,8 +77,40 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -66,8 +77,40 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
deckInfo = new DeckInfo(); deckInfo = new DeckInfo();
mLimitList = DataManager.get().getLimitManager().getTopLimit(); mLimitList = DataManager.get().getLimitManager().getTopLimit();
mContext = context; mContext = context;
addChildClickViewIds(R.id.local_deck_upload_btn);
LogUtil.i(TAG, "DeckListAdapter constructor");
setOnItemChildClickListener((adapter, view, position) -> {
//判断是否登录,如果未登录,直接返回
LoginToken loginToken = DeckSquareApiUtil.getLoginData();
if (loginToken == null) {
return;
}
//获得点击的卡组
DeckFile deckFile = (DeckFile) adapter.getData().get(position);
LogUtil.i(TAG, "deckFile " + deckFile.toString());
//上传卡组
VUiKit.defer().when(() -> {
PushDeckResponse result = DeckSquareApiUtil.requestIdAndPushDeck(deckFile,loginToken);
return result;
}).fail(e -> {
LogUtil.i(TAG, "square deck detail fail" + e.getMessage());
}).done(pushDeckResponse -> {
if (pushDeckResponse.isData()) {
YGOUtil.showTextToast("push success!");
} else {
YGOUtil.showTextToast("卡组上传失败!");
}
});
});
} }
@SuppressLint("ResourceType") @SuppressLint("ResourceType")
@Override @Override
protected void convert(DeckViewHolder holder, T item) { protected void convert(DeckViewHolder holder, T item) {
...@@ -76,7 +119,7 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -76,7 +119,7 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
this.deckFile = (DeckFile) item; this.deckFile = (DeckFile) item;
holder.deckName.setText(item.getName()); holder.deckName.setText(item.getName());
//预读卡组信息 //预读卡组信息
this.deckInfo = DeckLoader.readDeck(mCardLoader, deckFile.getPathFile(), mLimitList); this.deckInfo = DeckLoader.readDeck(mCardLoader, deckFile.getPathFile());
//加载卡组第一张卡的图 //加载卡组第一张卡的图
holder.cardImage.setVisibility(View.VISIBLE); holder.cardImage.setVisibility(View.VISIBLE);
imageLoader.bindImage(holder.cardImage, deckFile.getFirstCode(), ImageLoader.Type.middle); imageLoader.bindImage(holder.cardImage, deckFile.getFirstCode(), ImageLoader.Type.middle);
...@@ -106,7 +149,8 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -106,7 +149,8 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
holder.side.setText("-"); holder.side.setText("-");
holder.side.setTextColor(Color.RED); holder.side.setTextColor(Color.RED);
} }
if (deckFile.getTypeName().equals(YGOUtil.s(R.string.category_pack)) || deckFile.getPath().contains("cacheDeck")) {//卡包展示时不显示额外和副卡组数量文本 if (deckFile.getTypeName().equals(YGOUtil.s(R.string.category_pack)) || deckFile.getPath().contains("cacheDeck")) {
//卡包展示时不显示额外和副卡组数量文本
holder.ll_extra_n_side.setVisibility(View.GONE); holder.ll_extra_n_side.setVisibility(View.GONE);
} else { } else {
holder.ll_extra_n_side.setVisibility(View.VISIBLE); holder.ll_extra_n_side.setVisibility(View.VISIBLE);
...@@ -178,6 +222,14 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -178,6 +222,14 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
} else { } else {
holder.item_deck_list.setBackgroundResource(Color.TRANSPARENT); holder.item_deck_list.setBackgroundResource(Color.TRANSPARENT);
} }
//卡包展示、人机卡组不显示上传按钮图标
if (deckFile.getPathFile().getParent().endsWith(Constants.CORE_PACK_PATH)
|| deckFile.getPathFile().getParent().endsWith(Constants.WINDBOT_DECK_PATH)
||deckFile.getPathFile().getParent().endsWith("cacheDeck")) {
holder.local_deck_upload_btn.setVisibility(View.GONE);
} else {
holder.local_deck_upload_btn.setVisibility(View.VISIBLE);
}
} }
public void setSelectPosition(int selectPosition) { public void setSelectPosition(int selectPosition) {
...@@ -199,6 +251,12 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -199,6 +251,12 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
selectList.add(t); selectList.add(t);
} }
/**
* 内部维护了selectList,用于存储当前选中的卡组
* DeckListAdapter支持多选,传入false清除已选中的卡组,并更新adapter。传入true将标志位置1
*
* @param manySelect
*/
public void setManySelect(boolean manySelect) { public void setManySelect(boolean manySelect) {
isManySelect = manySelect; isManySelect = manySelect;
if (!isManySelect) { if (!isManySelect) {
...@@ -222,6 +280,8 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D ...@@ -222,6 +280,8 @@ public class DeckListAdapter<T extends TextSelect> extends BaseQuickAdapter<T, D
public interface OnItemSelectListener<T> { public interface OnItemSelectListener<T> {
void onItemSelect(int position, T item); void onItemSelect(int position, T item);
} }
} }
class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHolder { class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHolder {
...@@ -229,12 +289,14 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo ...@@ -229,12 +289,14 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo
ImageView prerelease_star; ImageView prerelease_star;
ImageView banned_mark; ImageView banned_mark;
TextView deckName; TextView deckName;
TextView deckId;
TextView main; TextView main;
TextView extra; TextView extra;
TextView side; TextView side;
LinearLayout ll_extra_n_side; LinearLayout ll_extra_n_side;
View item_deck_list; View item_deck_list;
View deck_info; View deck_info;
Button local_deck_upload_btn;
public DeckViewHolder(View view) { public DeckViewHolder(View view) {
super(view); super(view);
...@@ -242,6 +304,7 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo ...@@ -242,6 +304,7 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo
item_deck_list = findView(R.id.item_deck_list); item_deck_list = findView(R.id.item_deck_list);
cardImage = findView(R.id.card_image); cardImage = findView(R.id.card_image);
deckName = findView(R.id.deck_name); deckName = findView(R.id.deck_name);
deckId = findView(R.id.onlie_deck_id);
main = findView(R.id.count_main); main = findView(R.id.count_main);
extra = findView(R.id.count_ex); extra = findView(R.id.count_ex);
side = findView(R.id.count_side); side = findView(R.id.count_side);
...@@ -249,5 +312,6 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo ...@@ -249,5 +312,6 @@ class DeckViewHolder extends com.chad.library.adapter.base.viewholder.BaseViewHo
prerelease_star = findView(R.id.prerelease_star); prerelease_star = findView(R.id.prerelease_star);
banned_mark = findView(R.id.banned_mark); banned_mark = findView(R.id.banned_mark);
deck_info = findView(R.id.deck_info); deck_info = findView(R.id.deck_info);
local_deck_upload_btn = findView(R.id.local_deck_upload_btn);
} }
} }
\ No newline at end of file
package cn.garymb.ygomobile.ui.adapters;
import androidx.annotation.NonNull;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import java.util.List;
import cn.garymb.ygomobile.ex_card.ExCardListAdapter;
import cn.garymb.ygomobile.lite.R;
import ocgcore.data.Card;
//卡组预览的adapter
public class DeckPreviewListAdapter extends BaseQuickAdapter<Card, BaseViewHolder> {
private static final String TAG = ExCardListAdapter.class.getSimpleName();
public DeckPreviewListAdapter(int layoutResId) {
super(layoutResId);
}
public void updateData(List<Card> dataList) {
getData().clear();
addData(dataList);
notifyDataSetChanged();
}
@Override
protected void convert(@NonNull BaseViewHolder baseViewHolder, Card item) {
baseViewHolder.setText(R.id.preview_card_name, item.Name);
baseViewHolder.setText(R.id.preview_card_id, Integer.toString(item.Code));
}
}
...@@ -37,7 +37,7 @@ public class TextSelectAdapter<T extends TextSelect> extends BaseQuickAdapter<T, ...@@ -37,7 +37,7 @@ public class TextSelectAdapter<T extends TextSelect> extends BaseQuickAdapter<T,
selectPosition = position; selectPosition = position;
notifyDataSetChanged(); notifyDataSetChanged();
if (onItemSelectListener != null) if (onItemSelectListener != null)
onItemSelectListener.onItemSelect(position, data.get(position).getObject()); onItemSelectListener.onItemSelect(position, data.get(position));
} }
}); });
} }
...@@ -59,7 +59,7 @@ public class TextSelectAdapter<T extends TextSelect> extends BaseQuickAdapter<T, ...@@ -59,7 +59,7 @@ public class TextSelectAdapter<T extends TextSelect> extends BaseQuickAdapter<T,
} else { } else {
helper.setBackgroundResource(R.id.ll_layout, Color.TRANSPARENT); helper.setBackgroundResource(R.id.ll_layout, Color.TRANSPARENT);
} }
}else { } else {
helper.setBackgroundResource(R.id.ll_layout, Color.TRANSPARENT); helper.setBackgroundResource(R.id.ll_layout, Color.TRANSPARENT);
} }
......
...@@ -19,7 +19,7 @@ import android.widget.Toast; ...@@ -19,7 +19,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.RecyclerViewItemListener; import androidx.recyclerview.widget.RecyclerViewItemListener;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.FastScrollLinearLayoutManager; import androidx.recyclerview.widget.FastScrollLinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
......
...@@ -32,6 +32,9 @@ import ocgcore.data.LimitList; ...@@ -32,6 +32,9 @@ import ocgcore.data.LimitList;
import ocgcore.enums.CardType; import ocgcore.enums.CardType;
import ocgcore.enums.LimitType; import ocgcore.enums.LimitType;
/**
* 在对应的recyclerview中添加了很多透明的item来“占位”,占位后便于根据“拖动卡片的位置”计算添加的卡片类型(是主卡组、额外卡组还是副卡组)
*/
public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implements CardListProvider { public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implements CardListProvider {
private final List<DeckItem> mItems = new ArrayList<>(); private final List<DeckItem> mItems = new ArrayList<>();
private final SparseArray<Integer> mCount = new SparseArray<>(); private final SparseArray<Integer> mCount = new SparseArray<>();
...@@ -107,7 +110,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -107,7 +110,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
int id = DeckItem.MainStart + getMainCount(); int id = DeckItem.MainStart + getMainCount();
removeItem(DeckItem.MainEnd); removeItem(DeckItem.MainEnd);
addItem(id, new DeckItem(cardInfo, type)); addItem(id, new DeckItem(cardInfo, type));
notifyItemChanged(DeckItem.MainEnd); //notifyItemChanged(DeckItem.MainEnd);//todo 这行好像没啥用啊??
notifyItemChanged(id); notifyItemChanged(id);
notifyItemChanged(DeckItem.MainLabel); notifyItemChanged(DeckItem.MainLabel);
return true; return true;
...@@ -403,7 +406,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -403,7 +406,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
if (limitList != null) { if (limitList != null) {
setLimitList(limitList); setLimitList(limitList);
} }
return DeckLoader.readDeck(cardLoader, file, limitList); return DeckLoader.readDeck(cardLoader, file);
} }
public boolean save(File file) { public boolean save(File file) {
...@@ -445,12 +448,6 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -445,12 +448,6 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
return !TextUtils.equals(mDeckMd5, md5); return !TextUtils.equals(mDeckMd5, md5);
} }
@Override
public DeckViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.item_deck_card, parent, false);
return new DeckViewHolder(view);
}
private String getString(int id, Object... args) { private String getString(int id, Object... args) {
return context.getString(id, args); return context.getString(id, args);
} }
...@@ -536,13 +533,22 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -536,13 +533,22 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
// notifyItemChanged(DeckItem.HeadView); // notifyItemChanged(DeckItem.HeadView);
} }
@Override
public DeckViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Inflating a layout from XML and returning the holder
View view = mLayoutInflater.inflate(R.layout.item_deck_card, parent, false);
return new DeckViewHolder(view);
}
@Override @Override
public void onBindViewHolder(DeckViewHolder holder, int position) { public void onBindViewHolder(DeckViewHolder holder, int position) {
//Populating data into the item through holder
//根据data的内容调整view的样式
DeckItem item = mItems.get(position); DeckItem item = mItems.get(position);
holder.setItemType(item.getType()); holder.setItemType(item.getType());
if (item.getType() == DeckItemType.MainLabel || item.getType() == DeckItemType.SideLabel if (item.getType() == DeckItemType.MainLabel || item.getType() == DeckItemType.SideLabel
|| item.getType() == DeckItemType.ExtraLabel) { || item.getType() == DeckItemType.ExtraLabel) {//处理分隔栏的item view
//分隔栏
if (item.getType() == DeckItemType.MainLabel) { if (item.getType() == DeckItemType.MainLabel) {
holder.setText(getMainString()); holder.setText(getMainString());
} else if (item.getType() == DeckItemType.SideLabel) { } else if (item.getType() == DeckItemType.SideLabel) {
...@@ -550,7 +556,8 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -550,7 +556,8 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
} else if (item.getType() == DeckItemType.ExtraLabel) { } else if (item.getType() == DeckItemType.ExtraLabel) {
holder.setText(getExtraString()); holder.setText(getExtraString());
} }
} else { } else {//处理展示卡图的item view
/* 动态计算控件的高度,优先根据卡图的实际大小计算高度,如果结果<=0,则根据recyclerView的宽度计算控件高度 */
if (mHeight <= 0) { if (mHeight <= 0) {
if (holder.cardImage.getMeasuredWidth() > 0) { if (holder.cardImage.getMeasuredWidth() > 0) {
mWidth = holder.cardImage.getMeasuredWidth(); mWidth = holder.cardImage.getMeasuredWidth();
...@@ -567,11 +574,10 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -567,11 +574,10 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
//显示卡片 //显示卡片
holder.showImage(); holder.showImage();
holder.setSize(mHeight); holder.setSize(mHeight);
if (item.getType() == DeckItemType.Space) { if (item.getType() == DeckItemType.Space) {//占位,不显示卡图
//占位但是不显示卡图
holder.setCardType(0); holder.setCardType(0);
holder.showEmpty(); holder.showEmpty();
} else { } else {//非占位,显示卡图
Card cardInfo = item.getCardInfo(); Card cardInfo = item.getCardInfo();
// holder.cardImage.setOnClickListener(new View.OnClickListener() { // holder.cardImage.setOnClickListener(new View.OnClickListener() {
...@@ -582,7 +588,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement ...@@ -582,7 +588,7 @@ public class DeckAdapater extends RecyclerView.Adapter<DeckViewHolder> implement
// else // else
// Toast.makeText(context,"空点击"+position,Toast.LENGTH_SHORT).show(); // Toast.makeText(context,"空点击"+position,Toast.LENGTH_SHORT).show();
// } // }
// }); // });//将cardInfo在LimitList中检查,根据结果(限制、准限制、禁止)对应显示卡图
if (cardInfo != null) { if (cardInfo != null) {
holder.setCardType(cardInfo.Type); holder.setCardType(cardInfo.Type);
if (mImageTop == null) { if (mImageTop == null) {
......
package cn.garymb.ygomobile.ui.cards.deck; package cn.garymb.ygomobile.ui.cards.deck;
/**
* DeckItemType的不同值对应着,recyclerView中的item的不同布局形式
*/
public enum DeckItemType { public enum DeckItemType {
MainLabel, MainLabel,//对应“主卡组:60怪兽:21...“这种分隔标签
MainCard, MainCard,//对应主卡组中的卡图控件
ExtraLabel, ExtraLabel,//额外卡组
ExtraCard, ExtraCard,//对应额外卡组中的卡图控件
SideLabel, SideLabel,//副卡组
SideCard, SideCard,//对应副卡组中的卡图控件
Space, Space,//对应占位的卡图控件
Pack Pack
} }
...@@ -109,6 +109,14 @@ class DeckItemUtils { ...@@ -109,6 +109,14 @@ class DeckItemUtils {
return deck; return deck;
} }
/**
* 将file内容更新为List<DeckItem>中的内容
* 删除file,之后将List<DeckItem>中的内容保存到file中
* @param items
* @param file 原有file
* @return 如果file为null,返回false
*/
public static boolean save(List<DeckItem> items, File file) { public static boolean save(List<DeckItem> items, File file) {
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
OutputStreamWriter writer = null; OutputStreamWriter writer = null;
......
...@@ -20,6 +20,7 @@ import cn.garymb.ygomobile.utils.IOUtils; ...@@ -20,6 +20,7 @@ import cn.garymb.ygomobile.utils.IOUtils;
import ocgcore.data.Card; import ocgcore.data.Card;
public class DeckUtils { public class DeckUtils {
//将Deck通过ByteArrayOutputStream)转为String
public static String getDeckString(Deck deck) { public static String getDeckString(Deck deck) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
save(deck, outputStream); save(deck, outputStream);
...@@ -28,6 +29,7 @@ public class DeckUtils { ...@@ -28,6 +29,7 @@ public class DeckUtils {
return str; return str;
} }
//将DeckInfo(通过ByteArrayOutputStream)转为String
public static String getDeckString(DeckInfo deck) { public static String getDeckString(DeckInfo deck) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
save(deck, outputStream); save(deck, outputStream);
...@@ -36,6 +38,13 @@ public class DeckUtils { ...@@ -36,6 +38,13 @@ public class DeckUtils {
return str; return str;
} }
/**
* 将DeckInfo对象以ydk文件的格式存入到outputStream对应的文件中
*
* @param deck
* @param outputStream
* @return
*/
private static boolean save(DeckInfo deck, OutputStream outputStream) { private static boolean save(DeckInfo deck, OutputStream outputStream) {
OutputStreamWriter writer = null; OutputStreamWriter writer = null;
try { try {
...@@ -64,6 +73,8 @@ public class DeckUtils { ...@@ -64,6 +73,8 @@ public class DeckUtils {
return true; return true;
} }
//将Deck对象以ydk文件的格式存入到outputStream对应的文件中
private static boolean save(Deck deck, OutputStream outputStream) { private static boolean save(Deck deck, OutputStream outputStream) {
OutputStreamWriter writer = null; OutputStreamWriter writer = null;
try { try {
...@@ -92,6 +103,7 @@ public class DeckUtils { ...@@ -92,6 +103,7 @@ public class DeckUtils {
return true; return true;
} }
//将deck对象以ydk文件的格式存入到file对应的文件中
public static boolean save(DeckInfo deck, File file) { public static boolean save(DeckInfo deck, File file) {
if (deck == null) return false; if (deck == null) return false;
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
...@@ -113,6 +125,7 @@ public class DeckUtils { ...@@ -113,6 +125,7 @@ public class DeckUtils {
return true; return true;
} }
//将Deck对象以ydk文件的格式存入到File对应的文件中
public static boolean save(Deck deck, File file) { public static boolean save(Deck deck, File file) {
if (deck == null) return false; if (deck == null) return false;
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
...@@ -127,7 +140,7 @@ public class DeckUtils { ...@@ -127,7 +140,7 @@ public class DeckUtils {
outputStream = new FileOutputStream(file); outputStream = new FileOutputStream(file);
save(deck, outputStream); save(deck, outputStream);
} catch (Exception e) { } catch (Exception e) {
Log.e("DeckUtil","保存出错"+e); Log.e("DeckUtil", "保存出错" + e);
//ignore //ignore
} finally { } finally {
IOUtils.close(outputStream); IOUtils.close(outputStream);
...@@ -135,11 +148,12 @@ public class DeckUtils { ...@@ -135,11 +148,12 @@ public class DeckUtils {
return true; return true;
} }
public static File save(String name,String deckMessage) throws IOException { @Deprecated
public static File save(String name, String deckMessage) throws IOException {
FileWriter fw = null; FileWriter fw = null;
//如果文件存在,则重写内容;如果文件不存在,则创建文件 //如果文件存在,则重写内容;如果文件不存在,则创建文件
File f = new File(AppsSettings.get().getDeckDir(),name + Constants.YDK_FILE_EX); File f = new File(AppsSettings.get().getDeckDir(), name + Constants.YDK_FILE_EX);
fw = new FileWriter(f, false); fw = new FileWriter(f, false);
PrintWriter pw = new PrintWriter(fw); PrintWriter pw = new PrintWriter(fw);
......
...@@ -12,7 +12,11 @@ import androidx.recyclerview.widget.RecyclerView; ...@@ -12,7 +12,11 @@ import androidx.recyclerview.widget.RecyclerView;
import cn.garymb.ygomobile.lite.R; import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.ImageLoader; import cn.garymb.ygomobile.loader.ImageLoader;
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
class DeckViewHolder extends RecyclerView.ViewHolder { class DeckViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
private final View view; private final View view;
private final View headView; private final View headView;
private final View textlayout; private final View textlayout;
...@@ -22,8 +26,11 @@ class DeckViewHolder extends RecyclerView.ViewHolder { ...@@ -22,8 +26,11 @@ class DeckViewHolder extends RecyclerView.ViewHolder {
private long mCardType; private long mCardType;
private DeckItemType mItemType; private DeckItemType mItemType;
// Create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public DeckViewHolder(View view) { public DeckViewHolder(View view) {
// Stores the view in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(view); super(view);
this.view = view; this.view = view;
view.setTag(view.getId(), this); view.setTag(view.getId(), this);
...@@ -88,6 +95,10 @@ class DeckViewHolder extends RecyclerView.ViewHolder { ...@@ -88,6 +95,10 @@ class DeckViewHolder extends RecyclerView.ViewHolder {
// imageLoader.$(outFile, cardImage, outFile.getName().endsWith(Constants.BPG), 0, null); // imageLoader.$(outFile, cardImage, outFile.getName().endsWith(Constants.BPG), 0, null);
} }
/**
* 只展示分隔标签(例如“主卡组:60怪兽:21“),隐藏掉卡图ImageView
* @param text
*/
public void setText(String text) { public void setText(String text) {
labelText.setText(text); labelText.setText(text);
textlayout.setVisibility(View.VISIBLE); textlayout.setVisibility(View.VISIBLE);
...@@ -95,6 +106,9 @@ class DeckViewHolder extends RecyclerView.ViewHolder { ...@@ -95,6 +106,9 @@ class DeckViewHolder extends RecyclerView.ViewHolder {
rightImage.setVisibility(View.GONE); rightImage.setVisibility(View.GONE);
} }
/**
* 展示卡图,隐藏分隔标签
*/
public void showImage() { public void showImage() {
textlayout.setVisibility(View.GONE); textlayout.setVisibility(View.GONE);
cardImage.setVisibility(View.VISIBLE); cardImage.setVisibility(View.VISIBLE);
......
...@@ -184,7 +184,7 @@ public class MainActivity extends HomeActivity implements BottomNavigationBar.On ...@@ -184,7 +184,7 @@ public class MainActivity extends HomeActivity implements BottomNavigationBar.On
enableStart = error >= 0; enableStart = error >= 0;
getGameUriManager().doIntent(getIntent()); getGameUriManager().doIntent(getIntent());
}); });
} else { } else {//外部选择通过本应用打开ydk文件,会执行到这里
getGameUriManager().doIntent(intent); getGameUriManager().doIntent(intent);
} }
} }
......
...@@ -14,6 +14,8 @@ import android.util.Log; ...@@ -14,6 +14,8 @@ import android.util.Log;
import android.webkit.JavascriptInterface; import android.webkit.JavascriptInterface;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tencent.smtt.sdk.WebView; import com.tencent.smtt.sdk.WebView;
import org.json.JSONArray; import org.json.JSONArray;
...@@ -40,6 +42,7 @@ import cn.garymb.ygomobile.ui.plus.DefWebViewClient; ...@@ -40,6 +42,7 @@ import cn.garymb.ygomobile.ui.plus.DefWebViewClient;
import cn.garymb.ygomobile.utils.DeckUtil; import cn.garymb.ygomobile.utils.DeckUtil;
import cn.garymb.ygomobile.utils.JsonUtil; import cn.garymb.ygomobile.utils.JsonUtil;
import cn.garymb.ygomobile.utils.OkhttpUtil; import cn.garymb.ygomobile.utils.OkhttpUtil;
import cn.garymb.ygomobile.utils.SharedPreferenceUtil;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.Response; import okhttp3.Response;
...@@ -67,6 +70,7 @@ public class MyCard { ...@@ -67,6 +70,7 @@ public class MyCard {
public static final String ARG_UPDATE_AT = "updated_at"; public static final String ARG_UPDATE_AT = "updated_at";
public static final String ARG_URL = "url"; public static final String ARG_URL = "url";
public static final String ARG_NEWS = "news"; public static final String ARG_NEWS = "news";
public static final String URL_MC_SIGN_UP = "https://accounts.moecube.com/signup";
public static final String URL_MC_LOGOUT = "https://accounts.moecube.com/signin"; public static final String URL_MC_LOGOUT = "https://accounts.moecube.com/signin";
private final DefWebViewClient mDefWebViewClient = new DefWebViewClient() { private final DefWebViewClient mDefWebViewClient = new DefWebViewClient() {
@Override @Override
...@@ -336,7 +340,11 @@ public class MyCard { ...@@ -336,7 +340,11 @@ public class MyCard {
McUser mcUser = null; McUser mcUser = null;
if (TextUtils.isEmpty(exception)) { if (TextUtils.isEmpty(exception)) {
mcUser = new Gson().fromJson(userInfo, McUser.class); mcUser = new Gson().fromJson(userInfo, McUser.class);
UserManagement.getDx().setMcUser(mcUser); UserManagement.getDx().setMcUser(mcUser);//登录后,mcUser信息存在此
//另外保存一份token和id信息作为其他登录验证场景调用
SharedPreferenceUtil.setServerToken(mcUser.getToken());
SharedPreferenceUtil.setServerUserId(mcUser.getExternal_id());
SharedPreferenceUtil.setMyCardUserName(mcUser.getUsername());
} }
if (mListener!=null) if (mListener!=null)
mListener.onLogin(mcUser,exception); mListener.onLogin(mcUser,exception);
......
...@@ -58,6 +58,7 @@ import cn.garymb.ygomobile.ui.mycard.mcchat.management.ServiceManagement; ...@@ -58,6 +58,7 @@ import cn.garymb.ygomobile.ui.mycard.mcchat.management.ServiceManagement;
import cn.garymb.ygomobile.utils.DownloadUtil; import cn.garymb.ygomobile.utils.DownloadUtil;
import cn.garymb.ygomobile.utils.FileUtils; import cn.garymb.ygomobile.utils.FileUtils;
import cn.garymb.ygomobile.utils.HandlerUtil; import cn.garymb.ygomobile.utils.HandlerUtil;
import cn.garymb.ygomobile.utils.SharedPreferenceUtil;
import cn.garymb.ygomobile.utils.YGOUtil; import cn.garymb.ygomobile.utils.YGOUtil;
import cn.garymb.ygomobile.utils.glide.GlideCompat; import cn.garymb.ygomobile.utils.glide.GlideCompat;
import ocgcore.DataManager; import ocgcore.DataManager;
......
...@@ -10,8 +10,8 @@ public class McUser implements Serializable { ...@@ -10,8 +10,8 @@ public class McUser implements Serializable {
private int id; private int id;
private int external_id; private int external_id;
private String username; private String username;
//不要用
private String name; private String token;
private String email; private String email;
private String avatar_url; private String avatar_url;
private boolean admin; private boolean admin;
...@@ -57,17 +57,12 @@ public class McUser implements Serializable { ...@@ -57,17 +57,12 @@ public class McUser implements Serializable {
this.username = username; this.username = username;
} }
/** public String getToken() {
* 不要用这个,用getUserName return token;
* @return
*/
@Deprecated
public String getName() {
return name;
} }
public void setName(String name) { public void setToken(String token) {
this.name = name; this.token = token;
} }
public String getEmail() { public String getEmail() {
......
...@@ -72,7 +72,7 @@ public class ChatMessage { ...@@ -72,7 +72,7 @@ public class ChatMessage {
this.avatar = getAvatarUrl(name); this.avatar = getAvatarUrl(name);
} }
public String getAvatarUrl(String userName) { public static String getAvatarUrl(String userName) {
return "https://sapi.moecube.com:444/avatar/avatar/" + userName + "/100/ygomobile.png"; return "https://sapi.moecube.com:444/avatar/avatar/" + userName + "/100/ygomobile.png";
} }
......
...@@ -52,6 +52,11 @@ public class ImageUtil { ...@@ -52,6 +52,11 @@ public class ImageUtil {
show(context, url, im, null); show(context, url, im, null);
} }
/**
* 将图片变换为灰度图(变成灰白色)
* @param key
* @param imageView
*/
public static void setGrayImage(int key, ImageView imageView) { public static void setGrayImage(int key, ImageView imageView) {
ColorMatrix matrix = new ColorMatrix(); ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0); matrix.setSaturation(0);
......
...@@ -68,11 +68,18 @@ public class DeckUtil { ...@@ -68,11 +68,18 @@ public class DeckUtil {
} }
}; };
/**
* 生成卡组类型的list
*
* @param context
* @return
*/
public static List<DeckType> getDeckTypeList(Context context) { public static List<DeckType> getDeckTypeList(Context context) {
List<DeckType> deckTypeList = new ArrayList<>(); List<DeckType> deckTypeList = new ArrayList<>();
deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_pack), AppsSettings.get().getPackDeckDir())); deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_pack), AppsSettings.get().getPackDeckDir(), DeckType.ServerType.LOCAL));
deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_windbot_deck), AppsSettings.get().getAiDeckDir())); deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_windbot_deck), AppsSettings.get().getAiDeckDir(), DeckType.ServerType.LOCAL));
deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_Uncategorized), AppsSettings.get().getDeckDir())); deckTypeList.add(new DeckType(YGOUtil.s(R.string.category_Uncategorized), AppsSettings.get().getDeckDir(), DeckType.ServerType.LOCAL));
File[] files = new File(AppsSettings.get().getDeckDir()).listFiles(); File[] files = new File(AppsSettings.get().getDeckDir()).listFiles();
if (files != null) { if (files != null) {
...@@ -138,6 +145,7 @@ public class DeckUtil { ...@@ -138,6 +145,7 @@ public class DeckUtil {
/** /**
* 根据卡组绝对路径获取卡组分类名称 * 根据卡组绝对路径获取卡组分类名称
*
* @param deckPath * @param deckPath
* @return * @return
*/ */
...@@ -149,19 +157,20 @@ public class DeckUtil { ...@@ -149,19 +157,20 @@ public class DeckUtil {
if (name.equals("pack") || name.equals("cacheDeck")) { if (name.equals("pack") || name.equals("cacheDeck")) {
//卡包 //卡包
return YGOUtil.s(R.string.category_pack); return YGOUtil.s(R.string.category_pack);
} else if (name.equals("Decks")&&lastName.equals(Constants.WINDBOT_PATH)) { } else if (name.equals("Decks") && lastName.equals(Constants.WINDBOT_PATH)) {
//ai卡组 //ai卡组
return YGOUtil.s(R.string.category_windbot_deck); return YGOUtil.s(R.string.category_windbot_deck);
} else if (name.equals("deck") && lastName.equals(Constants.PREF_DEF_GAME_DIR)) { } else if (name.equals("deck") && lastName.equals(Constants.PREF_DEF_GAME_DIR)) {
//如果是deck并且上一个目录是ygocore的话,保证不会把名字为deck的卡包识别为未分类 //如果是deck并且上一个目录是ygocore的话,保证不会把名字为deck的卡包识别为未分类
return YGOUtil.s(R.string.category_Uncategorized); return YGOUtil.s(R.string.category_Uncategorized);
} else { } else {
return name; return name;
} }
} }
return null; return null;
} }
//获取扩展卡的列表
public static List<DeckFile> getExpansionsDeckList() throws IOException { public static List<DeckFile> getExpansionsDeckList() throws IOException {
AppsSettings appsSettings = AppsSettings.get(); AppsSettings appsSettings = AppsSettings.get();
List<DeckFile> deckList = new ArrayList<>(); List<DeckFile> deckList = new ArrayList<>();
......
...@@ -194,6 +194,31 @@ public class SharedPreferenceUtil { ...@@ -194,6 +194,31 @@ public class SharedPreferenceUtil {
getShareType().edit().putInt("deckEditType", type).apply(); getShareType().edit().putInt("deckEditType", type).apply();
} }
public static String getServerToken() {
return getShareRecord().getString("server_token", null);
}
public static boolean setServerToken(String token) {
return getShareRecord().edit().putString("server_token", token).commit();
}
public static Integer getServerUserId() {
return getShareType().getInt("server_user_id", -1);
}
public static void setServerUserId(int userId) {
getShareType().edit().putInt("server_user_id", userId).apply();
}
public static boolean deleteServerToken() {
// Get SharedPreferences instance
SharedPreferences sharedPreferences = getShareRecord();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("server_token"); // Replace "key_name" with your actual key
return editor.commit(); // Or editor.commit() if you need immediate results
}
public static String[] getArray(int id) { public static String[] getArray(int id) {
return App.get().getResources().getStringArray(id); return App.get().getResources().getStringArray(id);
} }
......
...@@ -9,16 +9,16 @@ import androidx.recyclerview.widget.RecyclerView; ...@@ -9,16 +9,16 @@ import androidx.recyclerview.widget.RecyclerView;
import cn.garymb.ygomobile.lite.R; import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.ui.adapters.TextSelectAdapter; import cn.garymb.ygomobile.ui.adapters.TextSelectAdapter;
import cn.garymb.ygomobile.ui.plus.DialogPlus; import cn.garymb.ygomobile.ui.plus.DialogPlus;
import cn.garymb.ygomobile.utils.YGODialogUtil; import cn.garymb.ygomobile.utils.YGODeckDialogUtil;
public class DeckTypeTouchHelperCallback extends ItemTouchHelper.Callback { public class DeckTypeTouchHelperCallback extends ItemTouchHelper.Callback {
private int dragFlags; private int dragFlags;
private int swipeFlags; private int swipeFlags;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private final YGODialogUtil.OnDeckTypeListener onDeckTypeListener; private final YGODeckDialogUtil.OnDeckTypeListener onDeckTypeListener;
public DeckTypeTouchHelperCallback(YGODialogUtil.OnDeckTypeListener onDeckTypeListener) { public DeckTypeTouchHelperCallback(YGODeckDialogUtil.OnDeckTypeListener onDeckTypeListener) {
this.onDeckTypeListener = onDeckTypeListener; this.onDeckTypeListener = onDeckTypeListener;
} }
......
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="false">
<!-- 位移动画:从当前位置向上移动150dp -->
<translate
android:duration="1500"
android:fromYDelta="0"
android:toYDelta="-30dp"
android:interpolator="@android:anim/decelerate_interpolator" />
<!-- 透明度动画:从完全可见到完全透明 -->
<alpha
android:duration="1500"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator" />
<!-- 缩放动画:稍微缩小一点 -->
<scale
android:duration="1000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.8"
android:toYScale="0.8"
android:interpolator="@android:anim/decelerate_interpolator" />
</set>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment