Merge pull request #525 from SimpleMobileTools/KryptKode-feat/scoped-storage
Krypt kode feat/scoped storage
This commit is contained in:
commit
6684235930
|
@ -57,7 +57,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:4e6eeb901f'
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:51f1996098'
|
||||
implementation 'com.github.Stericson:RootTools:df729dcb13'
|
||||
implementation 'com.github.Stericson:RootShell:1.6'
|
||||
implementation 'com.alexvasilkov:gesture-views:2.5.2'
|
||||
|
|
|
@ -61,6 +61,9 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
ensureBackgroundThread {
|
||||
reFetchItems()
|
||||
}
|
||||
|
||||
val adjustedPrimaryColor = getAdjustedPrimaryColor()
|
||||
mimetypes_fastscroller.updateColors(adjustedPrimaryColor, adjustedPrimaryColor.getContrastColor())
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
|
@ -130,13 +133,13 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
lastSearchedText = searchText
|
||||
when {
|
||||
searchText.isEmpty() -> {
|
||||
mimetypes_list.beVisible()
|
||||
mimetypes_fastscroller.beVisible()
|
||||
getRecyclerAdapter()?.updateItems(storedItems)
|
||||
mimetypes_placeholder.beGoneIf(storedItems.isNotEmpty())
|
||||
mimetypes_placeholder_2.beGone()
|
||||
}
|
||||
searchText.length == 1 -> {
|
||||
mimetypes_list.beGone()
|
||||
mimetypes_fastscroller.beGone()
|
||||
mimetypes_placeholder.beVisible()
|
||||
mimetypes_placeholder_2.beVisible()
|
||||
}
|
||||
|
@ -150,14 +153,9 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
|
||||
runOnUiThread {
|
||||
getRecyclerAdapter()?.updateItems(listItems, text)
|
||||
mimetypes_list.beVisibleIf(listItems.isNotEmpty())
|
||||
mimetypes_fastscroller.beVisibleIf(listItems.isNotEmpty())
|
||||
mimetypes_placeholder.beVisibleIf(listItems.isEmpty())
|
||||
mimetypes_placeholder_2.beGone()
|
||||
|
||||
mimetypes_list.onGlobalLayout {
|
||||
items_fastscroller.setScrollToY(mimetypes_list.computeVerticalScrollOffset())
|
||||
calculateContentHeight(listItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +230,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
isSearchOpen = false
|
||||
lastSearchedText = ""
|
||||
|
||||
mimetypes_list.beVisible()
|
||||
mimetypes_fastscroller.beVisible()
|
||||
mimetypes_placeholder.beGoneIf(storedItems.isNotEmpty())
|
||||
mimetypes_placeholder_2.beGone()
|
||||
}
|
||||
|
@ -321,7 +319,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
}
|
||||
|
||||
storedItems = items
|
||||
ItemsAdapter(this as SimpleActivity, storedItems, this, mimetypes_list, false, items_fastscroller, null) {
|
||||
ItemsAdapter(this as SimpleActivity, storedItems, this, mimetypes_list, false, null) {
|
||||
tryOpenPathIntent((it as ListItem).path, false)
|
||||
}.apply {
|
||||
setupZoomListener(zoomListener)
|
||||
|
@ -332,13 +330,6 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
mimetypes_list.scheduleLayoutAnimation()
|
||||
}
|
||||
|
||||
val dateFormat = config.dateFormat
|
||||
val timeFormat = getTimeFormat()
|
||||
items_fastscroller.setViews(mimetypes_list) {
|
||||
val listItem = getRecyclerAdapter()?.listItems?.getOrNull(it)
|
||||
items_fastscroller.updateBubbleText(listItem?.getBubbleText(this, dateFormat, timeFormat) ?: "")
|
||||
}
|
||||
|
||||
mimetypes_placeholder.beVisibleIf(items.isEmpty())
|
||||
}
|
||||
|
||||
|
@ -390,18 +381,9 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
|
|||
invalidateOptionsMenu()
|
||||
getRecyclerAdapter()?.apply {
|
||||
notifyItemRangeChanged(0, listItems.size)
|
||||
calculateContentHeight(listItems)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateContentHeight(items: MutableList<ListItem>) {
|
||||
val layoutManager = mimetypes_list.layoutManager as MyGridLayoutManager
|
||||
val thumbnailHeight = layoutManager.getChildAt(0)?.height ?: 0
|
||||
val fullHeight = ((items.size - 1) / layoutManager.spanCount + 1) * thumbnailHeight
|
||||
items_fastscroller.setContentHeight(fullHeight)
|
||||
items_fastscroller.setScrollToY(mimetypes_list.computeVerticalScrollOffset())
|
||||
}
|
||||
|
||||
private fun setupLayoutManager() {
|
||||
if (config.getFolderViewType(currentMimeType) == VIEW_TYPE_GRID) {
|
||||
currentViewType = VIEW_TYPE_GRID
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
|||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
|
||||
import com.simplemobiletools.commons.extensions.getFileSignature
|
||||
import com.simplemobiletools.commons.extensions.getTextSize
|
||||
import com.simplemobiletools.commons.extensions.getTimeFormat
|
||||
import com.simplemobiletools.commons.helpers.getFilePlaceholderDrawables
|
||||
|
@ -25,7 +24,7 @@ import kotlinx.android.synthetic.main.item_file_dir_list.view.*
|
|||
import java.util.*
|
||||
|
||||
class DecompressItemsAdapter(activity: SimpleActivity, var listItems: MutableList<ListItem>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
|
||||
MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
|
||||
|
||||
private lateinit var fileDrawable: Drawable
|
||||
private lateinit var folderDrawable: Drawable
|
||||
|
|
|
@ -24,13 +24,13 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
|||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.dialogs.*
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.*
|
||||
import com.simplemobiletools.commons.models.FileDirItem
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.commons.views.FastScroller
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.filemanager.pro.R
|
||||
import com.simplemobiletools.filemanager.pro.activities.SimpleActivity
|
||||
|
@ -41,13 +41,13 @@ import com.simplemobiletools.filemanager.pro.helpers.*
|
|||
import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener
|
||||
import com.simplemobiletools.filemanager.pro.models.ListItem
|
||||
import com.stericson.RootTools.RootTools
|
||||
import java.io.BufferedInputStream
|
||||
import kotlinx.android.synthetic.main.item_file_dir_grid.view.*
|
||||
import kotlinx.android.synthetic.main.item_file_dir_list.view.*
|
||||
import kotlinx.android.synthetic.main.item_file_dir_list.view.item_frame
|
||||
import kotlinx.android.synthetic.main.item_file_dir_list.view.item_icon
|
||||
import kotlinx.android.synthetic.main.item_file_dir_list.view.item_name
|
||||
import kotlinx.android.synthetic.main.item_section.view.*
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
@ -57,9 +57,9 @@ import java.util.zip.ZipOutputStream
|
|||
|
||||
class ItemsAdapter(
|
||||
activity: SimpleActivity, var listItems: MutableList<ListItem>, val listener: ItemOperationsListener?, recyclerView: MyRecyclerView,
|
||||
val isPickMultipleIntent: Boolean, fastScroller: FastScroller?, val swipeRefreshLayout: SwipeRefreshLayout?, itemClick: (Any) -> Unit
|
||||
val isPickMultipleIntent: Boolean, val swipeRefreshLayout: SwipeRefreshLayout?, itemClick: (Any) -> Unit
|
||||
) :
|
||||
MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||
MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
||||
private val TYPE_FILE_DIR = 1
|
||||
private val TYPE_SECTION = 2
|
||||
|
@ -326,6 +326,7 @@ class ItemsAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun addFileUris(path: String, paths: ArrayList<String>) {
|
||||
if (activity.getIsPathDirectory(path)) {
|
||||
val shouldShowHidden = activity.config.shouldShowHidden
|
||||
|
@ -621,6 +622,7 @@ class ItemsAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun compressPaths(sourcePaths: List<String>, targetPath: String): Boolean {
|
||||
val queue = LinkedList<String>()
|
||||
val fos = activity.getFileOutputStreamSync(targetPath, "application/zip") ?: return false
|
||||
|
@ -759,7 +761,6 @@ class ItemsAdapter(
|
|||
textToHighlight = highlightText
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
fastScroller?.measureRecyclerView()
|
||||
}
|
||||
|
||||
fun updateFontSizes() {
|
||||
|
@ -899,4 +900,6 @@ class ItemsAdapter(
|
|||
fileDrawable = resources.getDrawable(R.drawable.ic_file_generic)
|
||||
fileDrawables = getFilePlaceholderDrawables(activity)
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = listItems.getOrNull(position)?.getBubbleText(activity, dateFormat, timeFormat) ?: ""
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ import com.simplemobiletools.filemanager.pro.extensions.config
|
|||
import kotlinx.android.synthetic.main.item_manage_favorite.view.*
|
||||
import java.util.*
|
||||
|
||||
class ManageFavoritesAdapter(activity: BaseSimpleActivity, var favorites: ArrayList<String>, val listener: RefreshRecyclerViewListener?,
|
||||
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
|
||||
class ManageFavoritesAdapter(
|
||||
activity: BaseSimpleActivity, var favorites: ArrayList<String>, val listener: RefreshRecyclerViewListener?,
|
||||
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
|
||||
|
||||
private val config = activity.config
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simplemobiletools.filemanager.pro.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Parcelable
|
||||
import android.util.AttributeSet
|
||||
|
@ -50,7 +51,6 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
|
||||
override fun onResume(textColor: Int, primaryColor: Int) {
|
||||
context!!.updateTextColors(this)
|
||||
items_fastscroller.updatePrimaryColor()
|
||||
storedItems = ArrayList()
|
||||
getRecyclerAdapter()?.apply {
|
||||
updatePrimaryColor(primaryColor)
|
||||
|
@ -58,7 +58,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
initDrawables()
|
||||
}
|
||||
|
||||
items_fastscroller.updateBubbleColors()
|
||||
items_fastscroller.updateColors(primaryColor, primaryColor.getContrastColor())
|
||||
|
||||
if (currentPath != "") {
|
||||
breadcrumbs.updateColor(textColor)
|
||||
|
@ -124,10 +124,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
breadcrumbs.updateFontSize(context!!.getTextSize())
|
||||
}
|
||||
|
||||
ItemsAdapter(
|
||||
activity as SimpleActivity, storedItems, this, items_list, isPickMultipleIntent, items_fastscroller,
|
||||
items_swipe_refresh
|
||||
) {
|
||||
ItemsAdapter(activity as SimpleActivity, storedItems, this, items_list, isPickMultipleIntent, items_swipe_refresh) {
|
||||
if ((it as? ListItem)?.isSectionTitle == true) {
|
||||
openDirectory(it.mPath)
|
||||
searchClosed()
|
||||
|
@ -143,18 +140,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
items_list.scheduleLayoutAnimation()
|
||||
}
|
||||
|
||||
val dateFormat = context!!.config.dateFormat
|
||||
val timeFormat = context!!.getTimeFormat()
|
||||
items_fastscroller.setViews(items_list, items_swipe_refresh) {
|
||||
val listItem = getRecyclerAdapter()?.listItems?.getOrNull(it)
|
||||
items_fastscroller.updateBubbleText(listItem?.getBubbleText(context, dateFormat, timeFormat) ?: "")
|
||||
}
|
||||
|
||||
getRecyclerLayoutManager().onRestoreInstanceState(scrollStates[currentPath])
|
||||
items_list.onGlobalLayout {
|
||||
items_fastscroller.setScrollToY(items_list.computeVerticalScrollOffset())
|
||||
calculateContentHeight(storedItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +148,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
|
||||
private fun getRecyclerLayoutManager() = (items_list.layoutManager as MyGridLayoutManager)
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun getItems(path: String, callback: (originalPath: String, items: ArrayList<ListItem>) -> Unit) {
|
||||
skipItemUpdating = false
|
||||
ensureBackgroundThread {
|
||||
|
@ -289,13 +276,13 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
|
||||
when {
|
||||
searchText.isEmpty() -> {
|
||||
items_list.beVisible()
|
||||
items_fastscroller.beVisible()
|
||||
getRecyclerAdapter()?.updateItems(storedItems)
|
||||
items_placeholder.beGone()
|
||||
items_placeholder_2.beGone()
|
||||
}
|
||||
searchText.length == 1 -> {
|
||||
items_list.beGone()
|
||||
items_fastscroller.beGone()
|
||||
items_placeholder.beVisible()
|
||||
items_placeholder_2.beVisible()
|
||||
}
|
||||
|
@ -332,14 +319,9 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
|
||||
activity?.runOnUiThread {
|
||||
getRecyclerAdapter()?.updateItems(listItems, text)
|
||||
items_list.beVisibleIf(listItems.isNotEmpty())
|
||||
items_fastscroller.beVisibleIf(listItems.isNotEmpty())
|
||||
items_placeholder.beVisibleIf(listItems.isEmpty())
|
||||
items_placeholder_2.beGone()
|
||||
|
||||
items_list.onGlobalLayout {
|
||||
items_fastscroller.setScrollToY(items_list.computeVerticalScrollOffset())
|
||||
calculateContentHeight(listItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,13 +373,13 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
isSearchOpen = false
|
||||
if (!skipItemUpdating) {
|
||||
getRecyclerAdapter()?.updateItems(storedItems)
|
||||
calculateContentHeight(storedItems)
|
||||
}
|
||||
|
||||
skipItemUpdating = false
|
||||
lastSearchedText = ""
|
||||
|
||||
items_swipe_refresh.isEnabled = true
|
||||
items_list.beVisible()
|
||||
items_fastscroller.beVisible()
|
||||
items_placeholder.beGone()
|
||||
items_placeholder_2.beGone()
|
||||
}
|
||||
|
@ -472,14 +454,6 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
}
|
||||
}
|
||||
|
||||
private fun calculateContentHeight(items: MutableList<ListItem>) {
|
||||
val layoutManager = items_list.layoutManager as MyGridLayoutManager
|
||||
val thumbnailHeight = layoutManager.getChildAt(0)?.height ?: 0
|
||||
val fullHeight = ((items.size - 1) / layoutManager.spanCount + 1) * thumbnailHeight
|
||||
items_fastscroller.setContentHeight(fullHeight)
|
||||
items_fastscroller.setScrollToY(items_list.computeVerticalScrollOffset())
|
||||
}
|
||||
|
||||
override fun increaseColumnCount() {
|
||||
if (currentViewType == VIEW_TYPE_GRID) {
|
||||
context?.config?.fileColumnCnt = ++(items_list.layoutManager as MyGridLayoutManager).spanCount
|
||||
|
@ -498,7 +472,6 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
|
|||
activity?.invalidateOptionsMenu()
|
||||
getRecyclerAdapter()?.apply {
|
||||
notifyItemRangeChanged(0, listItems.size)
|
||||
calculateContentHeight(listItems)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
|||
return
|
||||
}
|
||||
|
||||
ItemsAdapter(activity as SimpleActivity, recents, this, recents_list, isPickMultipleIntent, null, recents_swipe_refresh) {
|
||||
ItemsAdapter(activity as SimpleActivity, recents, this, recents_list, isPickMultipleIntent, recents_swipe_refresh) {
|
||||
clickedPath((it as FileDirItem).path)
|
||||
}.apply {
|
||||
recents_list.adapter = this
|
||||
|
|
|
@ -35,24 +35,20 @@
|
|||
android:textStyle="italic"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/mimetypes_list"
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/mimetypes_fastscroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:paddingTop="@dimen/small_margin"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.simplemobiletools.commons.views.FastScroller
|
||||
android:id="@+id/items_fastscroller"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:paddingStart="@dimen/normal_margin">
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/mimetypes_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:paddingTop="@dimen/small_margin"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager" />
|
||||
|
||||
<include layout="@layout/fastscroller_handle_vertical" />
|
||||
|
||||
</com.simplemobiletools.commons.views.FastScroller>
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -60,27 +60,22 @@
|
|||
android:textStyle="italic"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/items_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/breadcrumbs"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager" />
|
||||
|
||||
<com.simplemobiletools.commons.views.FastScroller
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/items_fastscroller"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/breadcrumbs"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:paddingStart="@dimen/normal_margin">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/breadcrumbs">
|
||||
|
||||
<include layout="@layout/fastscroller_handle_vertical" />
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/items_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager" />
|
||||
|
||||
</com.simplemobiletools.commons.views.FastScroller>
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
</RelativeLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
|
|
Loading…
Reference in New Issue