mirror of
https://github.com/openvk/openvk
synced 2025-04-23 00:23:01 +03:00
Implement audiostatuses
Добавлены аудиостатусы (у пользователей), блок с друзьями, слушающих музыку на странице аудиозаписей, объект status_audio в users.get, улучшены настройки приватности и ещё что-то
This commit is contained in:
parent
a4583c6b22
commit
ef26b1044a
19 changed files with 298 additions and 48 deletions
|
@ -566,6 +566,14 @@ final class Audio extends VKAPIRequestHandler
|
|||
|
||||
$owner_id = $owner_id == 0 ? $this->getUser()->getId() : $owner_id;
|
||||
$playlists = [];
|
||||
|
||||
if($owner_id > 0 && $owner_id != $this->getUser()->getId()) {
|
||||
$user = (new \openvk\Web\Models\Repositories\Users)->get($owner_id);
|
||||
|
||||
if(!$user->getPrivacyPermission("audios.read", $this->getUser()))
|
||||
$this->fail(50, "Access to playlists denied");
|
||||
}
|
||||
|
||||
foreach((new Audios)->getPlaylistsByEntityId($owner_id, $offset, $count) as $playlist) {
|
||||
if(!$playlist->canBeViewedBy($this->getUser())) {
|
||||
if($drop_private == 1)
|
||||
|
|
|
@ -8,13 +8,23 @@ final class Status extends VKAPIRequestHandler
|
|||
function get(int $user_id = 0, int $group_id = 0)
|
||||
{
|
||||
$this->requireUser();
|
||||
if($user_id == 0 && $group_id == 0) {
|
||||
return $this->getUser()->getStatus();
|
||||
} else {
|
||||
if($group_id > 0)
|
||||
$this->fail(501, "Group statuses are not implemented");
|
||||
else
|
||||
return (new UsersRepo)->get($user_id)->getStatus();
|
||||
|
||||
if($user_id == 0 && $group_id == 0)
|
||||
$user_id = $this->getUser()->getId();
|
||||
|
||||
if($group_id > 0)
|
||||
$this->fail(501, "Group statuses are not implemented");
|
||||
else {
|
||||
$user = (new UsersRepo)->get($user_id);
|
||||
$audioStatus = $user->getCurrentAudioStatus();
|
||||
if($audioStatus) {
|
||||
return [
|
||||
"status" => $user->getStatus(),
|
||||
"audio" => $audioStatus->toVkApiStruct(),
|
||||
];
|
||||
}
|
||||
|
||||
return $user->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,12 @@ final class Users extends VKAPIRequestHandler
|
|||
case "status":
|
||||
if($usr->getStatus() != NULL)
|
||||
$response[$i]->status = $usr->getStatus();
|
||||
|
||||
$audioStatus = $usr->getCurrentAudioStatus();
|
||||
|
||||
if($audioStatus)
|
||||
$response[$i]->status_audio = $audioStatus->toVkApiStruct();
|
||||
|
||||
break;
|
||||
case "screen_name":
|
||||
if($usr->getShortCode() != NULL)
|
||||
|
|
|
@ -313,8 +313,8 @@ class Audio extends Media
|
|||
$lastListen = $listensTable->where([
|
||||
"entity" => $entityId,
|
||||
"audio" => $this->getId(),
|
||||
])->fetch();
|
||||
|
||||
])->order("index DESC")->fetch();
|
||||
|
||||
if(!$lastListen || (time() - $lastListen->time >= $this->getLength())) {
|
||||
$listensTable->insert([
|
||||
"entity" => $entityId,
|
||||
|
@ -331,6 +331,9 @@ class Audio extends Media
|
|||
$playlist->incrementListens();
|
||||
$playlist->save();
|
||||
}
|
||||
|
||||
$entity->setLast_played_track($this->getId());
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -421,4 +421,5 @@ class Club extends RowModel
|
|||
|
||||
use Traits\TBackDrops;
|
||||
use Traits\TSubscribable;
|
||||
use Traits\TAudioStatuses;
|
||||
}
|
||||
|
|
37
Web/Models/Entities/Traits/TAudioStatuses.php
Normal file
37
Web/Models/Entities/Traits/TAudioStatuses.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Entities\Traits;
|
||||
use openvk\Web\Models\Repositories\Audios;
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
|
||||
trait TAudioStatuses
|
||||
{
|
||||
function isBroadcastEnabled(): bool
|
||||
{
|
||||
return (bool) $this->getRecord()->audio_broadcast_enabled;
|
||||
}
|
||||
|
||||
function getCurrentAudioStatus()
|
||||
{
|
||||
if(!$this->isBroadcastEnabled()) return NULL;
|
||||
|
||||
$audioId = $this->getRecord()->last_played_track;
|
||||
|
||||
if(!$audioId) return NULL;
|
||||
$audio = (new Audios)->get($audioId);
|
||||
|
||||
if(!$audio || $audio->isDeleted())
|
||||
return NULL;
|
||||
|
||||
$listensTable = DatabaseConnection::i()->getContext()->table("audio_listens");
|
||||
$lastListen = $listensTable->where([
|
||||
"entity" => $this->getRealId(),
|
||||
"audio" => $audio->getId(),
|
||||
"time >" => (time() - $audio->getLength()) - 10,
|
||||
])->fetch();
|
||||
|
||||
if($lastListen)
|
||||
return $audio;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
|
@ -1249,7 +1249,32 @@ class User extends RowModel
|
|||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
function getFriendsAudios()
|
||||
{
|
||||
$friendsCount = $this->getFriendsCount();
|
||||
$friends = $this->getFriends(max(rand(1, (int)ceil($friendsCount / 6)), 1), 6);
|
||||
|
||||
$shuffleSeed = openssl_random_pseudo_bytes(6);
|
||||
$shuffleSeed = hexdec(bin2hex($shuffleSeed));
|
||||
|
||||
$friends = knuth_shuffle($friends, $shuffleSeed);
|
||||
$returnArr = [];
|
||||
|
||||
foreach($friends as $friend) {
|
||||
$returnArr[] = [
|
||||
"id" => $friend->getRealId(),
|
||||
"name" => $friend->getCanonicalName(),
|
||||
"avatar" => $friend->getAvatarURL("miniscule"),
|
||||
"tracksCount" => (new \openvk\Web\Models\Repositories\Audios)->getUserCollectionSize($friend),
|
||||
"nowListening" => $friend->getCurrentAudioStatus(),
|
||||
];
|
||||
}
|
||||
|
||||
return $returnArr;
|
||||
}
|
||||
|
||||
use Traits\TBackDrops;
|
||||
use Traits\TSubscribable;
|
||||
use Traits\TAudioStatuses;
|
||||
}
|
||||
|
|
|
@ -109,6 +109,9 @@ final class AudioPresenter extends OpenVKPresenter
|
|||
|
||||
$this->template->mode = $mode;
|
||||
$this->template->page = $page;
|
||||
|
||||
if(in_array($mode, ["list", "new", "popular"]))
|
||||
$this->template->friendsAudios = $this->user->identity->getFriendsAudios();
|
||||
}
|
||||
|
||||
function renderEmbed(int $owner, int $id): void
|
||||
|
|
|
@ -47,7 +47,8 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->template->notesCount = (new Notes)->getUserNotesCount($user);
|
||||
$this->template->audios = (new Audios)->getRandomThreeAudiosByEntityId($user->getId());
|
||||
$this->template->audiosCount = (new Audios)->getUserCollectionSize($user);
|
||||
|
||||
$this->template->audioStatus = $user->getCurrentAudioStatus();
|
||||
|
||||
$this->template->user = $user;
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +172,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
|
||||
if ($this->postParam("gender") <= 1 && $this->postParam("gender") >= 0)
|
||||
$user->setSex($this->postParam("gender"));
|
||||
$user->setAudio_broadcast_enabled($this->checkbox("broadcast_music"));
|
||||
|
||||
if(!empty($this->postParam("phone")) && $this->postParam("phone") !== $user->getPhone()) {
|
||||
if(!OPENVK_ROOT_CONF["openvk"]["credentials"]["smsc"]["enable"])
|
||||
|
@ -243,6 +245,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
}
|
||||
|
||||
$user->setStatus(empty($this->postParam("status")) ? NULL : $this->postParam("status"));
|
||||
$user->setAudio_broadcast_enabled($this->postParam("broadcast") == 1);
|
||||
$user->save();
|
||||
|
||||
$this->returnJson([
|
||||
|
|
|
@ -20,5 +20,20 @@
|
|||
<a n:attr="id => $mode === 'playlists' && $ownerId != $thisUser->getId() ? 'used' : 'ki'" href="/playlists{$ownerId}" n:if="isset($ownerId) && !$isMy">{if $ownerId > 0}{_playlists_user}{else}{_playlists_club}{/if}</a>
|
||||
<a href="/audios/newPlaylist{if $isMyClub}?gid={abs($ownerId)}{/if}" n:if="isset($thisUser) && $isMyClub">{_new_playlist}</a>
|
||||
{/if}
|
||||
|
||||
{if $friendsAudios}
|
||||
<div class="friendsAudiosList">
|
||||
<a href="/audios{$fr['id']}" style="width: 94%;padding-left: 10px;" n:foreach="$friendsAudios as $fr">
|
||||
<div class="elem">
|
||||
<img src="{$fr['avatar']}" />
|
||||
|
||||
<div class="additionalInfo">
|
||||
<span class="name">{$fr["name"]}</span>
|
||||
<span class="desc">{$fr["nowListening"] ? $fr["nowListening"]->getName() : tr("audios_count", $fr["tracksCount"])}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
|
@ -160,6 +160,13 @@
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
</td>
|
||||
<td>
|
||||
<label><input type="checkbox" name="broadcast_music" n:attr="checked => $user->isBroadcastEnabled()">{_broadcast_audio}</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
|
|
|
@ -390,9 +390,10 @@
|
|||
</td>
|
||||
<td>
|
||||
<select name="audios.read" style="width: 164px;">
|
||||
<option value="2" {if $user->getPrivacySetting('audios.read') == 2}selected{/if}>{_privacy_value_anybody}</option>
|
||||
<option value="1" {if $user->getPrivacySetting('audios.read') == 1}selected{/if}>{_privacy_value_friends}</option>
|
||||
<option value="0" {if $user->getPrivacySetting('audios.read') == 0}selected{/if}>{_privacy_value_nobody}</option>
|
||||
<option value="3" {if $user->getPrivacySetting('audios.read') == 3}selected{/if}>{_privacy_value_anybody_dative}</option>
|
||||
<option value="2" {if $user->getPrivacySetting('audios.read') == 2}selected{/if}>{_privacy_value_users}</option>
|
||||
<option value="1" {if $user->getPrivacySetting('audios.read') == 1}selected{/if}>{_privacy_value_friends_dative}</option>
|
||||
<option value="0" {if $user->getPrivacySetting('audios.read') == 0}selected{/if}>{_privacy_value_only_me_dative}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -417,6 +417,10 @@
|
|||
<form name="status_popup_form" onsubmit="changeStatus(); return false;">
|
||||
<div style="margin-bottom: 10px;">
|
||||
<input type="text" name="status" size="50" value="{$user->getStatus()}" />
|
||||
<label style="width: 316px;display: block;">
|
||||
<input type="checkbox" name="broadcast" n:attr="checked => $user->isBroadcastEnabled()" />
|
||||
{_broadcast_audio}
|
||||
</label>
|
||||
</div>
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<button type="submit" name="submit" class="button" style="height: 22px;">{_send}</button>
|
||||
|
@ -425,11 +429,20 @@
|
|||
<div class="accountInfo clearFix">
|
||||
<div class="profileName">
|
||||
<h2>{$user->getFullName()}</h2>
|
||||
{if !is_null($user->getStatus())}
|
||||
<div n:class="page_status, $thatIsThisUser ? page_status_edit_button" n:attr="id => $thatIsThisUser ? page_status_text : NULL">{$user->getStatus()}</div>
|
||||
{elseif $thatIsThisUser}
|
||||
<div class="page_status">
|
||||
<div n:class="edit_link, $thatIsThisUser ? page_status_edit_button" id="page_status_text">[ {_change_status} ]</div>
|
||||
|
||||
{if !$audioStatus}
|
||||
{if !is_null($user->getStatus())}
|
||||
<div n:class="page_status, $thatIsThisUser ? page_status_edit_button" n:attr="id => $thatIsThisUser ? page_status_text : NULL">{$user->getStatus()}</div>
|
||||
{elseif $thatIsThisUser}
|
||||
<div class="page_status">
|
||||
<div n:class="edit_link, $thatIsThisUser ? page_status_edit_button" id="page_status_text">[ {_change_status} ]</div>
|
||||
</div>
|
||||
{/if}
|
||||
{else}
|
||||
<div class="page_status" style="display: flex;">
|
||||
<div n:class="audioStatus, $thatIsThisUser ? page_status_edit_button" id="page_status_text">
|
||||
{$audioStatus->getName()}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -594,7 +607,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div n:if="$audiosCount > 0">
|
||||
<div n:if="$audiosCount > 0 && $user->getPrivacyPermission('audios.read', $thisUser ?? NULL)">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$audiosCount});">
|
||||
{_audios}
|
||||
</div>
|
||||
|
@ -758,12 +771,14 @@
|
|||
|
||||
async function changeStatus() {
|
||||
const status = document.status_popup_form.status.value;
|
||||
const broadcast = document.status_popup_form.broadcast.checked;
|
||||
|
||||
document.status_popup_form.submit.innerHTML = "<div class=\"button-loading\"></div>";
|
||||
document.status_popup_form.submit.disabled = true;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("status", status);
|
||||
formData.append("broadcast", Number(broadcast));
|
||||
formData.append("hash", document.status_popup_form.hash.value);
|
||||
const response = await ky.post("/edit?act=status", {body: formData});
|
||||
|
||||
|
|
|
@ -566,4 +566,86 @@
|
|||
z-index: 199;
|
||||
width: 156px;
|
||||
margin-top: -65px !important;
|
||||
}
|
||||
|
||||
.audiosSearchBox input[type='search'] {
|
||||
height: 25px;
|
||||
width: 77%;
|
||||
padding-left: 21px;
|
||||
padding-top: 4px;
|
||||
background: rgb(255, 255, 255) url("/assets/packages/static/openvk/img/search_icon.png") 5px 6px no-repeat;
|
||||
}
|
||||
|
||||
.audiosSearchBox {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 7px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.audiosSearchBox select {
|
||||
width: 30%;
|
||||
padding-left: 7px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
.audioStatus {
|
||||
color: #2B587A;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.audioStatus::before {
|
||||
background-image: url('/assets/packages/static/openvk/img/audios_controls.png');
|
||||
background-repeat: no-repeat;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
background-position: -66px -51px;
|
||||
margin-top: 1px;
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
content: "";
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.friendsAudiosList {
|
||||
margin-left: -7px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem {
|
||||
display: flex;
|
||||
padding: 1px 1px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem img {
|
||||
width: 30px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem .additionalInfo {
|
||||
margin-left: 7px;
|
||||
padding-top: 1px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem .additionalInfo .name {
|
||||
color: #2B587A;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem .additionalInfo .desc {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: #878A8F;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.friendsAudiosList .elem:hover {
|
||||
background: #E8EBF0;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -96,8 +96,9 @@ class bigPlayer {
|
|||
|
||||
this.nodes["thisPlayer"] = document.querySelector(".bigPlayer")
|
||||
this.nodes["thisPlayer"].classList.add("lagged")
|
||||
this.nodes["audioPlayer"] = document.createElement("audio")
|
||||
|
||||
this.player = () => { return this.nodes["thisPlayer"].querySelector("audio.audio") }
|
||||
this.player = () => { return this.nodes["audioPlayer"] }
|
||||
this.nodes["playButtons"] = this.nodes["thisPlayer"].querySelector(".playButtons")
|
||||
this.nodes["dashPlayer"] = dashjs.MediaPlayer().create()
|
||||
|
||||
|
@ -365,34 +366,62 @@ class bigPlayer {
|
|||
|
||||
u(this.player()).on("ended", (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
let playlist = this.context.context_type == "playlist_context" ? this.context.context_id : null
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/audio${this.tracks["currentTrack"].id}/listen`,
|
||||
data: {
|
||||
hash: u("meta[name=csrf]").attr("value"),
|
||||
playlist: playlist
|
||||
},
|
||||
success: (response) => {
|
||||
if(response.success) {
|
||||
console.info("Listen is counted.")
|
||||
|
||||
if(response.new_playlists_listens)
|
||||
document.querySelector("#listensCount").innerHTML = tr("listens_count", response.new_playlists_listens)
|
||||
} else
|
||||
console.info("Listen is not counted.")
|
||||
}
|
||||
})
|
||||
|
||||
// в начало очереди
|
||||
if(!this.tracks.nextTrack) {
|
||||
this.setTrack(this.tracks.tracks[0].id)
|
||||
if(!this.context["playedPages"].includes("1")) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/audios/context",
|
||||
data: {
|
||||
context: this["context"].context_type,
|
||||
context_entity: this["context"].context_id,
|
||||
hash: u("meta[name=csrf]").attr("value"),
|
||||
page: 1
|
||||
},
|
||||
success: (response_2) => {
|
||||
this.tracks["tracks"] = response_2["items"].concat(this.tracks["tracks"])
|
||||
this.context["playedPages"].push(String(1))
|
||||
|
||||
this.setTrack(this.tracks["tracks"][0].id)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.setTrack(this.tracks.tracks[0].id)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.showNextTrack()
|
||||
})
|
||||
|
||||
u(this.player()).on("loadstart", (e) => {
|
||||
let playlist = this.context.context_type == "playlist_context" ? this.context.context_id : null
|
||||
|
||||
let tempThisId = this.tracks.currentTrack.id
|
||||
setTimeout(() => {
|
||||
if(tempThisId != this.tracks.currentTrack.id) return
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/audio${this.tracks["currentTrack"].id}/listen`,
|
||||
data: {
|
||||
hash: u("meta[name=csrf]").attr("value"),
|
||||
playlist: playlist
|
||||
},
|
||||
success: (response) => {
|
||||
if(response.success) {
|
||||
console.info("Listen is counted.")
|
||||
|
||||
if(response.new_playlists_listens)
|
||||
document.querySelector("#listensCount").innerHTML = tr("listens_count", response.new_playlists_listens)
|
||||
} else
|
||||
console.info("Listen is not counted.")
|
||||
}
|
||||
})
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
if(localStorage.volume != null && localStorage.volume < 1 && localStorage.volume > 0)
|
||||
this.player().volume = localStorage.volume
|
||||
|
@ -537,7 +566,7 @@ class bigPlayer {
|
|||
else
|
||||
this.tracks["tracks"] = this.tracks["tracks"].concat(newArr["items"])
|
||||
|
||||
this.context["playedPages"].push(Number(newArr["page"]))
|
||||
this.context["playedPages"].push(String(newArr["page"]))
|
||||
|
||||
if(lesser)
|
||||
this.tracks["previousTrack"] = this.tracks["tracks"].at(this.tracks["tracks"].indexOf(obj) - 1).id
|
||||
|
@ -1310,7 +1339,7 @@ $(document).on("click", ".audiosContainer .paginator a", (e) => {
|
|||
},
|
||||
success: (response_2) => {
|
||||
window.player.tracks["tracks"] = window.player.tracks["tracks"].concat(response_2["items"])
|
||||
window.player.context["playedPages"].push(page)
|
||||
window.player.context["playedPages"].push(String(page))
|
||||
console.info("Page is switched")
|
||||
}
|
||||
})
|
||||
|
|
|
@ -6,7 +6,7 @@ if(document.querySelector("#editPlaylistForm")) {
|
|||
context_id = document.querySelector("#editPlaylistForm").dataset.id
|
||||
}
|
||||
|
||||
if(document.querySelector(".showMoreAudiosPlaylist").dataset.club != null) {
|
||||
if(document.querySelector(".showMoreAudiosPlaylist") && document.querySelector(".showMoreAudiosPlaylist").dataset.club != null) {
|
||||
context_type = "entity_audios"
|
||||
context_id = Number(document.querySelector(".showMoreAudiosPlaylist").dataset.club) * -1
|
||||
}
|
||||
|
|
|
@ -91,4 +91,5 @@ CREATE TABLE IF NOT EXISTS `playlist_relations` (
|
|||
KEY `audio` (`media`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
|
||||
|
||||
ALTER TABLE `groups` ADD `everyone_can_upload_audios` TINYINT(1) NOT NULL DEFAULT '0' AFTER `backdrop_2`;
|
||||
ALTER TABLE `groups` ADD `everyone_can_upload_audios` TINYINT(1) NOT NULL DEFAULT '0' AFTER `backdrop_2`;
|
||||
ALTER TABLE `profiles` ADD `last_played_track` BIGINT(20) UNSIGNED NULL DEFAULT NULL AFTER `client_name`, ADD `audio_broadcast_enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `last_played_track`;
|
|
@ -568,7 +568,7 @@
|
|||
"privacy_setting_add_to_friends" = "Who can add me to friends";
|
||||
"privacy_setting_write_wall" = "Who can publish post on my wall";
|
||||
"privacy_setting_write_messages" = "Who can write messages to me";
|
||||
"privacy_setting_view_audio" = "Who can view my audios";
|
||||
"privacy_setting_view_audio" = "Who can see my audios";
|
||||
"privacy_value_anybody" = "Anybody";
|
||||
"privacy_value_anybody_dative" = "Anybody";
|
||||
"privacy_value_users" = "OpenVK users";
|
||||
|
@ -830,6 +830,8 @@
|
|||
"no_access_clubs" = "There are no groups where you are an administrator.";
|
||||
"audio_successfully_uploaded" = "Audio has been successfully uploaded and is currently being processed.";
|
||||
|
||||
"broadcast_audio" = "Broadcast audio to status";
|
||||
|
||||
/* Notifications */
|
||||
|
||||
"feedback" = "Feedback";
|
||||
|
|
|
@ -541,7 +541,7 @@
|
|||
"privacy_setting_add_to_friends" = "Кто может называть меня другом";
|
||||
"privacy_setting_write_wall" = "Кто может писать у меня на стене";
|
||||
"privacy_setting_write_messages" = "Кто может писать мне сообщения";
|
||||
"privacy_setting_view_audio" = "Кто может видеть мои аудиозаписи";
|
||||
"privacy_setting_view_audio" = "Кому видно мои аудиозаписи";
|
||||
"privacy_value_anybody" = "Все желающие";
|
||||
"privacy_value_anybody_dative" = "Всем желающим";
|
||||
"privacy_value_users" = "Пользователям OpenVK";
|
||||
|
@ -785,6 +785,8 @@
|
|||
"no_access_clubs" = "Нет групп, где вы являетесь администратором.";
|
||||
"audio_successfully_uploaded" = "Аудио успешно загружено и на данный момент обрабатывается.";
|
||||
|
||||
"broadcast_audio" = "Транслировать аудио в статус";
|
||||
|
||||
/* Notifications */
|
||||
|
||||
"feedback" = "Ответы";
|
||||
|
|
Loading…
Reference in a new issue