mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 01:55:50 +01:00
Huawei: Added selecting for more than one item for music management
This commit is contained in:
parent
16a8efb7ee
commit
7edb1f5941
@ -31,6 +31,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
@ -80,6 +81,12 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
private FloatingActionButton fabMusicUpload;
|
||||
private FloatingActionButton fabMusicPlaylistAdd;
|
||||
|
||||
|
||||
private MaterialToolbar bottomToolbar;
|
||||
private TextView selectionInfo;
|
||||
private ImageButton selectionAddPlaylist;
|
||||
private ImageButton selectionDelete;
|
||||
|
||||
private int maxMusicCount = 0;
|
||||
private int maxPlaylistCount = 0;
|
||||
|
||||
@ -134,6 +141,14 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
|
||||
hideActionButtons();
|
||||
|
||||
bottomToolbar = findViewById(R.id.bottom_toolbar);
|
||||
|
||||
ImageButton cancelSelection = findViewById(R.id.music_cancel_selection);
|
||||
selectionInfo = findViewById(R.id.music_selection_info);
|
||||
selectionAddPlaylist = findViewById(R.id.music_multiselect_add_to_playlist);
|
||||
selectionDelete = findViewById(R.id.music_multiselect_delete);
|
||||
|
||||
|
||||
RecyclerView musicListView = findViewById(R.id.music_songs_list);
|
||||
loadingView = findViewById(R.id.music_loading);
|
||||
|
||||
@ -153,20 +168,56 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
|
||||
musicAdapter = new MusicListAdapter(
|
||||
musicList,
|
||||
new MusicListAdapter.onItemAction() {
|
||||
new MusicListAdapter.onDataAction() {
|
||||
@Override
|
||||
public void onItemClick(View view, GBDeviceMusic music) {
|
||||
openPopupMenu(view, music);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(View view, GBDeviceMusic music) {
|
||||
return false;
|
||||
public void onMultiSelect(int count, boolean limit) {
|
||||
multiSelect(count, limit);
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
musicListView.setAdapter(musicAdapter);
|
||||
|
||||
cancelSelection.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
musicAdapter.clearSelectedItems();
|
||||
}
|
||||
});
|
||||
|
||||
selectionAddPlaylist.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
List<GBDeviceMusic> musics = musicAdapter.getSelectedItems();
|
||||
if(!musics.isEmpty()) {
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
for(GBDeviceMusic music: musics) {
|
||||
list.add(music.getId());
|
||||
}
|
||||
addMusicSongToPlaylist(list);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
selectionDelete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
List<GBDeviceMusic> musics = musicAdapter.getSelectedItems();
|
||||
if(!musics.isEmpty()) {
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
for(GBDeviceMusic music: musics) {
|
||||
list.add(music.getId());
|
||||
}
|
||||
deleteMusicMultipleConfirm(list);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
playlistSpinnerLayout = findViewById(R.id.music_playlists_layout);
|
||||
|
||||
playlistsSpinner = findViewById(R.id.music_playlists);
|
||||
@ -194,6 +245,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
GBDeviceMusicPlaylist item = (GBDeviceMusicPlaylist) adapterView.getItemAtPosition(i);
|
||||
musicAdapter.clearSelectedItems();
|
||||
if (item.getId() == 0) {
|
||||
deletePlaylist.setVisibility(View.GONE);
|
||||
renamePlaylist.setVisibility(View.GONE);
|
||||
@ -218,6 +270,25 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
playlistsSpinner.setAdapter(playlistAdapter);
|
||||
}
|
||||
|
||||
private void multiSelect(int count, boolean limit) {
|
||||
if(limit) {
|
||||
GB.toast(this, R.string.music_multiselect_limit, Toast.LENGTH_LONG, GB.WARN);
|
||||
}
|
||||
if(count > 0) {
|
||||
hideActionButtons();
|
||||
bottomToolbar.setVisibility(View.VISIBLE);
|
||||
selectionInfo.setText("" + count);
|
||||
if(playlists.size() <= 1) {
|
||||
selectionAddPlaylist.setVisibility(View.GONE);
|
||||
} else {
|
||||
selectionAddPlaylist.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
bottomToolbar.setVisibility(View.GONE);
|
||||
showActionButtons();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideActionButtons() {
|
||||
fabMusicUpload.hide();
|
||||
fabMusicPlaylistAdd.hide();
|
||||
@ -246,6 +317,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
private void stopLoading() {
|
||||
loadingTimeout.removeCallbacks(loadingRunnable);
|
||||
loadingView.setVisibility(View.GONE);
|
||||
musicAdapter.clearSelectedItems();
|
||||
showActionButtons();
|
||||
}
|
||||
|
||||
@ -311,7 +383,6 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
}
|
||||
|
||||
GBDeviceMusicPlaylist current = (GBDeviceMusicPlaylist) playlistsSpinner.getSelectedItem();
|
||||
musicList.clear();
|
||||
if (current.getId() == 0) {
|
||||
menu.removeItem(R.id.musicmanager_delete_from_playlist);
|
||||
} else {
|
||||
@ -335,19 +406,36 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
deleteMusicConfirm(music);
|
||||
return true;
|
||||
} else if (itemId == R.id.musicmanager_add_to_playlist) {
|
||||
addMusicSongToPlaylist(music);
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
list.add(music.getId());
|
||||
addMusicSongToPlaylist(list);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deleteMusicConfirm(final GBDeviceMusic music) {
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
list.add(music.getId());
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.Delete)
|
||||
.setMessage(this.getString(R.string.music_delete_confirm_description, music.getTitle()))
|
||||
.setIcon(R.drawable.ic_warning)
|
||||
.setPositiveButton(android.R.string.yes, (dialog, whichButton) -> {
|
||||
deleteMusicFromDevice((GBDeviceMusicPlaylist) playlistsSpinner.getSelectedItem(), music);
|
||||
deleteMusicFromDevice((GBDeviceMusicPlaylist) playlistsSpinner.getSelectedItem(), list);
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void deleteMusicMultipleConfirm(final ArrayList<Integer> list) {
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.Delete)
|
||||
.setMessage(this.getString(R.string.music_delete_multiple_confirm_description, list.size()))
|
||||
.setIcon(R.drawable.ic_warning)
|
||||
.setPositiveButton(android.R.string.yes, (dialog, whichButton) -> {
|
||||
deleteMusicFromDevice((GBDeviceMusicPlaylist) playlistsSpinner.getSelectedItem(), list);
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
@ -368,17 +456,13 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
GBApplication.deviceService(mGBDevice).onMusicOperation(2, playlist.getId(), newPlaylistName, null);
|
||||
}
|
||||
|
||||
private void addMusicToDevicePlaylist(GBDeviceMusicPlaylist playlist, final GBDeviceMusic music) {
|
||||
private void addMusicToDevicePlaylist(GBDeviceMusicPlaylist playlist, final ArrayList<Integer> list) {
|
||||
startLoading();
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
list.add(music.getId());
|
||||
GBApplication.deviceService(mGBDevice).onMusicOperation(3, playlist.getId(), null, list);
|
||||
}
|
||||
|
||||
private void deleteMusicFromDevice(GBDeviceMusicPlaylist playlist, final GBDeviceMusic music) {
|
||||
private void deleteMusicFromDevice(GBDeviceMusicPlaylist playlist, final ArrayList<Integer> list) {
|
||||
startLoading();
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
list.add(music.getId());
|
||||
GBApplication.deviceService(mGBDevice).onMusicOperation(4, playlist.getId(), null, list);
|
||||
}
|
||||
|
||||
@ -398,7 +482,9 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
.setView(container)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
|
||||
String playlistName = input.getText().toString();
|
||||
if(!playlistName.isEmpty()) {
|
||||
addPlaylistToDevice(playlistName);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
@ -423,7 +509,9 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
.setView(container)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
|
||||
String playlistName = input.getText().toString();
|
||||
if(!playlistName.isEmpty()) {
|
||||
renamePlaylistOnDevice(playlist, playlistName);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
@ -443,7 +531,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
.show();
|
||||
}
|
||||
|
||||
private void addMusicSongToPlaylist(final GBDeviceMusic music) {
|
||||
private void addMusicSongToPlaylist(final ArrayList<Integer> list) {
|
||||
final Spinner dPlaylists = new Spinner(this);
|
||||
|
||||
List<GBDeviceMusicPlaylist> dialogPlaylists = new ArrayList<>();
|
||||
@ -469,7 +557,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
.setView(container)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
|
||||
GBDeviceMusicPlaylist playlist = (GBDeviceMusicPlaylist) dPlaylists.getSelectedItem();
|
||||
addMusicToDevicePlaylist(playlist, music);
|
||||
addMusicToDevicePlaylist(playlist, list);
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
@ -513,7 +601,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
int playlistIndex = intent.getIntExtra("playlistIndex", -1);
|
||||
String playlistName = intent.getStringExtra("playlistName");
|
||||
|
||||
if (playlistIndex != -1 && !TextUtils.isEmpty(playlistName)) {
|
||||
if (playlistIndex != -1 && playlistName != null) {
|
||||
playlists.add(new GBDeviceMusicPlaylist(playlistIndex, playlistName, new ArrayList<>()));
|
||||
playlistAdapter.notifyDataSetChanged();
|
||||
}
|
||||
@ -531,7 +619,7 @@ public class MusicManagerActivity extends AbstractGBActivity {
|
||||
} else if (operation == 2) {
|
||||
int playlistIndex = intent.getIntExtra("playlistIndex", -1);
|
||||
String playlistName = intent.getStringExtra("playlistName");
|
||||
if (playlistIndex != -1 && !TextUtils.isEmpty(playlistName)) {
|
||||
if (playlistIndex != -1 && playlistName != null) {
|
||||
for (GBDeviceMusicPlaylist playlist : playlists) {
|
||||
if (playlist.getId() == playlistIndex) {
|
||||
playlist.setName(playlistName);
|
||||
|
@ -3,13 +3,11 @@ package nodomain.freeyourgadget.gadgetbridge.adapter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
@ -17,15 +15,18 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceMusic;
|
||||
|
||||
public class MusicListAdapter extends RecyclerView.Adapter<MusicListAdapter.MusicViewHolder> {
|
||||
|
||||
public interface onItemAction {
|
||||
public static int MAX_MULTISELECT_COUNT = 50;
|
||||
public interface onDataAction {
|
||||
void onItemClick(View view, GBDeviceMusic music);
|
||||
boolean onItemLongClick(View view, GBDeviceMusic music);
|
||||
void onMultiSelect(int count, boolean limit);
|
||||
}
|
||||
|
||||
private final List<GBDeviceMusic> musicList;
|
||||
private final onItemAction callback;
|
||||
private final onDataAction callback;
|
||||
|
||||
public MusicListAdapter(List<GBDeviceMusic> list, onItemAction callback) {
|
||||
private final List<GBDeviceMusic> selectedItems = new ArrayList<>();
|
||||
|
||||
public MusicListAdapter(List<GBDeviceMusic> list, onDataAction callback) {
|
||||
this.musicList = list;
|
||||
this.callback = callback;
|
||||
}
|
||||
@ -46,6 +47,20 @@ public class MusicListAdapter extends RecyclerView.Adapter<MusicListAdapter.Musi
|
||||
return new MusicViewHolder(view);
|
||||
}
|
||||
|
||||
private void toggleSelection(GBDeviceMusic music) {
|
||||
if(selectedItems.size() >= MAX_MULTISELECT_COUNT) {
|
||||
callback.onMultiSelect(selectedItems.size(), true);
|
||||
return;
|
||||
}
|
||||
if(selectedItems.contains(music)) {
|
||||
selectedItems.remove(music);
|
||||
} else {
|
||||
selectedItems.add(music);
|
||||
}
|
||||
notifyItemChanged(musicList.indexOf(music));
|
||||
callback.onMultiSelect(selectedItems.size(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final MusicListAdapter.MusicViewHolder holder, int position) {
|
||||
final GBDeviceMusic music = musicList.get(position);
|
||||
@ -53,32 +68,50 @@ public class MusicListAdapter extends RecyclerView.Adapter<MusicListAdapter.Musi
|
||||
holder.musicTitle.setText(music.getTitle());
|
||||
holder.musicArtist.setText(music.getArtist());
|
||||
|
||||
holder.icon.setSelected(selectedItems.contains(music));
|
||||
|
||||
if(callback != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(!selectedItems.isEmpty()) {
|
||||
toggleSelection(music);
|
||||
} else {
|
||||
callback.onItemClick(view, music);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
return callback.onItemLongClick(view, music);
|
||||
toggleSelection(music);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSelectedItems() {
|
||||
selectedItems.clear();
|
||||
notifyDataSetChanged();
|
||||
callback.onMultiSelect(selectedItems.size(), false);
|
||||
}
|
||||
|
||||
public List<GBDeviceMusic> getSelectedItems() {
|
||||
return selectedItems;
|
||||
}
|
||||
|
||||
public static class MusicViewHolder extends RecyclerView.ViewHolder {
|
||||
final TextView musicArtist;
|
||||
final TextView musicTitle;
|
||||
final ImageView icon;
|
||||
|
||||
MusicViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
musicArtist = itemView.findViewById(R.id.item_details);
|
||||
musicTitle = itemView.findViewById(R.id.item_name);
|
||||
icon = itemView.findViewById(R.id.item_image);
|
||||
}
|
||||
|
||||
}
|
||||
|
5
app/src/main/res/drawable/ic_music_item.xml
Normal file
5
app/src/main/res/drawable/ic_music_item.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true" android:drawable="@drawable/ic_edit" />
|
||||
<item android:drawable="@drawable/ic_music" />
|
||||
</selector>
|
@ -26,6 +26,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="20" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/music_playlist_rename"
|
||||
android:layout_width="48dp"
|
||||
@ -34,6 +35,7 @@
|
||||
android:background="@null"
|
||||
android:contentDescription="@string/music_rename_playlist"
|
||||
app:srcCompat="@drawable/ic_edit" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/music_playlist_delete"
|
||||
android:layout_width="48dp"
|
||||
@ -53,6 +55,7 @@
|
||||
android:layout_centerHorizontal="true"
|
||||
android:divider="@null" />
|
||||
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_music_upload"
|
||||
android:layout_width="wrap_content"
|
||||
@ -61,7 +64,6 @@
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/music_new_playlist"
|
||||
app:srcCompat="@android:drawable/stat_sys_upload" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
@ -73,8 +75,65 @@
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="90dp"
|
||||
app:srcCompat="@drawable/ic_add"
|
||||
/>
|
||||
android:contentDescription="@string/music_new_playlist"
|
||||
app:srcCompat="@drawable/ic_add" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/bottom_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="54dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@color/primary_dark">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/music_cancel_selection"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:contentDescription="@string/music_rename_playlist"
|
||||
app:srcCompat="@drawable/ic_action_notify_cancel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/music_selection_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_weight="1"
|
||||
android:text="" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/music_multiselect_add_to_playlist"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_toStartOf="@id/music_multiselect_delete"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:contentDescription="@string/music_add_to_playlist"
|
||||
app:srcCompat="@drawable/ic_checklist" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/music_multiselect_delete"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:contentDescription="@string/music_delete"
|
||||
app:srcCompat="@drawable/ic_delete" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/music_loading"
|
||||
|
@ -26,7 +26,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
android:src="@drawable/ic_music"/>
|
||||
android:src="@drawable/ic_music_item"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -3462,6 +3462,7 @@
|
||||
<string name="pref_music_management_title">Manage Music</string>
|
||||
<string name="pref_music_management_summary">Manage music on the watch</string>
|
||||
<string name="music_delete_confirm_description">Are you sure you want to delete \'%1$s\'?</string>
|
||||
<string name="music_delete_multiple_confirm_description">Are you sure you want to delete \'%1$d\' songs?</string>
|
||||
<string name="music_add_to_playlist">Add to playlist</string>
|
||||
<string name="music_delete_from_playlist">Delete from playlist</string>
|
||||
<string name="music_delete">Delete song</string>
|
||||
@ -3470,6 +3471,7 @@
|
||||
<string name="music_rename_playlist">Rename playlist</string>
|
||||
<string name="music_error">Error occurred</string>
|
||||
<string name="music_huawei_device_info">Supported formats: %1$s\nWatch storage: %2$d MB</string>
|
||||
<string name="music_multiselect_limit">Limit for selecting more than one item reached</string>
|
||||
|
||||
<!-- Welcome screens strings -->
|
||||
<string name="first_start_welcome_title">Welcome</string>
|
||||
|
Loading…
Reference in New Issue
Block a user