Saved Fragment states when switched instead of recreated them
- Added delete results button in main menu - Made search button color more recognisable
This commit is contained in:
parent
d3e77c2b9b
commit
aa5eab7743
10 changed files with 79 additions and 48 deletions
|
|
@ -23,7 +23,7 @@
|
||||||
<PersistentState>
|
<PersistentState>
|
||||||
<option name="values">
|
<option name="values">
|
||||||
<map>
|
<map>
|
||||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/videocam/baseline_videocam_24.xml" />
|
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/keyboard_arrow_down/baseline_keyboard_arrow_down_24.xml" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</PersistentState>
|
</PersistentState>
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<option name="values">
|
<option name="values">
|
||||||
<map>
|
<map>
|
||||||
<entry key="color" value="ff4d00" />
|
<entry key="color" value="ff4d00" />
|
||||||
<entry key="outputName" value="ic_video" />
|
<entry key="outputName" value="ic_download" />
|
||||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\youtubedl-android-0.13.1\youtubedl-android-0.13.1" />
|
<entry key="sourceFile" value="C:\Users\denis\Desktop\youtubedl-android-0.13.1\youtubedl-android-0.13.1" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="deploymentTargetDropDown">
|
|
||||||
<runningDeviceTargetSelectedWithDropDown>
|
|
||||||
<Target>
|
|
||||||
<type value="RUNNING_DEVICE_TARGET" />
|
|
||||||
<deviceKey>
|
|
||||||
<Key>
|
|
||||||
<type value="SERIAL_NUMBER" />
|
|
||||||
<value value="192.168.1.131:43991" />
|
|
||||||
</Key>
|
|
||||||
</deviceKey>
|
|
||||||
</Target>
|
|
||||||
</runningDeviceTargetSelectedWithDropDown>
|
|
||||||
<timeTargetWasSelectedWithDropDown value="2022-05-28T21:34:17.666332700Z" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_launcher_background.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_launcher_background.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
|
||||||
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_search.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.27704147071398033" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.27704147071398033" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2057460611677479" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history_list.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history_list.xml" value="0.2057460611677479" />
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Px;
|
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.cardview.widget.CardView;
|
import androidx.cardview.widget.CardView;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
@ -90,19 +89,18 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
private ArrayList<Video> resultObjects;
|
private ArrayList<Video> resultObjects;
|
||||||
private Queue<Video> downloadQueue;
|
private Queue<Video> downloadQueue;
|
||||||
private boolean hasResults = false;
|
|
||||||
private boolean isPlaylist = false;
|
|
||||||
private boolean downloadAll = false;
|
|
||||||
private int[] positions = {0,0};
|
private int[] positions = {0,0};
|
||||||
|
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
private DBManager dbManager;
|
private DBManager dbManager;
|
||||||
|
|
||||||
private final DownloadProgressCallback callback = new DownloadProgressCallback() {
|
private final DownloadProgressCallback callback = new DownloadProgressCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onProgressUpdate(float progress, long etaInSeconds, String line) {
|
public void onProgressUpdate(float progress, long etaInSeconds, String line) {
|
||||||
requireActivity().runOnUiThread(() -> progressBar.setProgress((int) progress)
|
requireActivity().runOnUiThread(() -> {
|
||||||
);
|
progressBar.setProgress((int) progress);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -138,12 +136,19 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
compositeDisposable = new CompositeDisposable();
|
compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
|
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
|
||||||
initViews();
|
initViews();
|
||||||
|
|
||||||
fragmentView.setOnScrollChangeListener((view, i, i1, i2, i3) -> positions = new int[]{i,i1});
|
fragmentView.setOnScrollChangeListener((view, i, i1, i2, i3) -> positions = new int[]{i,i1});
|
||||||
|
|
||||||
|
if(inputQuery != null){
|
||||||
|
parseQuery();
|
||||||
|
inputQuery = null;
|
||||||
|
return fragmentView;
|
||||||
|
}
|
||||||
|
|
||||||
dbManager = new DBManager(requireContext());
|
dbManager = new DBManager(requireContext());
|
||||||
resultObjects = dbManager.merrRezultatet();
|
resultObjects = dbManager.merrRezultatet();
|
||||||
|
|
||||||
|
|
@ -169,6 +174,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||||
|
menu.clear();
|
||||||
inflater.inflate(R.menu.main_menu, menu);
|
inflater.inflate(R.menu.main_menu, menu);
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
|
||||||
|
|
@ -204,9 +210,22 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.delete_results:
|
||||||
|
dbManager.clearResults();
|
||||||
|
linearLayout.removeAllViews();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void handleIntent(Intent intent){
|
public void handleIntent(Intent intent){
|
||||||
inputQuery = intent.getStringExtra(Intent.EXTRA_TEXT);
|
inputQuery = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
parseQuery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseQuery() {
|
private void parseQuery() {
|
||||||
|
|
@ -224,7 +243,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
if (inputQuery.contains("list=")) {
|
if (inputQuery.contains("list=")) {
|
||||||
type = "Playlist";
|
type = "Playlist";
|
||||||
isPlaylist = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +266,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
JSONObject element = dataArray.getJSONObject(i);
|
JSONObject element = dataArray.getJSONObject(i);
|
||||||
JSONObject snippet = element.getJSONObject("snippet");
|
JSONObject snippet = element.getJSONObject("snippet");
|
||||||
if(element.getJSONObject("id").getString("kind").equals("youtube#video")){
|
if(element.getJSONObject("id").getString("kind").equals("youtube#video")){
|
||||||
hasResults = true;
|
|
||||||
|
|
||||||
videoID = element.getJSONObject("id").getString("videoId");
|
videoID = element.getJSONObject("id").getString("videoId");
|
||||||
snippet.put("videoID", videoID);
|
snippet.put("videoID", videoID);
|
||||||
|
|
@ -282,7 +299,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
thread.start();
|
thread.start();
|
||||||
thread.join();
|
thread.join();
|
||||||
|
|
||||||
hasResults = true;
|
|
||||||
requestData = fixThumbnail(requestData);
|
requestData = fixThumbnail(requestData);
|
||||||
Video video = createVideofromJSON(requestData);
|
Video video = createVideofromJSON(requestData);
|
||||||
resultObjects.add(video);
|
resultObjects.add(video);
|
||||||
|
|
@ -303,7 +319,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
|
|
||||||
JSONArray dataArray = requestData.getJSONArray("items");
|
JSONArray dataArray = requestData.getJSONArray("items");
|
||||||
hasResults = true;
|
|
||||||
for(int i = 0; i < dataArray.length(); i++){
|
for(int i = 0; i < dataArray.length(); i++){
|
||||||
JSONObject element = dataArray.getJSONObject(i);
|
JSONObject element = dataArray.getJSONObject(i);
|
||||||
JSONObject snippet = element.getJSONObject("snippet");
|
JSONObject snippet = element.getJSONObject("snippet");
|
||||||
|
|
@ -785,5 +800,4 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,21 +2,17 @@ package com.deniscerri.ytdl;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.content.res.ComplexColorCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
import com.deniscerri.ytdl.databinding.ActivityMainBinding;
|
import com.deniscerri.ytdl.databinding.ActivityMainBinding;
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|
||||||
|
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
|
||||||
|
|
@ -33,6 +29,7 @@ public class MainActivity extends AppCompatActivity{
|
||||||
private HistoryFragment historyFragment;
|
private HistoryFragment historyFragment;
|
||||||
private SettingsFragment settingsFragment;
|
private SettingsFragment settingsFragment;
|
||||||
private Fragment lastFragment;
|
private Fragment lastFragment;
|
||||||
|
private FragmentManager fm;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
@ -51,23 +48,36 @@ public class MainActivity extends AppCompatActivity{
|
||||||
);
|
);
|
||||||
binding.bottomNavigationView.setItemActiveIndicatorColor(list);
|
binding.bottomNavigationView.setItemActiveIndicatorColor(list);
|
||||||
binding.bottomNavigationView.setItemRippleColor(list);
|
binding.bottomNavigationView.setItemRippleColor(list);
|
||||||
binding.bottomNavigationView.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.material_dynamic_neutral10));
|
|
||||||
|
int nightMode = getApplicationContext().getResources().getConfiguration().uiMode &
|
||||||
|
Configuration.UI_MODE_NIGHT_MASK;
|
||||||
|
if(nightMode == Configuration.UI_MODE_NIGHT_YES){
|
||||||
|
binding.bottomNavigationView.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.material_dynamic_neutral10));
|
||||||
|
}
|
||||||
|
|
||||||
|
getWindow().setStatusBarColor(ContextCompat.getColor(getApplicationContext(), R.color.material_dynamic_neutral10));
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
homeFragment = new HomeFragment();
|
homeFragment = new HomeFragment();
|
||||||
historyFragment = new HistoryFragment();
|
historyFragment = new HistoryFragment();
|
||||||
settingsFragment = new SettingsFragment();
|
settingsFragment = new SettingsFragment();
|
||||||
|
|
||||||
|
fm = getSupportFragmentManager();
|
||||||
|
fm.beginTransaction()
|
||||||
|
.replace(R.id.frame_layout, homeFragment)
|
||||||
|
.add(R.id.frame_layout, historyFragment)
|
||||||
|
.add(R.id.frame_layout, settingsFragment)
|
||||||
|
.hide(historyFragment)
|
||||||
|
.hide(settingsFragment)
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
lastFragment = homeFragment;
|
||||||
|
|
||||||
replaceFragment(homeFragment);
|
|
||||||
binding.bottomNavigationView.setOnItemSelectedListener(item -> {
|
binding.bottomNavigationView.setOnItemSelectedListener(item -> {
|
||||||
switch(item.getItemId()){
|
switch(item.getItemId()){
|
||||||
case R.id.home:
|
case R.id.home:
|
||||||
|
|
@ -100,6 +110,7 @@ public class MainActivity extends AppCompatActivity{
|
||||||
Log.e(TAG, action);
|
Log.e(TAG, action);
|
||||||
if(Intent.ACTION_SEND.equals(action)){
|
if(Intent.ACTION_SEND.equals(action)){
|
||||||
homeFragment.handleIntent(intent);
|
homeFragment.handleIntent(intent);
|
||||||
|
replaceFragment(homeFragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,10 +121,8 @@ public class MainActivity extends AppCompatActivity{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceFragment(Fragment f){
|
private void replaceFragment(Fragment f){
|
||||||
FragmentManager fm = getSupportFragmentManager();
|
fm.beginTransaction().hide(lastFragment).show(f).commit();
|
||||||
FragmentTransaction fragmentTransaction = fm.beginTransaction();
|
lastFragment = f;
|
||||||
fragmentTransaction.replace(R.id.frame_layout, f);
|
|
||||||
fragmentTransaction.commit();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,24 @@ public class DBManager extends SQLiteOpenHelper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearResults(){
|
||||||
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS " + results_table_name);
|
||||||
|
|
||||||
|
String query = "CREATE TABLE " + results_table_name + " ("
|
||||||
|
+ id + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
+ videoId + " TEXT,"
|
||||||
|
+ title + " TEXT,"
|
||||||
|
+ author + " TEXT,"
|
||||||
|
+ thumb + " TEXT,"
|
||||||
|
+ type + " TEXT,"
|
||||||
|
+ time + " TEXT,"
|
||||||
|
+ isPlaylistItem + " BOOLEAN)";
|
||||||
|
|
||||||
|
db.execSQL(query);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
|
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
|
||||||
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + results_table_name);
|
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + results_table_name);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:height="24dp"
|
<vector android:height="24dp"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
<path android:fillColor="@color/colorAccent" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,11 @@
|
||||||
app:showAsAction="ifRoom|collapseActionView"
|
app:showAsAction="ifRoom|collapseActionView"
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
|
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/delete_results"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/fshi_rezultatet"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,4 +41,5 @@
|
||||||
<string name="shkruaj_url_e_youtube">Shkruaj URL e YouTube</string>
|
<string name="shkruaj_url_e_youtube">Shkruaj URL e YouTube</string>
|
||||||
<string name="download_path">sdcard/Download</string>
|
<string name="download_path">sdcard/Download</string>
|
||||||
<string name="fshi_historin">Fshi Historinë</string>
|
<string name="fshi_historin">Fshi Historinë</string>
|
||||||
|
<string name="fshi_rezultatet">Fshi rezultatet</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
<item name="colorPrimaryDark">@color/material_dynamic_primary20</item>
|
<item name="colorPrimaryDark">@color/material_dynamic_primary20</item>
|
||||||
<item name="colorAccent">@color/material_dynamic_primary40</item>
|
<item name="colorAccent">@color/material_dynamic_primary40</item>
|
||||||
<item name="background">@color/white</item>
|
<item name="background">@color/white</item>
|
||||||
<item name="android:statusBarColor">@color/material_dynamic_neutral10</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Base application theme less than android 12 -->
|
<!-- Base application theme less than android 12 -->
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue