Player update
This commit is contained in:
parent
91b4869934
commit
aefd8df5c6
@ -175,11 +175,11 @@ public class AccountActivity extends CommonActivity {
|
|||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
Account account = response.body();
|
Account account = response.body();
|
||||||
|
|
||||||
String owner = MetaDataHelper.getOwnerString(account.getName(),
|
String owner = MetaDataHelper.getOwnerString(account,
|
||||||
account.getHost(),
|
AccountActivity.this, true
|
||||||
AccountActivity.this
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// set view data
|
// set view data
|
||||||
TextView ownerStringView = findViewById(R.id.account_owner_string);
|
TextView ownerStringView = findViewById(R.id.account_owner_string);
|
||||||
ownerStringView.setText(owner);
|
ownerStringView.setText(owner);
|
||||||
|
@ -94,15 +94,15 @@ public class ChannelAdapter extends RecyclerView.Adapter<ChannelAdapter.AccountV
|
|||||||
holder.videoMeta.setText(
|
holder.videoMeta.setText(
|
||||||
MetaDataHelper.getMetaString(videoList.get(position).getCreatedAt(),
|
MetaDataHelper.getMetaString(videoList.get(position).getCreatedAt(),
|
||||||
videoList.get(position).getViews(),
|
videoList.get(position).getViews(),
|
||||||
context
|
context,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// set owner
|
// set owner
|
||||||
holder.videoOwner.setText(
|
holder.videoOwner.setText(
|
||||||
MetaDataHelper.getOwnerString(videoList.get(position).getAccount().getName(),
|
MetaDataHelper.getOwnerString(videoList.get(position).getAccount(),
|
||||||
videoList.get(position).getAccount().getHost(),
|
context, true
|
||||||
context
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
package net.schueller.peertube.adapter
|
package net.schueller.peertube.adapter
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@ -39,10 +41,14 @@ import net.schueller.peertube.helper.MetaDataHelper.getDuration
|
|||||||
import net.schueller.peertube.helper.MetaDataHelper.getMetaString
|
import net.schueller.peertube.helper.MetaDataHelper.getMetaString
|
||||||
import net.schueller.peertube.helper.MetaDataHelper.getOwnerString
|
import net.schueller.peertube.helper.MetaDataHelper.getOwnerString
|
||||||
import com.mikepenz.iconics.Iconics.Builder
|
import com.mikepenz.iconics.Iconics.Builder
|
||||||
|
import net.schueller.peertube.R
|
||||||
import net.schueller.peertube.R.id
|
import net.schueller.peertube.R.id
|
||||||
import net.schueller.peertube.R.menu
|
import net.schueller.peertube.R.menu
|
||||||
import net.schueller.peertube.databinding.*
|
import net.schueller.peertube.databinding.*
|
||||||
import net.schueller.peertube.fragment.VideoMetaDataFragment
|
import net.schueller.peertube.fragment.VideoMetaDataFragment
|
||||||
|
import net.schueller.peertube.helper.MetaDataHelper.getCreatorAvatar
|
||||||
|
import net.schueller.peertube.helper.MetaDataHelper.getCreatorString
|
||||||
|
import net.schueller.peertube.helper.MetaDataHelper.getTagsString
|
||||||
import net.schueller.peertube.intents.Intents
|
import net.schueller.peertube.intents.Intents
|
||||||
import net.schueller.peertube.model.*
|
import net.schueller.peertube.model.*
|
||||||
import net.schueller.peertube.model.ui.VideoMetaViewItem
|
import net.schueller.peertube.model.ui.VideoMetaViewItem
|
||||||
@ -55,7 +61,7 @@ import okhttp3.ResponseBody
|
|||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import net.schueller.peertube.R
|
import net.schueller.peertube.helper.MetaDataHelper.isChannel
|
||||||
import net.schueller.peertube.network.GetUserService
|
import net.schueller.peertube.network.GetUserService
|
||||||
|
|
||||||
|
|
||||||
@ -190,10 +196,26 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
binding.videoDownloadWrapper.visibility = GONE
|
binding.videoDownloadWrapper.visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
val account = video.account
|
// created at / views
|
||||||
|
binding.videoMeta.text = getMetaString(
|
||||||
|
video.createdAt,
|
||||||
|
video.views,
|
||||||
|
context,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
// owner / creator
|
||||||
|
val displayNameAndHost = getOwnerString(video.account, context)
|
||||||
|
if (isChannel(video)) {
|
||||||
|
binding.videoBy.text = context.resources.getString(string.video_by_line, displayNameAndHost)
|
||||||
|
} else {
|
||||||
|
binding.videoBy.visibility = GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.videoOwner.text = getCreatorString(video, context)
|
||||||
|
|
||||||
// owner / creator Avatar
|
// owner / creator Avatar
|
||||||
val avatar = account.avatar
|
val avatar = getCreatorAvatar(video, context)
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
val baseUrl = APIUrlHelper.getUrl(context)
|
val baseUrl = APIUrlHelper.getUrl(context)
|
||||||
val avatarPath = avatar.path
|
val avatarPath = avatar.path
|
||||||
@ -201,22 +223,25 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
.load(baseUrl + avatarPath)
|
.load(baseUrl + avatarPath)
|
||||||
.into(binding.avatar)
|
.into(binding.avatar)
|
||||||
}
|
}
|
||||||
// created at / views
|
|
||||||
binding.videoMeta.text = getMetaString(
|
|
||||||
video.createdAt,
|
|
||||||
video.views,
|
|
||||||
context!!
|
|
||||||
)
|
|
||||||
|
|
||||||
// owner / creator
|
|
||||||
binding.videoOwner.text = getOwnerString(
|
|
||||||
video.account.name,
|
|
||||||
video.account.host,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
|
|
||||||
// videoOwnerSubscribers
|
// videoOwnerSubscribers
|
||||||
binding.videoOwnerSubscribers.text = video.account.followersCount.toString()
|
binding.videoOwnerSubscribers.text = context.resources.getQuantityString(R.plurals.video_channel_subscribers, video.channel.followersCount, video.channel.followersCount)
|
||||||
|
|
||||||
|
|
||||||
|
// video owner click
|
||||||
|
binding.videoCreatorInfo.setOnClickListener {
|
||||||
|
val intent = Intent(context, AccountActivity::class.java)
|
||||||
|
intent.putExtra(VideoListActivity.EXTRA_ACCOUNTDISPLAYNAME, displayNameAndHost)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// avatar click
|
||||||
|
binding.avatar.setOnClickListener {
|
||||||
|
val intent = Intent(context, AccountActivity::class.java)
|
||||||
|
intent.putExtra(Companion.EXTRA_ACCOUNTDISPLAYNAME, displayNameAndHost)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// get subscription status
|
// get subscription status
|
||||||
@ -231,7 +256,7 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
// {"video.channel.name + "@" + video.channel.host":true}
|
// {"video.channel.name + "@" + video.channel.host":true}
|
||||||
if (response.body()?.get(video.channel.name + "@" + video.channel.host)!!.asBoolean) {
|
if (response.body()?.get(video.channel.name + "@" + video.channel.host)!!.asBoolean) {
|
||||||
binding.videoOwnerSubscribeButton.setText(string.unsubscribe)
|
binding.videoOwnerSubscribeButton.setText(string.unsubscribe)
|
||||||
isSubscribed = true;
|
isSubscribed = true
|
||||||
} else {
|
} else {
|
||||||
binding.videoOwnerSubscribeButton.setText(string.subscribe)
|
binding.videoOwnerSubscribeButton.setText(string.subscribe)
|
||||||
}
|
}
|
||||||
@ -244,6 +269,7 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: update subscriber count
|
||||||
binding.videoOwnerSubscribeButton.setOnClickListener {
|
binding.videoOwnerSubscribeButton.setOnClickListener {
|
||||||
if (Session.getInstance().isLoggedIn) {
|
if (Session.getInstance().isLoggedIn) {
|
||||||
if (!isSubscribed) {
|
if (!isSubscribed) {
|
||||||
@ -265,22 +291,33 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
val payload = video.channel.name + "@" + video.channel.host
|
AlertDialog.Builder(context)
|
||||||
val call = userService.unsubscribe(payload)
|
.setTitle(context.getString(string.video_sub_del_alert_title))
|
||||||
call.enqueue(object : Callback<ResponseBody?> {
|
.setMessage(context.getString(string.video_sub_del_alert_msg))
|
||||||
override fun onResponse(
|
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
|
||||||
call: Call<ResponseBody?>,
|
// Yes
|
||||||
response: Response<ResponseBody?>
|
val payload = video.channel.name + "@" + video.channel.host
|
||||||
) {
|
val call = userService.unsubscribe(payload)
|
||||||
if (response.isSuccessful) {
|
call.enqueue(object : Callback<ResponseBody?> {
|
||||||
binding.videoOwnerSubscribeButton.setText(string.subscribe)
|
override fun onResponse(
|
||||||
isSubscribed = false
|
call: Call<ResponseBody?>,
|
||||||
}
|
response: Response<ResponseBody?>
|
||||||
|
) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
binding.videoOwnerSubscribeButton.setText(string.subscribe)
|
||||||
|
isSubscribed = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
|
.setNegativeButton(android.R.string.cancel) { _: DialogInterface?, _: Int ->
|
||||||
// Do nothing.
|
// No
|
||||||
}
|
}
|
||||||
})
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@ -337,7 +374,7 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
.into(binding.thumb)
|
.into(binding.thumb)
|
||||||
|
|
||||||
// Avatar
|
// Avatar
|
||||||
val avatar: Avatar? = video.account.avatar
|
val avatar = getCreatorAvatar(video, context)
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
val avatarPath = avatar.path
|
val avatarPath = avatar.path
|
||||||
Picasso.get()
|
Picasso.get()
|
||||||
@ -364,12 +401,8 @@ sealed class MultiViewRecyclerViewHolder(binding: ViewBinding) : RecyclerView.Vi
|
|||||||
)
|
)
|
||||||
|
|
||||||
// set owner
|
// set owner
|
||||||
val displayNameAndHost = getOwnerString(
|
val displayNameAndHost = getOwnerString(video.account, context, true)
|
||||||
video.account.name,
|
binding.videoOwner.text = getCreatorString(video, context, true)
|
||||||
video.account.host,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
binding.videoOwner.text = displayNameAndHost
|
|
||||||
|
|
||||||
// video owner click
|
// video owner click
|
||||||
binding.videoOwner.setOnClickListener {
|
binding.videoOwner.setOnClickListener {
|
||||||
|
@ -18,32 +18,92 @@ package net.schueller.peertube.helper
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
|
import net.schueller.peertube.R
|
||||||
import net.schueller.peertube.R.string
|
import net.schueller.peertube.R.string
|
||||||
|
import net.schueller.peertube.model.Account
|
||||||
|
import net.schueller.peertube.model.Avatar
|
||||||
|
import net.schueller.peertube.model.Video
|
||||||
import org.ocpsoft.prettytime.PrettyTime
|
import org.ocpsoft.prettytime.PrettyTime
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
object MetaDataHelper {
|
object MetaDataHelper {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getMetaString(getCreatedAt: Date, viewCount: Int, context: Context): String {
|
fun getMetaString(getCreatedAt: Date, viewCount: Int, context: Context, reversed: Boolean = false): String {
|
||||||
|
|
||||||
// Compatible with SDK 21+
|
// Compatible with SDK 21+
|
||||||
val currentLanguage = Locale.getDefault().displayLanguage
|
val currentLanguage = Locale.getDefault().displayLanguage
|
||||||
val p = PrettyTime(currentLanguage)
|
val p = PrettyTime(currentLanguage)
|
||||||
val relativeTime = p.format(Date(getCreatedAt.time))
|
val relativeTime = p.format(Date(getCreatedAt.time))
|
||||||
return relativeTime +
|
return if (reversed) {
|
||||||
context.resources.getString(string.meta_data_seperator) +
|
viewCount.toString() +
|
||||||
viewCount + context.resources.getString(string.meta_data_views)
|
context.resources.getString(string.meta_data_views) +
|
||||||
|
context.resources.getString(string.meta_data_seperator) +
|
||||||
|
relativeTime
|
||||||
|
} else {
|
||||||
|
relativeTime +
|
||||||
|
context.resources.getString(string.meta_data_seperator) +
|
||||||
|
viewCount + context.resources.getString(string.meta_data_views)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTagsString(video: Video): String {
|
||||||
|
return if (video.tags.isNotEmpty()) {
|
||||||
|
" #" + video.tags.joinToString(" #", "", "", 3, "")
|
||||||
|
} else {
|
||||||
|
" "
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getOwnerString(accountName: String, serverHost: String, context: Context): String {
|
fun getCreatorString(video: Video, context: Context, fqdn: Boolean = false): String {
|
||||||
return accountName +
|
return if (isChannel(video)) {
|
||||||
context.resources.getString(string.meta_data_owner_seperator) +
|
if (!fqdn) {
|
||||||
serverHost
|
video.channel.displayName
|
||||||
|
} else {
|
||||||
|
getConcatFqdnString(video.channel.name, video.channel.host, context)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getOwnerString(video.account, context, fqdn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getOwnerString(account: Account, context: Context, fqdn: Boolean = true): String {
|
||||||
|
return if (!fqdn) {
|
||||||
|
account.name
|
||||||
|
} else {
|
||||||
|
getConcatFqdnString(account.name, account.host, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getConcatFqdnString(user: String, host: String, context: Context): String {
|
||||||
|
return context.resources.getString(string.video_owner_fqdn_line, user, host)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getCreatorAvatar(video: Video, context: Context): Avatar? {
|
||||||
|
return if (isChannel(video)) {
|
||||||
|
if (video.channel.avatar == null) {
|
||||||
|
video.account.avatar
|
||||||
|
} else {
|
||||||
|
video.channel.avatar
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
video.account.avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun isChannel(video: Video): Boolean {
|
||||||
|
// c285b523-d688-43c5-a9ad-f745ff09bbd1
|
||||||
|
return !video.channel.name.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}".toRegex())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getDuration(duration: Long?): String {
|
fun getDuration(duration: Long?): String {
|
||||||
return DateUtils.formatElapsedTime(duration!!)
|
return DateUtils.formatElapsedTime(duration!!)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<!-- Video Title Block -->
|
<!-- Video Title Block -->
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
android:id="@+id/video_title_block"
|
android:id="@+id/video_title_block"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -331,20 +332,20 @@
|
|||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="72dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="72dp"
|
android:layout_height="48dp"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:contentDescription="@string/video_row_account_avatar"
|
android:contentDescription="@string/video_row_account_avatar"
|
||||||
android:paddingStart="12dp"
|
android:paddingStart="6dp"
|
||||||
android:paddingTop="12dp"
|
android:paddingEnd="6dp" />
|
||||||
android:paddingEnd="12dp" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/video_creator_info"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="6dp"
|
||||||
android:layout_toEndOf="@+id/avatar"
|
android:layout_toEndOf="@+id/avatar"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
@ -354,6 +355,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead" />
|
android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/videoBy"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/videoOwnerSubscribers"
|
android:id="@+id/videoOwnerSubscribers"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -367,11 +375,13 @@
|
|||||||
android:id="@+id/videoOwnerSubscribeButton"
|
android:id="@+id/videoOwnerSubscribeButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
android:layout_marginEnd="0dp"
|
android:layout_marginEnd="0dp"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Button" />
|
android:textAppearance="@style/Base.TextAppearance.AppCompat.Button" />
|
||||||
|
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
<string name="video_download_icon" translatable="false">{faw-download}</string>
|
<string name="video_download_icon" translatable="false">{faw-download}</string>
|
||||||
<string name="video_save_icon" translatable="false">{faw-save}</string>
|
<string name="video_save_icon" translatable="false">{faw-save}</string>
|
||||||
|
|
||||||
<string name="meta_data_owner_seperator" translatable="false">\@</string>
|
|
||||||
<string name="meta_data_seperator" translatable="false">\u0020-\u0020</string>
|
<string name="meta_data_seperator" translatable="false">\u0020-\u0020</string>
|
||||||
|
|
||||||
<string name="title_activity_video_play" translatable="false">VideoPlayActivity</string>
|
<string name="title_activity_video_play" translatable="false">VideoPlayActivity</string>
|
||||||
|
@ -376,4 +376,12 @@
|
|||||||
<string name="subscribe">Subscribe</string>
|
<string name="subscribe">Subscribe</string>
|
||||||
<string name="unsubscribe">Unsubscribe</string>
|
<string name="unsubscribe">Unsubscribe</string>
|
||||||
<string name="video_comments_title">Comments</string>
|
<string name="video_comments_title">Comments</string>
|
||||||
|
<plurals name="video_channel_subscribers">
|
||||||
|
<item quantity="one">%1$d subscriber</item>
|
||||||
|
<item quantity="other">%1$d subscribers</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="video_by_line">By %1$s</string>
|
||||||
|
<string name="video_owner_fqdn_line">%1$s@%2$s</string>
|
||||||
|
<string name="video_sub_del_alert_title">Unsubscribe</string>
|
||||||
|
<string name="video_sub_del_alert_msg">Are you sure you would like to unsubscribe?</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user