Merge "Fix issues 5158104 and 4981556 (fragment problems)"
This commit is contained in:
committed by
Android (Google) Code Review
commit
4293064179
@@ -3277,6 +3277,7 @@ package android.app {
|
|||||||
method public void setArguments(android.os.Bundle);
|
method public void setArguments(android.os.Bundle);
|
||||||
method public void setHasOptionsMenu(boolean);
|
method public void setHasOptionsMenu(boolean);
|
||||||
method public void setInitialSavedState(android.app.Fragment.SavedState);
|
method public void setInitialSavedState(android.app.Fragment.SavedState);
|
||||||
|
method public void setMenuVisibility(boolean);
|
||||||
method public void setRetainInstance(boolean);
|
method public void setRetainInstance(boolean);
|
||||||
method public void setTargetFragment(android.app.Fragment, int);
|
method public void setTargetFragment(android.app.Fragment, int);
|
||||||
method public void startActivity(android.content.Intent);
|
method public void startActivity(android.content.Intent);
|
||||||
@@ -3342,6 +3343,7 @@ package android.app {
|
|||||||
method public abstract java.lang.CharSequence getBreadCrumbTitle();
|
method public abstract java.lang.CharSequence getBreadCrumbTitle();
|
||||||
method public abstract int getBreadCrumbTitleRes();
|
method public abstract int getBreadCrumbTitleRes();
|
||||||
method public abstract int getId();
|
method public abstract int getId();
|
||||||
|
method public abstract java.lang.String getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract interface FragmentManager.OnBackStackChangedListener {
|
public static abstract interface FragmentManager.OnBackStackChangedListener {
|
||||||
|
|||||||
@@ -4206,7 +4206,6 @@ public class Activity extends ContextThemeWrapper
|
|||||||
fragment.mContainerId = containerId;
|
fragment.mContainerId = containerId;
|
||||||
fragment.mTag = tag;
|
fragment.mTag = tag;
|
||||||
fragment.mInLayout = true;
|
fragment.mInLayout = true;
|
||||||
fragment.mImmediateActivity = this;
|
|
||||||
fragment.mFragmentManager = mFragments;
|
fragment.mFragmentManager = mFragments;
|
||||||
fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
|
fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
|
||||||
mFragments.addFragment(fragment, true);
|
mFragments.addFragment(fragment, true);
|
||||||
@@ -4222,7 +4221,6 @@ public class Activity extends ContextThemeWrapper
|
|||||||
// This fragment was retained from a previous instance; get it
|
// This fragment was retained from a previous instance; get it
|
||||||
// going now.
|
// going now.
|
||||||
fragment.mInLayout = true;
|
fragment.mInLayout = true;
|
||||||
fragment.mImmediateActivity = this;
|
|
||||||
// If this fragment is newly instantiated (either right now, or
|
// If this fragment is newly instantiated (either right now, or
|
||||||
// from last saved state), then give it the attributes to
|
// from last saved state), then give it the attributes to
|
||||||
// initialize itself.
|
// initialize itself.
|
||||||
|
|||||||
@@ -344,10 +344,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
|
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
|
||||||
if (fragment.mImmediateActivity != null) {
|
|
||||||
throw new IllegalStateException("Fragment already added: " + fragment);
|
|
||||||
}
|
|
||||||
fragment.mImmediateActivity = mManager.mActivity;
|
|
||||||
fragment.mFragmentManager = mManager;
|
fragment.mFragmentManager = mManager;
|
||||||
|
|
||||||
if (tag != null) {
|
if (tag != null) {
|
||||||
@@ -388,11 +384,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FragmentTransaction remove(Fragment fragment) {
|
public FragmentTransaction remove(Fragment fragment) {
|
||||||
if (fragment.mImmediateActivity == null) {
|
|
||||||
throw new IllegalStateException("Fragment not added: " + fragment);
|
|
||||||
}
|
|
||||||
fragment.mImmediateActivity = null;
|
|
||||||
|
|
||||||
Op op = new Op();
|
Op op = new Op();
|
||||||
op.cmd = OP_REMOVE;
|
op.cmd = OP_REMOVE;
|
||||||
op.fragment = fragment;
|
op.fragment = fragment;
|
||||||
@@ -402,10 +393,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FragmentTransaction hide(Fragment fragment) {
|
public FragmentTransaction hide(Fragment fragment) {
|
||||||
if (fragment.mImmediateActivity == null) {
|
|
||||||
throw new IllegalStateException("Fragment not added: " + fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
Op op = new Op();
|
Op op = new Op();
|
||||||
op.cmd = OP_HIDE;
|
op.cmd = OP_HIDE;
|
||||||
op.fragment = fragment;
|
op.fragment = fragment;
|
||||||
@@ -415,10 +402,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FragmentTransaction show(Fragment fragment) {
|
public FragmentTransaction show(Fragment fragment) {
|
||||||
if (fragment.mImmediateActivity == null) {
|
|
||||||
throw new IllegalStateException("Fragment not added: " + fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
Op op = new Op();
|
Op op = new Op();
|
||||||
op.cmd = OP_SHOW;
|
op.cmd = OP_SHOW;
|
||||||
op.fragment = fragment;
|
op.fragment = fragment;
|
||||||
@@ -428,10 +411,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FragmentTransaction detach(Fragment fragment) {
|
public FragmentTransaction detach(Fragment fragment) {
|
||||||
//if (fragment.mImmediateActivity == null) {
|
|
||||||
// throw new IllegalStateException("Fragment not added: " + fragment);
|
|
||||||
//}
|
|
||||||
|
|
||||||
Op op = new Op();
|
Op op = new Op();
|
||||||
op.cmd = OP_DETACH;
|
op.cmd = OP_DETACH;
|
||||||
op.fragment = fragment;
|
op.fragment = fragment;
|
||||||
@@ -441,10 +420,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FragmentTransaction attach(Fragment fragment) {
|
public FragmentTransaction attach(Fragment fragment) {
|
||||||
//if (fragment.mImmediateActivity == null) {
|
|
||||||
// throw new IllegalStateException("Fragment not added: " + fragment);
|
|
||||||
//}
|
|
||||||
|
|
||||||
Op op = new Op();
|
Op op = new Op();
|
||||||
op.cmd = OP_ATTACH;
|
op.cmd = OP_ATTACH;
|
||||||
op.fragment = fragment;
|
op.fragment = fragment;
|
||||||
@@ -663,7 +638,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
case OP_ADD: {
|
case OP_ADD: {
|
||||||
Fragment f = op.fragment;
|
Fragment f = op.fragment;
|
||||||
f.mNextAnim = op.popExitAnim;
|
f.mNextAnim = op.popExitAnim;
|
||||||
f.mImmediateActivity = null;
|
|
||||||
mManager.removeFragment(f,
|
mManager.removeFragment(f,
|
||||||
FragmentManagerImpl.reverseTransit(mTransition),
|
FragmentManagerImpl.reverseTransit(mTransition),
|
||||||
mTransitionStyle);
|
mTransitionStyle);
|
||||||
@@ -671,7 +645,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
case OP_REPLACE: {
|
case OP_REPLACE: {
|
||||||
Fragment f = op.fragment;
|
Fragment f = op.fragment;
|
||||||
f.mNextAnim = op.popExitAnim;
|
f.mNextAnim = op.popExitAnim;
|
||||||
f.mImmediateActivity = null;
|
|
||||||
mManager.removeFragment(f,
|
mManager.removeFragment(f,
|
||||||
FragmentManagerImpl.reverseTransit(mTransition),
|
FragmentManagerImpl.reverseTransit(mTransition),
|
||||||
mTransitionStyle);
|
mTransitionStyle);
|
||||||
@@ -679,7 +652,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
for (int i=0; i<op.removed.size(); i++) {
|
for (int i=0; i<op.removed.size(); i++) {
|
||||||
Fragment old = op.removed.get(i);
|
Fragment old = op.removed.get(i);
|
||||||
old.mNextAnim = op.popEnterAnim;
|
old.mNextAnim = op.popEnterAnim;
|
||||||
f.mImmediateActivity = mManager.mActivity;
|
|
||||||
mManager.addFragment(old, false);
|
mManager.addFragment(old, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -687,7 +659,6 @@ final class BackStackRecord extends FragmentTransaction implements
|
|||||||
case OP_REMOVE: {
|
case OP_REMOVE: {
|
||||||
Fragment f = op.fragment;
|
Fragment f = op.fragment;
|
||||||
f.mNextAnim = op.popEnterAnim;
|
f.mNextAnim = op.popEnterAnim;
|
||||||
f.mImmediateActivity = mManager.mActivity;
|
|
||||||
mManager.addFragment(f, false);
|
mManager.addFragment(f, false);
|
||||||
} break;
|
} break;
|
||||||
case OP_HIDE: {
|
case OP_HIDE: {
|
||||||
|
|||||||
@@ -402,10 +402,6 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
|||||||
// from all transactions.
|
// from all transactions.
|
||||||
FragmentManager mFragmentManager;
|
FragmentManager mFragmentManager;
|
||||||
|
|
||||||
// Set as soon as a fragment is added to a transaction (or removed),
|
|
||||||
// to be able to do validation.
|
|
||||||
Activity mImmediateActivity;
|
|
||||||
|
|
||||||
// Activity this fragment is attached to.
|
// Activity this fragment is attached to.
|
||||||
Activity mActivity;
|
Activity mActivity;
|
||||||
|
|
||||||
@@ -439,6 +435,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
|||||||
// If set this fragment has menu items to contribute.
|
// If set this fragment has menu items to contribute.
|
||||||
boolean mHasMenu;
|
boolean mHasMenu;
|
||||||
|
|
||||||
|
// Set to true to allow the fragment's menu to be shown.
|
||||||
|
boolean mMenuVisible = true;
|
||||||
|
|
||||||
// Used to verify that subclasses call through to super class.
|
// Used to verify that subclasses call through to super class.
|
||||||
boolean mCalled;
|
boolean mCalled;
|
||||||
|
|
||||||
@@ -889,6 +888,24 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a hint for whether this fragment's menu should be visible. This
|
||||||
|
* is useful if you know that a fragment has been placed in your view
|
||||||
|
* hierarchy so that the user can not currently seen it, so any menu items
|
||||||
|
* it has should also not be shown.
|
||||||
|
*
|
||||||
|
* @param menuVisible The default is true, meaning the fragment's menu will
|
||||||
|
* be shown as usual. If false, the user will not see the menu.
|
||||||
|
*/
|
||||||
|
public void setMenuVisibility(boolean menuVisible) {
|
||||||
|
if (mMenuVisible != menuVisible) {
|
||||||
|
mMenuVisible = menuVisible;
|
||||||
|
if (mHasMenu && isAdded() && !isHidden()) {
|
||||||
|
mFragmentManager.invalidateOptionsMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the LoaderManager for this fragment, creating it if needed.
|
* Return the LoaderManager for this fragment, creating it if needed.
|
||||||
*/
|
*/
|
||||||
@@ -1233,7 +1250,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
|||||||
mRestored = false;
|
mRestored = false;
|
||||||
mBackStackNesting = 0;
|
mBackStackNesting = 0;
|
||||||
mFragmentManager = null;
|
mFragmentManager = null;
|
||||||
mActivity = mImmediateActivity = null;
|
mActivity = null;
|
||||||
mFragmentId = 0;
|
mFragmentId = 0;
|
||||||
mContainerId = 0;
|
mContainerId = 0;
|
||||||
mTag = null;
|
mTag = null;
|
||||||
@@ -1421,17 +1438,14 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
|||||||
writer.print(" mInLayout="); writer.println(mInLayout);
|
writer.print(" mInLayout="); writer.println(mInLayout);
|
||||||
writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
|
writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
|
||||||
writer.print(" mDetached="); writer.print(mDetached);
|
writer.print(" mDetached="); writer.print(mDetached);
|
||||||
writer.print(" mRetainInstance="); writer.print(mRetainInstance);
|
writer.print(" mMenuVisible="); writer.print(mMenuVisible);
|
||||||
writer.print(" mRetaining="); writer.print(mRetaining);
|
|
||||||
writer.print(" mHasMenu="); writer.println(mHasMenu);
|
writer.print(" mHasMenu="); writer.println(mHasMenu);
|
||||||
|
writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
|
||||||
|
writer.print(" mRetaining="); writer.println(mRetaining);
|
||||||
if (mFragmentManager != null) {
|
if (mFragmentManager != null) {
|
||||||
writer.print(prefix); writer.print("mFragmentManager=");
|
writer.print(prefix); writer.print("mFragmentManager=");
|
||||||
writer.println(mFragmentManager);
|
writer.println(mFragmentManager);
|
||||||
}
|
}
|
||||||
if (mImmediateActivity != null) {
|
|
||||||
writer.print(prefix); writer.print("mImmediateActivity=");
|
|
||||||
writer.println(mImmediateActivity);
|
|
||||||
}
|
|
||||||
if (mActivity != null) {
|
if (mActivity != null) {
|
||||||
writer.print(prefix); writer.print("mActivity=");
|
writer.print(prefix); writer.print("mActivity=");
|
||||||
writer.println(mActivity);
|
writer.println(mActivity);
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ public abstract class FragmentManager {
|
|||||||
*/
|
*/
|
||||||
public int getId();
|
public int getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name that was supplied to
|
||||||
|
* {@link FragmentTransaction#addToBackStack(String)
|
||||||
|
* FragmentTransaction.addToBackStack(String)} when creating this entry.
|
||||||
|
*/
|
||||||
|
public String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the full bread crumb title resource identifier for the entry,
|
* Return the full bread crumb title resource identifier for the entry,
|
||||||
* or 0 if it does not have one.
|
* or 0 if it does not have one.
|
||||||
@@ -949,7 +956,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (!f.mRetaining) {
|
if (!f.mRetaining) {
|
||||||
makeInactive(f);
|
makeInactive(f);
|
||||||
} else {
|
} else {
|
||||||
f.mImmediateActivity = null;
|
|
||||||
f.mActivity = null;
|
f.mActivity = null;
|
||||||
f.mFragmentManager = null;
|
f.mFragmentManager = null;
|
||||||
}
|
}
|
||||||
@@ -1037,7 +1043,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
mAdded.add(fragment);
|
mAdded.add(fragment);
|
||||||
fragment.mAdded = true;
|
fragment.mAdded = true;
|
||||||
fragment.mRemoving = false;
|
fragment.mRemoving = false;
|
||||||
if (fragment.mHasMenu) {
|
if (fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
if (moveToStateNow) {
|
if (moveToStateNow) {
|
||||||
@@ -1051,7 +1057,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
final boolean inactive = !fragment.isInBackStack();
|
final boolean inactive = !fragment.isInBackStack();
|
||||||
if (!fragment.mDetached || inactive) {
|
if (!fragment.mDetached || inactive) {
|
||||||
mAdded.remove(fragment);
|
mAdded.remove(fragment);
|
||||||
if (fragment.mHasMenu) {
|
if (fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
fragment.mAdded = false;
|
fragment.mAdded = false;
|
||||||
@@ -1086,7 +1092,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
fragment.mView.setVisibility(View.GONE);
|
fragment.mView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fragment.mAdded && fragment.mHasMenu) {
|
if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
fragment.onHiddenChanged(true);
|
fragment.onHiddenChanged(true);
|
||||||
@@ -1106,7 +1112,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
}
|
}
|
||||||
fragment.mView.setVisibility(View.VISIBLE);
|
fragment.mView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
if (fragment.mAdded && fragment.mHasMenu) {
|
if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
fragment.onHiddenChanged(false);
|
fragment.onHiddenChanged(false);
|
||||||
@@ -1120,7 +1126,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (fragment.mAdded) {
|
if (fragment.mAdded) {
|
||||||
// We are not already in back stack, so need to remove the fragment.
|
// We are not already in back stack, so need to remove the fragment.
|
||||||
mAdded.remove(fragment);
|
mAdded.remove(fragment);
|
||||||
if (fragment.mHasMenu) {
|
if (fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
fragment.mAdded = false;
|
fragment.mAdded = false;
|
||||||
@@ -1136,7 +1142,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (!fragment.mAdded) {
|
if (!fragment.mAdded) {
|
||||||
mAdded.add(fragment);
|
mAdded.add(fragment);
|
||||||
fragment.mAdded = true;
|
fragment.mAdded = true;
|
||||||
if (fragment.mHasMenu) {
|
if (fragment.mHasMenu && fragment.mMenuVisible) {
|
||||||
mNeedMenuInvalidate = true;
|
mNeedMenuInvalidate = true;
|
||||||
}
|
}
|
||||||
moveToState(fragment, mCurState, transition, transitionStyle);
|
moveToState(fragment, mCurState, transition, transitionStyle);
|
||||||
@@ -1640,7 +1646,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
"No instantiated fragment for index #" + fms.mAdded[i]);
|
"No instantiated fragment for index #" + fms.mAdded[i]);
|
||||||
}
|
}
|
||||||
f.mAdded = true;
|
f.mAdded = true;
|
||||||
f.mImmediateActivity = mActivity;
|
|
||||||
if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f);
|
if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f);
|
||||||
mAdded.add(f);
|
mAdded.add(f);
|
||||||
}
|
}
|
||||||
@@ -1748,7 +1753,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (mActive != null) {
|
if (mActive != null) {
|
||||||
for (int i=0; i<mAdded.size(); i++) {
|
for (int i=0; i<mAdded.size(); i++) {
|
||||||
Fragment f = mAdded.get(i);
|
Fragment f = mAdded.get(i);
|
||||||
if (f != null && !f.mHidden && f.mHasMenu) {
|
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
|
||||||
show = true;
|
show = true;
|
||||||
f.onCreateOptionsMenu(menu, inflater);
|
f.onCreateOptionsMenu(menu, inflater);
|
||||||
if (newMenus == null) {
|
if (newMenus == null) {
|
||||||
@@ -1778,7 +1783,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (mActive != null) {
|
if (mActive != null) {
|
||||||
for (int i=0; i<mAdded.size(); i++) {
|
for (int i=0; i<mAdded.size(); i++) {
|
||||||
Fragment f = mAdded.get(i);
|
Fragment f = mAdded.get(i);
|
||||||
if (f != null && !f.mHidden && f.mHasMenu) {
|
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
|
||||||
show = true;
|
show = true;
|
||||||
f.onPrepareOptionsMenu(menu);
|
f.onPrepareOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
@@ -1791,7 +1796,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (mActive != null) {
|
if (mActive != null) {
|
||||||
for (int i=0; i<mAdded.size(); i++) {
|
for (int i=0; i<mAdded.size(); i++) {
|
||||||
Fragment f = mAdded.get(i);
|
Fragment f = mAdded.get(i);
|
||||||
if (f != null && !f.mHidden && f.mHasMenu) {
|
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
|
||||||
if (f.onOptionsItemSelected(item)) {
|
if (f.onOptionsItemSelected(item)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1819,7 +1824,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (mActive != null) {
|
if (mActive != null) {
|
||||||
for (int i=0; i<mAdded.size(); i++) {
|
for (int i=0; i<mAdded.size(); i++) {
|
||||||
Fragment f = mAdded.get(i);
|
Fragment f = mAdded.get(i);
|
||||||
if (f != null && !f.mHidden && f.mHasMenu) {
|
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
|
||||||
f.onOptionsMenuClosed(menu);
|
f.onOptionsMenuClosed(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user