Added a option to toggle fast forward / Added NSFW extension toggle to extension settings (#48)

* Remove 18+ extension if Anilist 18+ is off
 ~requested by @arif

* Translation filter for extension(WIP)

* Added a option to toggle fast forward
suggested by arif

* Added NFSW toggle to extension settings
now it will be more easy rather then going to anilist to toggle it
 ~suggested by arif

* Forgot to undo this

* changed icons in extension setting

* get rid of companion object (todo)

* get rid of companion object (todo)

---------

Co-authored-by: rebelonion <87634197+rebelonion@users.noreply.github.com>
This commit is contained in:
aayush262 2023-11-18 02:40:58 +05:30 committed by GitHub
parent 5543d29317
commit 736b06bdbe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 192 additions and 55 deletions

View file

@ -823,7 +823,9 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
//FastRewind (Left Panel)
val fastRewindDetector = GestureDetector(this, object : GesturesListener() {
override fun onLongClick(event: MotionEvent) = fastForward()
override fun onLongClick(event: MotionEvent) {
if (settings.fastforward) fastForward()
}
override fun onDoubleClick(event: MotionEvent) {
doubleTap(false, event)
@ -853,8 +855,9 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
//FastForward (Right Panel)
val fastForwardDetector = GestureDetector(this, object : GesturesListener() {
override fun onLongClick(event: MotionEvent) = fastForward()
override fun onLongClick(event: MotionEvent) {
if (settings.fastforward) fastForward()
}
override fun onDoubleClick(event: MotionEvent) {
doubleTap(true, event)
}

View file

@ -15,6 +15,7 @@ class DevelopersDialogFragment : BottomSheetDialogFragment() {
private val developers = arrayOf(
Developer("rebelonion","https://avatars.githubusercontent.com/u/87634197?v=4","Owner and Maintainer","https://github.com/rebelonion"),
Developer("Wai What", "https://avatars.githubusercontent.com/u/149729762?v=4", "Icon Designer", "https://github.com/WaiWhat"),
Developer("Aayush262", "https://avatars.githubusercontent.com/u/99584765?v=4", "Contributor", "https://github.com/aayush2622"),
)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {

View file

@ -6,12 +6,14 @@ import android.os.Build.VERSION.*
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.widget.AutoCompleteTextView
import android.widget.LinearLayout
import android.widget.SearchView
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
@ -21,6 +23,9 @@ import ani.dantotsu.databinding.ActivityExtensionsBinding
import ani.dantotsu.themes.ThemeManager
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ExtensionsActivity : AppCompatActivity() {
private val restartMainActivity = object : OnBackPressedCallback(false) {
@ -86,6 +91,12 @@ class ExtensionsActivity : AppCompatActivity() {
initActivity(this)
binding.languageselect.setOnClickListener {
val popup = PopupMenu(this, it)
popup.inflate(R.menu.launguage_selector_menu)
popup.show()
}
binding.settingsContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = statusBarHeight

View file

@ -222,15 +222,9 @@ class InstalledAnimeExtensionsFragment : Fragment() {
holder.extensionIconImageView.setImageDrawable(extension.icon)
}
if (extension.hasUpdate) {
holder.closeTextView.text = "Update"
holder.closeTextView.setTextColor(
ContextCompat.getColor(
holder.itemView.context,
R.color.warning
)
)
holder.closeTextView.setImageResource(R.drawable.ic_round_sync_24)
} else {
holder.closeTextView.text = "Uninstall"
holder.closeTextView.setImageResource(R.drawable.ic_round_delete_24)
}
holder.closeTextView.setOnClickListener {
onUninstallClicked(extension)
@ -245,7 +239,7 @@ class InstalledAnimeExtensionsFragment : Fragment() {
val extensionVersionTextView: TextView = view.findViewById(R.id.extensionVersionTextView)
val settingsImageView: ImageView = view.findViewById(R.id.settingsImageView)
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
val closeTextView: ImageView = view.findViewById(R.id.closeTextView)
}
companion object {

View file

@ -215,15 +215,9 @@ class InstalledMangaExtensionsFragment : Fragment() {
holder.extensionIconImageView.setImageDrawable(extension.icon)
}
if (extension.hasUpdate) {
holder.closeTextView.text = "Update"
holder.closeTextView.setTextColor(
ContextCompat.getColor(
holder.itemView.context,
R.color.warning
)
)
holder.closeTextView.setImageResource(R.drawable.ic_round_sync_24)
} else {
holder.closeTextView.text = "Uninstall"
holder.closeTextView.setImageResource(R.drawable.ic_round_delete_24)
}
holder.closeTextView.setOnClickListener {
onUninstallClicked(extension)
@ -238,7 +232,7 @@ class InstalledMangaExtensionsFragment : Fragment() {
val extensionVersionTextView: TextView = view.findViewById(R.id.extensionVersionTextView)
val settingsImageView: ImageView = view.findViewById(R.id.settingsImageView)
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
val closeTextView: ImageView = view.findViewById(R.id.closeTextView)
}
companion object {

View file

@ -40,6 +40,7 @@ data class PlayerSettings(
var focusPause: Boolean = true,
var gestures: Boolean = true,
var doubleTap: Boolean = true,
var fastforward: Boolean = true,
var seekTime: Int = 10,
var skipTime: Int = 85,

View file

@ -183,7 +183,11 @@ class PlayerSettingsActivity : AppCompatActivity() {
settings.doubleTap = isChecked
saveData(player, settings)
}
binding.playerSettingsFastForward.isChecked = settings.fastforward
binding.playerSettingsFastForward.setOnCheckedChangeListener { _, isChecked ->
settings.fastforward = isChecked
saveData(player, settings)
}
binding.playerSettingsSeekTime.value = settings.seekTime.toFloat()
binding.playerSettingsSeekTime.addOnChangeListener { _, value, _ ->
settings.seekTime = value.toInt()

View file

@ -50,6 +50,11 @@ class SettingsActivity : AppCompatActivity() {
private val restartMainActivity = object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() = startMainActivity(this@SettingsActivity)
}
companion object {
@Volatile
var isNsfwEnabled: Boolean = loadData("NFSWExtension") ?: false
}
lateinit var binding: ActivitySettingsBinding
private val extensionInstaller = Injekt.get<BasePreferences>().extensionInstaller()
private val networkPreferences = Injekt.get<NetworkPreferences>()
@ -167,6 +172,12 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
binding.skipExtensionIcons.setOnCheckedChangeListener { _, isChecked ->
saveData("skip_extension_icons", isChecked)
}
binding.NSFWExtension.isChecked = loadData("NFSWExtension") ?: false
binding.NSFWExtension.setOnCheckedChangeListener { _, isChecked ->
isNsfwEnabled = isChecked
saveData("NFSWExtension", isChecked)
}
binding.userAgent.setText(networkPreferences.defaultUserAgent().get())
binding.userAgent.setOnEditorActionListener { _, _, _ ->

View file

@ -15,6 +15,7 @@ import androidx.paging.PagingState
import androidx.paging.cachedIn
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.settings.SettingsActivity
import ani.dantotsu.databinding.ItemExtensionAllBinding
import ani.dantotsu.loadData
import com.bumptech.glide.Glide
@ -82,16 +83,20 @@ class AnimeExtensionPagingSource(
} else {
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
}
val filternfsw = if(SettingsActivity.isNsfwEnabled) {//TODO
filteredExtensions
} else {
filteredExtensions.filterNot { it.isNsfw }
}
return try {
val sublist = filteredExtensions.subList(
val sublist = filternfsw.subList(
fromIndex = position,
toIndex = (position + params.loadSize).coerceAtMost(filteredExtensions.size)
toIndex = (position + params.loadSize).coerceAtMost(filternfsw.size)
)
LoadResult.Page(
data = sublist,
prevKey = if (position == 0) null else position - params.loadSize,
nextKey = if (position + params.loadSize >= filteredExtensions.size) null else position + params.loadSize
nextKey = if (position + params.loadSize >= filternfsw.size) null else position + params.loadSize
)
} catch (e: Exception) {
LoadResult.Error(e)

View file

@ -16,6 +16,7 @@ import androidx.paging.PagingState
import androidx.paging.cachedIn
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.settings.SettingsActivity
import ani.dantotsu.databinding.ItemExtensionAllBinding
import ani.dantotsu.loadData
import com.bumptech.glide.Glide
@ -86,16 +87,20 @@ class MangaExtensionPagingSource(
} else {
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
}
val filternfsw = if(SettingsActivity.isNsfwEnabled) {//TODO
filteredExtensions
} else {
filteredExtensions.filterNot { it.isNsfw }
}
return try {
val sublist = filteredExtensions.subList(
val sublist = filternfsw.subList(
fromIndex = position,
toIndex = (position + params.loadSize).coerceAtMost(filteredExtensions.size)
toIndex = (position + params.loadSize).coerceAtMost(filternfsw.size)
)
LoadResult.Page(
data = sublist,
prevKey = if (position == 0) null else position - params.loadSize,
nextKey = if (position + params.loadSize >= filteredExtensions.size) null else position + params.loadSize
nextKey = if (position + params.loadSize >= filternfsw.size) null else position + params.loadSize
)
} catch (e: Exception) {
LoadResult.Error(e)

View file

@ -0,0 +1,20 @@
<vector android:height="24dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000" android:pathData="M10,12V17"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
<path android:fillColor="#00000000" android:pathData="M14,12V17"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
<path android:fillColor="#00000000" android:pathData="M4,7H20"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
<path android:fillColor="#00000000"
android:pathData="M6,10V18C6,19.657 7.343,21 9,21H15C16.657,21 18,19.657 18,18V10"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
<path android:fillColor="#00000000"
android:pathData="M9,5C9,3.895 9.895,3 11,3H13C14.105,3 15,3.895 15,5V7H9V5Z"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
</vector>

View file

@ -0,0 +1,7 @@
<vector android:height="24dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000"
android:pathData="M12,12H12.01M12,6H12.01M12,18H12.01M13,12C13,12.552 12.552,13 12,13C11.448,13 11,12.552 11,12C11,11.448 11.448,11 12,11C12.552,11 13,11.448 13,12ZM13,18C13,18.552 12.552,19 12,19C11.448,19 11,18.552 11,18C11,17.448 11.448,17 12,17C12.552,17 13,17.448 13,18ZM13,6C13,6.552 12.552,7 12,7C11.448,7 11,6.552 11,6C11,5.448 11.448,5 12,5C12.552,5 13,5.448 13,6Z"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
</vector>

View file

@ -0,0 +1,7 @@
<vector android:height="24dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0F0F0F" android:pathData="M20,1C20,0.448 20.448,0 21,0C21.552,0 22,0.448 22,1V2H23C23.552,2 24,2.448 24,3C24,3.552 23.552,4 23,4H22V5C22,5.552 21.552,6 21,6C20.448,6 20,5.552 20,5V4H19C18.448,4 18,3.552 18,3C18,2.448 18.448,2 19,2H20V1Z"/>
<path android:fillColor="#0F0F0F" android:pathData="M21.194,8.075C21.702,7.858 22.297,8.091 22.467,8.617C23.145,10.715 23.179,12.977 22.552,15.106C21.831,17.557 20.279,19.68 18.163,21.112C16.046,22.543 13.498,23.193 10.955,22.95C8.412,22.708 6.032,21.587 4.225,19.781C2.418,17.976 1.295,15.597 1.051,13.054C0.806,10.511 1.454,7.962 2.883,5.845C4.313,3.728 6.435,2.174 8.885,1.45C11.014,0.822 13.276,0.854 15.374,1.53C15.9,1.7 16.134,2.295 15.918,2.803C15.701,3.311 15.114,3.545 14.585,3.386C12.918,2.886 11.135,2.878 9.453,3.375C7.45,3.966 5.715,5.237 4.547,6.968C3.378,8.699 2.848,10.783 3.048,12.862C3.248,14.941 4.166,16.885 5.643,18.362C7.121,19.838 9.066,20.754 11.146,20.952C13.225,21.151 15.308,20.619 17.038,19.449C18.768,18.279 20.037,16.543 20.627,14.54C21.122,12.857 21.113,11.074 20.612,9.408C20.452,8.879 20.686,8.291 21.194,8.075Z"/>
<path android:fillColor="#0F0F0F" android:pathData="M7.711,9.145L7.294,9.353C6.7,9.65 6,9.218 6,8.553C6,8.214 6.191,7.904 6.494,7.753L7.789,7.106C7.928,7.036 8.081,7 8.236,7H9C9.552,7 10,7.448 10,8V16C10,16.552 9.552,17 9,17C8.448,17 8,16.552 8,16V9.324C8,9.175 7.844,9.078 7.711,9.145Z"/>
<path android:fillColor="#0F0F0F" android:fillType="evenOdd" android:pathData="M18,9C18,7.895 17.105,7 16,7H14C12.895,7 12,7.895 12,9V10.5C12,11.328 12.672,12 13.5,12C12.672,12 12,12.672 12,13.5V15C12,16.105 12.895,17 14,17H16C17.105,17 18,16.105 18,15V13.5C18,12.672 17.328,12 16.5,12C17.328,12 18,11.328 18,10.5V9ZM16,10C16,9.448 15.552,9 15,9C14.448,9 14,9.448 14,10C14,10.552 14.448,11 15,11C15.552,11 16,10.552 16,10ZM16,14C16,14.552 15.552,15 15,15C14.448,15 14,14.552 14,14C14,13.448 14.448,13 15,13C15.552,13 16,13.448 16,14Z"/>
</vector>

View file

@ -0,0 +1,7 @@
<vector android:height="24dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000"
android:pathData="M12.913,17H20.087M12.913,17L11,21M12.913,17L15.778,11.009C16.009,10.526 16.125,10.285 16.283,10.209C16.42,10.142 16.58,10.142 16.717,10.209C16.875,10.285 16.991,10.526 17.222,11.009L20.087,17M20.087,17L22,21M2,5H8M8,5H11.5M8,5V3M11.5,5H14M11.5,5C11.004,7.957 9.853,10.636 8.166,12.884M10,14C9.387,13.725 8.763,13.342 8.166,12.884M8.166,12.884C6.813,11.848 5.603,10.427 5,9M8.166,12.884C6.561,15.023 4.471,16.772 2,18"
android:strokeColor="#000000" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="2"/>
</vector>

View file

@ -47,7 +47,17 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="@+id/languageselect"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/sort_by"
app:tint="?attr/colorOnBackground"
app:srcCompat="@drawable/ic_round_translate_24" />
</LinearLayout>
<LinearLayout

View file

@ -949,6 +949,29 @@
</com.google.android.material.switchmaterial.SwitchMaterial>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/playerSettingsFastForward"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:checked="true"
android:drawableStart="@drawable/ic_round_fast_forward_24"
android:drawablePadding="16dp"
app:drawableTint="?attr/colorPrimary"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
android:minHeight="64dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/fast_forward"
android:textAlignment="viewStart"
android:textColor="@color/bg_opp"
app:cornerRadius="0dp"
app:showText="false"
app:thumbTint="@color/button_switch_track">
</com.google.android.material.switchmaterial.SwitchMaterial>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/playerSettingsDoubleTap"
android:layout_width="match_parent"

View file

@ -519,7 +519,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:drawableStart="@drawable/ic_round_no_icon"
android:drawableStart="@drawable/ic_round_no_icon_24"
android:drawablePadding="16dp"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
@ -532,6 +532,24 @@
app:showText="false"
app:thumbTint="@color/button_switch_track" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/NSFWExtension"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:drawableStart="@drawable/ic_round_nsfw_24"
android:drawablePadding="16dp"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
android:minHeight="64dp"
android:text="@string/NSFWExtention"
android:textAlignment="viewStart"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:drawableTint="?attr/colorPrimary"
app:showText="false"
app:thumbTint="@color/button_switch_track" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -308,14 +308,13 @@
android:text="@string/popular_anime"
android:textSize="16sp" />
<androidx.appcompat.widget.SwitchCompat
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/animeIncludeList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/include_media_in_list" />
</LinearLayout>
</LinearLayout>

View file

@ -15,7 +15,7 @@
android:layout_marginEnd="3dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_width="245dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
@ -25,37 +25,37 @@
android:id="@+id/extensionNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold"
android:text="Extension Name"
android:textSize="15sp"
android:fontFamily="@font/poppins_semi_bold"/>
android:textSize="15sp" />
<TextView
android:id="@+id/extensionVersionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="1"
android:text="version"
android:textSize="11sp" />
</LinearLayout>
<TextView
<ImageView
android:id="@+id/settingsImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_weight="0"
android:contentDescription="Settings"
android:src="@drawable/ic_round_dots_vertical_24"
app:tint="?attr/colorOnBackground" />
<ImageView
android:id="@+id/closeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="16dp"
android:textStyle="bold"
android:text="Uninstall"
android:textColor="?attr/colorPrimary"
android:textSize="14sp"/>
<ImageView
android:id="@+id/settingsImageView"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/ic_round_settings_24"
app:tint="?attr/colorOnBackground"
android:layout_gravity="center_vertical"
android:layout_weight="0"
android:contentDescription="Settings"/>
android:contentDescription="uninstall"
android:src="@drawable/ic_round_delete_24"
app:tint="?attr/colorOnBackground" />
</LinearLayout>

View file

@ -36,13 +36,13 @@
android:textSize="11sp" />
</LinearLayout>
<TextView
<ImageView
android:id="@+id/closeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="Install"
android:src="@drawable/ic_round_download_24"
android:textColor="?attr/colorPrimary"
android:textSize="14sp"/>
</LinearLayout>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/all"
android:title="All" />
<item
android:id="@+id/multi"
android:title="Multi" />
<item
android:id="@+id/english"
android:title="English" />
<item
android:id="@+id/abcd"
android:title="abcd" />
</menu>

View file

@ -154,7 +154,7 @@
<string name="sequel">Sequel</string>
<string name="anilist_settings">Anilist Settings</string>
<string name="extension_settings">Extension Settings</string>
<string name="extension_settings">Extension</string>
<string name="downloads">Downloads</string>
<string name="settings">Settings</string>
<string name="extensions">Extensions</string>
@ -253,6 +253,7 @@
<string name="pause_video_focus">Pause when not in Focus</string>
<string name="gestures">Volume &amp; Brightness Gestures</string>
<string name="double_tap">Double tap to Seek</string>
<string name="fast_forward">Fast Forward</string>
<string name="double_tap_info">Turning off will show fast forward &amp; rewind buttons</string>
<string name="seek_time">Seek Time</string>
<string name="seek_time_info">Amount of time in seconds for fast forward &amp; rewind.</string>
@ -624,6 +625,7 @@
<string name="view_manga">View Manga</string>
<string name="force_legacy_installer">Force Legacy Installer</string>
<string name="extensions_settings">Extensions</string>
<string name="NSFWExtention">NSFW Extensions</string>
<string name="skip_loading_extension_icons">Skip loading extension icons</string>
<string name="use_material_you">Use Material You</string>
<string name="extension_specific_dns">Extension-specific DNS</string>