fixed twitter link handler
This commit is contained in:
parent
eb85ce3e90
commit
54c8254040
|
@ -9,7 +9,9 @@ import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
|
@ -56,7 +58,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/i/redirect", URI_CODE_TWITTER_REDIRECT);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/i/redirect", URI_CODE_TWITTER_REDIRECT);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/intent/tweet", URI_CODE_TWITTER_INTENT_TWEET);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/intent/tweet", URI_CODE_TWITTER_INTENT_TWEET);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/status/#", URI_CODE_TWITTER_STATUS);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/status/#", URI_CODE_TWITTER_STATUS);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/status/#/photo/#", URI_CODE_TWITTER_STATUS);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/status/#/*/#", URI_CODE_TWITTER_STATUS);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*", URI_CODE_TWITTER_USER);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*", URI_CODE_TWITTER_USER);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/following", URI_CODE_TWITTER_USER_FOLLOWING);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/following", URI_CODE_TWITTER_USER_FOLLOWING);
|
||||||
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/followers", URI_CODE_TWITTER_USER_FOLLOWERS);
|
URI_MATCHER.addURI(AUTHORITY_TWITTER_COM, "/*/followers", URI_CODE_TWITTER_USER_FOLLOWERS);
|
||||||
|
@ -67,7 +69,16 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SharedPreferences mPreferences;
|
private SharedPreferences mPreferences;
|
||||||
private PackageManager mPackageManager;
|
|
||||||
|
private static Uri regulateTwitterUri(Uri data) {
|
||||||
|
final String encodedFragment = data.getEncodedFragment();
|
||||||
|
if (encodedFragment != null && encodedFragment.startsWith("!/")) {
|
||||||
|
return regulateTwitterUri(Uri.parse("https://twitter.com" + encodedFragment.substring(1)));
|
||||||
|
}
|
||||||
|
final Uri.Builder builder = data.buildUpon();
|
||||||
|
builder.authority(AUTHORITY_TWITTER_COM);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||||
|
@ -99,7 +110,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
mPackageManager = getPackageManager();
|
final PackageManager packageManager = getPackageManager();
|
||||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
final Uri data = intent.getData();
|
final Uri data = intent.getData();
|
||||||
|
@ -108,15 +119,17 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Uri uri = regulateTwitterUri(data);
|
final Uri uri = regulateTwitterUri(data);
|
||||||
final Intent handledIntent = getHandledIntent(uri);
|
final Pair<Intent, Boolean> handled = getHandledIntent(uri);
|
||||||
if (handledIntent != null) {
|
if (handled.first != null) {
|
||||||
startActivity(handledIntent);
|
startActivity(handled.first);
|
||||||
} else {
|
} else {
|
||||||
|
if (!handled.second) {
|
||||||
AbsLogger.error(new TwitterLinkException("Unable to handle twitter uri " + uri));
|
AbsLogger.error(new TwitterLinkException("Unable to handle twitter uri " + uri));
|
||||||
|
}
|
||||||
final String packageName = mPreferences.getString(KEY_FALLBACK_TWITTER_LINK_HANDLER, null);
|
final String packageName = mPreferences.getString(KEY_FALLBACK_TWITTER_LINK_HANDLER, null);
|
||||||
final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri);
|
final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
fallbackIntent.setPackage(packageName);
|
fallbackIntent.setPackage(packageName);
|
||||||
if (TextUtils.isEmpty(packageName) || mPackageManager.queryIntentActivities(fallbackIntent, 0).isEmpty()) {
|
if (TextUtils.isEmpty(packageName) || packageManager.queryIntentActivities(fallbackIntent, 0).isEmpty()) {
|
||||||
final Intent pickIntent = new Intent(INTENT_ACTION_PICK_ACTIVITY);
|
final Intent pickIntent = new Intent(INTENT_ACTION_PICK_ACTIVITY);
|
||||||
pickIntent.putExtra(EXTRA_INTENT, new Intent(Intent.ACTION_VIEW, uri));
|
pickIntent.putExtra(EXTRA_INTENT, new Intent(Intent.ACTION_VIEW, uri));
|
||||||
pickIntent.putExtra(EXTRA_BLACKLIST, new String[]{getPackageName()});
|
pickIntent.putExtra(EXTRA_BLACKLIST, new String[]{getPackageName()});
|
||||||
|
@ -129,17 +142,8 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Uri regulateTwitterUri(Uri data) {
|
@NonNull
|
||||||
final String encodedFragment = data.getEncodedFragment();
|
private Pair<Intent, Boolean> getHandledIntent(final Uri uri) {
|
||||||
if (encodedFragment != null && encodedFragment.startsWith("!/")) {
|
|
||||||
return regulateTwitterUri(Uri.parse("https://twitter.com" + encodedFragment.substring(1)));
|
|
||||||
}
|
|
||||||
final Uri.Builder builder = data.buildUpon();
|
|
||||||
builder.authority(AUTHORITY_TWITTER_COM);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intent getHandledIntent(final Uri uri) {
|
|
||||||
final List<String> pathSegments = uri.getPathSegments();
|
final List<String> pathSegments = uri.getPathSegments();
|
||||||
switch (URI_MATCHER.match(uri)) {
|
switch (URI_MATCHER.match(uri)) {
|
||||||
case URI_CODE_TWITTER_STATUS: {
|
case URI_CODE_TWITTER_STATUS: {
|
||||||
|
@ -147,7 +151,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_STATUS);
|
builder.authority(AUTHORITY_STATUS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments.get(2));
|
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments.get(2));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_INTENT_TWEET: {
|
case URI_CODE_TWITTER_INTENT_TWEET: {
|
||||||
final Intent handledIntent = new Intent(this, ComposeActivity.class);
|
final Intent handledIntent = new Intent(this, ComposeActivity.class);
|
||||||
|
@ -155,7 +159,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
final String text = uri.getQueryParameter("text");
|
final String text = uri.getQueryParameter("text");
|
||||||
final String url = uri.getQueryParameter("url");
|
final String url = uri.getQueryParameter("url");
|
||||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
||||||
return handledIntent;
|
return Pair.create(handledIntent, true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER: {
|
case URI_CODE_TWITTER_USER: {
|
||||||
final String pathSegment = pathSegments.get(0);
|
final String pathSegment = pathSegments.get(0);
|
||||||
|
@ -167,7 +171,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
final String text = uri.getQueryParameter("text");
|
final String text = uri.getQueryParameter("text");
|
||||||
final String url = uri.getQueryParameter("url");
|
final String url = uri.getQueryParameter("url");
|
||||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
||||||
return handledIntent;
|
return Pair.create(handledIntent, true);
|
||||||
} else if ("following".equals(pathSegment)) {
|
} else if ("following".equals(pathSegment)) {
|
||||||
builder.authority(AUTHORITY_USER_FRIENDS);
|
builder.authority(AUTHORITY_USER_FRIENDS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_USER_ID, String.valueOf(getDefaultAccountId(this)));
|
builder.appendQueryParameter(QUERY_PARAM_USER_ID, String.valueOf(getDefaultAccountId(this)));
|
||||||
|
@ -180,69 +184,68 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
|
||||||
} else if (!ArrayUtils.contains(TWITTER_RESERVED_PATHS, pathSegment)) {
|
} else if (!ArrayUtils.contains(TWITTER_RESERVED_PATHS, pathSegment)) {
|
||||||
builder.authority(AUTHORITY_USER);
|
builder.authority(AUTHORITY_USER);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegment);
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegment);
|
||||||
} else
|
}
|
||||||
return null;
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_FOLLOWING: {
|
case URI_CODE_TWITTER_USER_FOLLOWING: {
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_FRIENDS);
|
builder.authority(AUTHORITY_USER_FRIENDS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_FOLLOWERS: {
|
case URI_CODE_TWITTER_USER_FOLLOWERS: {
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_FOLLOWERS);
|
builder.authority(AUTHORITY_USER_FOLLOWERS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_FAVORITES: {
|
case URI_CODE_TWITTER_USER_FAVORITES: {
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_FAVORITES);
|
builder.authority(AUTHORITY_USER_FAVORITES);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, pathSegments.get(0));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_LIST: {
|
case URI_CODE_TWITTER_USER_LIST: {
|
||||||
final String firstSegment = pathSegments.get(0);
|
final String firstSegment = pathSegments.get(0);
|
||||||
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
||||||
return null;
|
return Pair.create(null, true);
|
||||||
}
|
}
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_LIST);
|
builder.authority(AUTHORITY_USER_LIST);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_LIST_MEMBERS: {
|
case URI_CODE_TWITTER_USER_LIST_MEMBERS: {
|
||||||
final String firstSegment = pathSegments.get(0);
|
final String firstSegment = pathSegments.get(0);
|
||||||
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
||||||
return null;
|
return Pair.create(null, true);
|
||||||
}
|
}
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_LIST_MEMBERS);
|
builder.authority(AUTHORITY_USER_LIST_MEMBERS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
case URI_CODE_TWITTER_USER_LIST_SUBSCRIBERS: {
|
case URI_CODE_TWITTER_USER_LIST_SUBSCRIBERS: {
|
||||||
final String firstSegment = pathSegments.get(0);
|
final String firstSegment = pathSegments.get(0);
|
||||||
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, firstSegment)) {
|
||||||
return null;
|
return Pair.create(null, true);
|
||||||
}
|
}
|
||||||
final Uri.Builder builder = new Uri.Builder();
|
final Uri.Builder builder = new Uri.Builder();
|
||||||
builder.scheme(SCHEME_TWIDERE);
|
builder.scheme(SCHEME_TWIDERE);
|
||||||
builder.authority(AUTHORITY_USER_LIST_SUBSCRIBERS);
|
builder.authority(AUTHORITY_USER_LIST_SUBSCRIBERS);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, firstSegment);
|
||||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||||
return new Intent(Intent.ACTION_VIEW, builder.build());
|
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return Pair.create(null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TwitterLinkException extends Exception {
|
private class TwitterLinkException extends Exception {
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.twidere.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 15/9/4.
|
||||||
|
*/
|
||||||
|
public class HomeViewPager extends ExtendedViewPager {
|
||||||
|
|
||||||
|
private DrawerLayout mDrawerLayout;
|
||||||
|
|
||||||
|
public HomeViewPager(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HomeViewPager(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawerLayout(DrawerLayout drawerLayout) {
|
||||||
|
mDrawerLayout = drawerLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
|
return super.onInterceptTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
|
||||||
|
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -237,7 +237,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
|
||||||
|
|
||||||
if (adapter.isMediaPreviewEnabled()) {
|
if (adapter.isMediaPreviewEnabled()) {
|
||||||
mediaPreview.setStyle(adapter.getMediaPreviewStyle());
|
mediaPreview.setStyle(adapter.getMediaPreviewStyle());
|
||||||
final boolean hasMedia = media != null && media.length > 0;
|
final boolean hasMedia = !ArrayUtils.isEmpty(media);
|
||||||
if (hasMedia && (adapter.isSensitiveContentEnabled() || !status.is_possibly_sensitive)) {
|
if (hasMedia && (adapter.isSensitiveContentEnabled() || !status.is_possibly_sensitive)) {
|
||||||
mediaPreview.setVisibility(View.VISIBLE);
|
mediaPreview.setVisibility(View.VISIBLE);
|
||||||
mediaPreview.displayMedia(media, loader, status.account_id, this,
|
mediaPreview.displayMedia(media, loader, status.account_id, this,
|
||||||
|
|
Loading…
Reference in New Issue