some changes

This commit is contained in:
themohooks 2025-02-11 17:04:31 +03:00
parent a193a702d7
commit 6c2e8b46a5
11 changed files with 373 additions and 34 deletions

View file

@ -12,6 +12,7 @@ class SetVisibility
{
public function __construct()
{
$priority = 0;
$photo = new Photo($_GET['id']);
$data = json_decode($photo->i('content'), true);
@ -21,12 +22,17 @@ class SetVisibility
if ($_POST['comment'] != null) {
$data['declineComment'] = $_POST['comment'];
}
$data['declineReason'] = $_GET['decline_reason'];
if ($_GET['mod'] != 1) {
$data['declineReason'] = $_GET['reason'];
} else {
$priority = $_GET['reason'];
}
$updatedJsonString = json_encode($data);
DB::query('UPDATE photos SET moderated=:mod, timeupload=:time, content=:c WHERE id=:id', array(':id'=>$_GET['id'], ':mod'=>$_GET['mod'], ':time'=>time(), ':c'=>$updatedJsonString));
DB::query('UPDATE photos SET moderated=:mod, timeupload=:time, priority=:pr, content=:c WHERE id=:id', array(':id'=>$_GET['id'], ':mod'=>$_GET['mod'], ':time'=>time(), ':pr'=>$priority, ':c'=>$updatedJsonString));
$uid = DB::query('SELECT user_id FROM photos WHERE id=:id', array(':id'=>$_GET['id']))[0]['user_id'];
if ($_GET['mod'] === 1) {
$followers = DB::query('SELECT * FROM followers WHERE user_id=:uid', array(':uid'=>$uid));

View file

@ -13,7 +13,7 @@ class LoadRecent
$response = [];
if ($_POST['serverhost'] != 'transphoto.org') {
$photos = DB::query('SELECT * FROM photos WHERE moderated=1 ORDER BY id DESC LIMIT 30');
$photos = DB::query('SELECT * FROM photos WHERE moderated=1 AND id<:id ORDER BY id DESC LIMIT 30', array(':id'=>$_GET['lastpid']));
foreach ($photos as $p) {
@ -23,7 +23,7 @@ class LoadRecent
$date = Date::zmdate($p['posted_at']);
}
$user = DB::query('SELECT * FROM users WHERE id=:id', array(':id' => $p['user_id']))[0];
$comments = DB::query('SELECT COUNT(*) FROM photos_comments WHERE photo_id=:pid', array(':pid'=>$p['id']))[0]['COUNT(*)'];
$response[] = [
'id' => $p['id'],
'place' => htmlspecialchars($p['place']),
@ -31,7 +31,8 @@ class LoadRecent
'user_name' => $user['username'],
'user_id' => $p['user_id'],
'photourl' => $p['photourl'],
'photourl_small' => 'https://' . $_SERVER['SERVER_NAME'] . '/api/photo/compress?url=' . $p['photourl']
'photourl_small' => 'https://' . $_SERVER['SERVER_NAME'] . '/api/photo/compress?url=' . $p['photourl'],
'ccnt' => $comments
];
}
} else {

View file

@ -0,0 +1,52 @@
<?php
namespace App\Services;
class KeyTranslation
{
public static function key($key)
{
switch ($key) {
case 'title':
return 'Название сервера';
break;
case 'adminemail':
return 'Почта Администратора';
break;
case 'showtitle':
return 'Отображать название в заголовке';
break;
case 'logo':
return 'Расположение логотипа';
break;
case 'description':
return 'Описание сервера';
break;
case 'keywords':
return 'Ключевые слова (для SEO)';
break;
case 'maintenance':
return 'Режим технических работ';
break;
case 'debug':
return 'Дебаг';
break;
case 'access':
return 'Доступ к сайту';
break;
case 'type':
return 'Тип';
break;
case 'countries':
return 'Страны';
break;
case 'cloudflare-caching':
return 'Кэширование Cloudflare (и прочих CDN)';
break;
default:
return $key;
break;
}
}
}

115
static/css/mobile.css Normal file
View file

@ -0,0 +1,115 @@
body, td, p, li, input, select, optgroup, option, button { font-size:14px; }
#title { font-family:var(--narrow-font); font-size:32px; padding:5px 7px; position:relative; z-index:2001; }
#title img { margin:0 8px 0 -2px; }
#title2 { padding-right:5px; }
.main, .adframe { padding:0 5px 10px; }
.footer { padding:10px 5px; }
.p20, .p20i { padding-left:15px; padding-right:15px; }
h1 { font-size:24px; }
h2 { font-size:20px; }
h3 { font-size:17px; }
h4 { font-size:17px; margin-bottom:5px; }
.f, .fv3, .pb-photo, .temp, .hpshade { width:125px; }
.fv2, .fv1, .fv, .fv > .f { width:115px; }
.pb-photo { padding:5px; }
.mm-mobile-btn { display:flex; justify-content:center; align-items:center; position:absolute; top:0; right:0; z-index:2002; box-sizing:border-box; width:56px; height:54px; background-color:rgba(0,0,0,0.2); color:#fff; font-size:28px; }
.mm-mobile-btn.active { background-color:rgba(255,255,255,0.2); }
#mm-user-btn { right:57px; }
#mm-bars-btn { right:0; }
.mm { position:absolute; top:54px; width:100%; z-index:2002; border-bottom:solid 1px var(--theme-bg-color); box-shadow:0 8px 8px #0007; }
.mm-bar ul, .mm-bar { list-style-type:none; padding:0; margin:0; }
.mm-bar ul { display:none; background:linear-gradient(rgba(0,0,0,0.2),rgba(0,0,0,0.2)) var(--theme-bg-color); }
.mm ul { margin:0 10px 7px; }
.mm-bar-item li { display:flex; flex-direction:column; align-items:center; justify-content:center; position:relative; box-sizing:border-box; border-top:solid 1px var(--theme-bg-color); font-family:var(--narrow-font); font-size:28px; }
.mm-bar-item li div { box-sizing:border-box; width:100%; background-color:#eee; }
.mm-bar-item li div::before { content:'>'; color:#fff; display:block; position:absolute; top:7px; left:10px; z-index:2003; transform:scaleX(0.8); transition:transform .1s ease-out; }
.mm-level-3 > div::before { top:1px; }
a.mm-item, label.mm-item { color:#fff; }
.mm-item { box-sizing:border-box; width:100%; min-height:50px; padding:5px 0; text-align:center; border:none; }
.mm-level-2 .mm-item { min-height: 42px; font-size: 22px; }
.mm-level-3 .mm-item { min-height: 34px; font-size: 16px; }
.mm-bar-item label:hover { border:none; }
.mm-bar-item input[type="checkbox"] { display:none; }
.mm-bar-item input[type="checkbox"]:checked + div > ul { display:flex; flex-direction:column; }
.mm-bar-item input[type="checkbox"]:checked + div::before { transform:scaleY(0.8) rotate(90deg); }
span.mm-icon, span.mm-right-icon { display:block; position:absolute; z-index:2003; }
.mm-icon { top:7px; left:10px; }
.mm-right-icon { top:5px; right:10px; }
.mm-notify { position: absolute; right: 7px; bottom: 7px; }
.mm-level-1 .mm-notify { top: 10px; font-size: 16px; line-height: 16px; height: 30px; min-width: 30px; }
.mm-level-2 .mm-notify { top: 9px; font-size: 12px; line-height: 12px; height: 24px; min-width: 24px; }
#idx-main { margin-top:5px; }
#idx-column-center { padding:0; }
#idx-column-menu { display:none; position:absolute; top:54px; right:0; padding:5px 10px; background-color:#f7f7f7; width:300px; border-left:solid 1px #ddd; border-bottom:solid 1px #ddd; z-index:2001; }
.idx-donate { margin-right:-10px; }
.idx-donate > a { padding-right:15px; }
.ix-photos-oneline { width:100vw; min-height:70px; margin:0 -5px 7px; overflow-x:auto; }
.ix-photos-oneline:before, .ix-photos-oneline:after { content:''; width:5px; flex-shrink:0; background-color:var(--theme-main-color); }
.ix-photos-oneline > a { flex-grow:0; flex-shrink:0; flex-basis:auto; width:100px; }
.ix-photos-multiline { min-height:210px; margin-bottom:10px; }
.ix-photos-multiline > a { flex-basis:100px; }
.prw-animate, .prw-grid-item { height:70px; }
.prw-animate:hover { animation:none; }
#morerand { top:4px; }
#loadmore { height:auto; padding-bottom:4px; margin-bottom:7px; }
.rtable { box-sizing:border-box; width:100vw; margin:0 -5px; overflow-x:auto; }
.rtable > :first-child { margin:0 5px; }
[type="text"],
[type="password"],
[type="color"],
[type="date"],
[type="datetime"],
[type="datetime-local"],
[type="email"],
[type="number"],
[type="search"],
[type="tel"],
[type="time"],
[type="url"],
[type="month"],
[type="week"],
select,
textarea {
box-shadow:none;
-moz-box-shadow:none;
-webkit-box-shadow:none;
}
.mf-center-block-wide,
.mf-center-block-x-wide {
width:calc(100% + 10px);
margin-left: -5px;
margin-right:-5px;
}
.cmt-showall { display:block; text-align:center; margin-bottom:-5px; }
.mark-btn { margin-bottom:7px; }
.mid-btn { margin:7px 0; }
.mark-btn a, .mid-btn a { width:100%; }

BIN
static/img/cond.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -318,7 +318,7 @@ document.onclick = function(e)
{
e = e || window.event;
E = e.target || e.srcElement;
if (E.id != 'phint' && E.parentNode.id != 'phint' && E != _getID('mform').place) $('#phint').slideUp();
if (E.className != 'searchVehiclesBtn' && E.id != 'vlist_table' && E.className != 'num' && $('#vlist').css('display') == 'block') $('#vlist').hide().html('');
@ -349,6 +349,7 @@ function artClick()
function loadGalleries(cid)
{
if (cid == gal_cid) return;

View file

@ -121,7 +121,7 @@ function searchVehicles()
function AddPhotoToBlock(block, arr, prepend)
{
block[prepend ? 'prepend' : 'append']('<div class="prw-grid-item"><div class="prw-wrapper">' + arr.links + '<div>' + arr.pdate + '</div></div><a href="/photo/' + arr.pid + '/" target="_blank" class="prw-animate" style="background-image:url(\'' + arr.prw + '\')">' + (arr.ccnt != 0 ? '<div class="hdshade"><div class="com-icon">' + arr.ccnt + '</div></div>' : '') + '</a></div>');
block[prepend ? 'prepend' : 'append']('<div class="prw-grid-item"><div class="prw-wrapper">' + arr.place + '<div>' + arr.date + '</div></div><a href="/photo/' + arr.id + '/" target="_blank" class="prw-animate" style="background-image:url(\'' + arr.photourl_small + '\')">' + (arr.ccnt != 0 ? '<div class="hdshade"><div class="com-icon">' + arr.ccnt + '</div></div>' : '') + '</a></div>');
}
@ -166,19 +166,19 @@ function LoadRecentPhotos()
loadmore.prop('disabled', true).addClass('loader-button').val(' ');
$.getJSON('/api.php', { action: 'get-recent-photos', width: width, lastpid: lastpid, hidden: hidden.length }, function(data)
$.getJSON('/api/photo/loadrecent', { lastpid: lastpid }, function(data)
{
if (data)
{
if (lastpid == 0) recent.attr('firstpid', data[0].pid);
if (lastpid == 0) recent.attr('firstpid', data[0].id);
hidden.show();
for (var i = 0; i < data.length; i++) AddPhotoToBlock(recent, data[i]);
recent.attr('lastpid', data[i-1].pid);
recent.attr('lastpid', data[i-1].id);
}
else recent.append('Load error');
loadmore.prop('disabled', false).removeClass('loader-button').val(_text['IX_LOADMORE']);
loadmore.prop('disabled', false).removeClass('loader-button').val('Загрузить ещё');
})
.fail(function(jx) { if (jx.responseText != '') console.log(jx.responseText); });
}

View file

@ -16,6 +16,7 @@
<script src="/static/js/jquery-ui.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/jquery.form.min.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/core.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/index.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/core_lk.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/imageupload.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>
<script src="/static/js/progress.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) { echo '?'.time(); } ?>"></script>

View file

@ -35,7 +35,7 @@ use \App\Models\User;
}
</style>
<td class="main">
<h1><b>Журнал</b></h1>
<h1><b>Фотографии</b></h1>
<script src="/js/diff.js"></script>
<script src="/js/pwrite-compare.js"></script>
<br clear="all"><br>
@ -74,7 +74,7 @@ use \App\Models\User;
<td class="c">
';
if ($p['moderated'] === 0) {
echo '<a href="/api/admin/images/setvisibility?id='.$p['id'].'&mod=1" class="btn btn-primary">Принять</a>
echo '<a data-bs-toggle="modal" data-bs-target="#acceptPhotoModal'.$p['id'].'" href="#" class="btn btn-primary">Принять</a>
<a data-bs-toggle="modal" data-bs-target="#declinePhotoModal'.$p['id'].'" href="#" class="btn btn-danger">Отклонить</a>';
}
echo '
@ -85,6 +85,68 @@ use \App\Models\User;
echo '
</tr>
<div class="modal fade" id="acceptPhotoModal'.$p['id'].'" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel"><b>Принятие фотографии</b></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="form-check">
<input name="accept'.$p['id'].'" value="0" class="form-check-input" type="radio" name="flexRadioDefault" id="acceptReason1" checked>
<label class="form-check-label" for="acceptReason1">
Нормальная публикация
</label>
</div>
<div class="form-check">
<input name="accept'.$p['id'].'" value="1" class="form-check-input" type="radio" name="flexRadioDefault" id="acceptReason3">
<label class="form-check-label" for="acceptReason3">
Условная публикация
</label>
</div>
<div class="form-check">
<input name="accept'.$p['id'].'" value="2" class="form-check-input" type="radio" name="flexRadioDefault" id="acceptReason2">
<label class="form-check-label" for="acceptReason2">
Временная публикация
</label>
</div>
<div class="form-check">
<input name="accept'.$p['id'].'" value="3" class="form-check-input" type="radio" name="flexRadioDefault" id="acceptReason4">
<label class="form-check-label" for="acceptReason4">
Техническая публикация
</label>
</div>
<h6 class="mt-3">Другие действия</h6>
<div class="form-check">
<input name="anotheraccept'.$p['id'].'[]" class="form-check-input" type="checkbox" value="1" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
Отключить комментарии
</label>
</div>
<div class="form-check">
<input name="anotheraccept'.$p['id'].'[]" class="form-check-input" type="checkbox" value="2" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
Отключить рейтинг
</label>
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Дополнительный комментарий</label>
<textarea class="form-control" id="exampleFormControlTextarea1" name="comment" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<a type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</a>'; ?>
<a href="#" onclick="photoAction(<?=$p['id']?>, document.querySelector(`input[name='accept<?=$p['id']?>']:checked`).value, 1); return false;" data-bs-dismiss="modal" class="btn btn-primary">Сохранить</a>
<?php echo '
</div>
</div>
</div>
</div>
<div class="modal fade" id="declinePhotoModal'.$p['id'].'" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
@ -159,7 +221,7 @@ use \App\Models\User;
function photoAction(photo_id, decline_reason, mod) {
$.ajax({
type: "GET",
url: '/api/admin/images/setvisibility?id='+photo_id+'&mod='+mod+'&decline_reason='+decline_reason,
url: '/api/admin/images/setvisibility?id='+photo_id+'&mod='+mod+'&reason='+decline_reason,
data: $(this).serialize(),
success: function(response) {
$('#pht'+photo_id).remove();

View file

@ -0,0 +1,107 @@
<?php
use \App\Services\{KeyTranslation};
use \App\Models\User;
use Symfony\Component\Yaml\Yaml;
$yamlFile = $_SERVER['DOCUMENT_ROOT'].'/ngallery.yaml';
function renderInputs($data, $prefix = '') {
foreach ($data as $key => $value) {
$name = $prefix ? "{$prefix}[{$key}]" : $key;
$key = KeyTranslation::key($key);
if (is_string($value) || is_bool($value)) {
if ($value === true || $value === false) {
$value = $value ? 'true' : 'false';
}
if ($value === 'true' || $value === 'false') {
echo "<div class='mb-2'>
<label>{$key}</label>
<select class='form-control' name='{$name}'>
<option value='true' " . ($value === 'true' ? 'selected' : '') . ">true</option>
<option value='false' " . ($value === 'false' ? 'selected' : '') . ">false</option>
</select>
</div>";
} else {
echo "<div class='mb-2'>
<label>{$key}</label>
<input class='form-control' type='text' name='{$name}' value='" . htmlspecialchars($value, ENT_QUOTES) . "'>
</div>";
}
} elseif (is_numeric($value)) {
echo "<div class='mb-2'>
<label>{$key}</label>
<input class='form-control' type='number' name='{$name}' value='{$value}'>
</div>";
} elseif (is_array($value)) {
echo "<fieldset class='mb-3 p-2 border'><legend>{$key}</legend>";
renderInputs($value, $name);
echo "</fieldset>";
}
}
}
?>
<!DOCTYPE html>
<html lang="ru">
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<link rel="stylesheet" href="/static/css/notie.css<?php if (NGALLERY['root']['cloudflare-caching'] === true) {
echo '?' . time();
} ?>">
<script src="/static/js/notie.js<?php if (NGALLERY['root']['cloudflare-caching'] === true) {
echo '?' . time();
} ?>"></script>
<script>
notie.setOptions({
transitionCurve: 'cubic-bezier(0.2, 0, 0.2, 1)'
});
var Notify = {
noty: function(status, text) {
if (status == 'danger') status = 'error';
return notie.alert({
type: status,
text: text
})
},
}
</script>
<body>
<div class="container">
<?= \App\Controllers\AdminController::loadMenu(); ?>
<?= \App\Controllers\AdminController::loadContent(); ?>
<h1><b>Настройки</b></h1>
<div class="alert alert-warning" role="alert">
Изменяйте только на свой страх и риск.
</div>
<div class="p20w" style="display:block">
<?php
// Вывод формы
echo '<form method="post">';
foreach (NGALLERY as $ng) {
renderInputs($ng);
}
echo '<button type="submit">Сохранить</button>';
echo '</form>';
?>
</div><br>
</div>
</body>
</html>

View file

@ -78,7 +78,11 @@ LIMIT 10;');
<img width="250" src="/api/photo/compress?url=' . $p['photourl'] . '">
<div class="hpshade">
<div class="eye-icon">+' . $pd['view_count'] . '</div>
</div>
</div>';
if ((int)$p['priority'] === 1) {
echo '<div class="temp" style="background-image:url(/static/img/cond.png)"></div>';
}
echo '
</a>';
}
}
@ -125,27 +129,17 @@ LIMIT 10;');
<h4 style="clear:both"><a href="/update">Недавно добавленные фотографии</a></h4>
<div id="recent-photos" class="ix-photos ix-photos-multiline" lastpid="1970527" firstpid="1970550">
<?php
$photos = DB::query('SELECT * FROM photos WHERE moderated=1 ORDER BY id DESC LIMIT 30');
foreach ($photos as $p) {
if ($p['posted_at'] === 943909200 || Date::zmdate($p['posted_at']) === '30 ноября 1999 в 00:00') {
$date = 'дата не указана';
} else {
$date = Date::zmdate($p['posted_at']);
}
$bck = 'background-image:url("/api/photo/compress?url=' . $p['photourl'] . '")';
echo ' <div class="prw-grid-item">
<div class="prw-wrapper"><span style="word-spacing:-1px"><b>' . htmlspecialchars($p['place']) . '</b></span>
<div>' . $date . '</div>
</div>
'; ?>
<a href="/photo/<?= $p['id'] ?>" target="_blank" class="prw-animate" style='background-image:url("/api/photo/compress?url=<?= $p['photourl'] ?>")'></a>
</div>
<?php }
$first_id = $photos[0]['id'];
$last_id = end($photos)['id'];
?>
<div id="recent-photos" class="ix-photos ix-photos-multiline" lastpid="<?=$first_id?>" firstpid="<?=$last_id?>">
</div>
</div>
<div style="text-align:center; margin:10px 0"><input type="button" name="button" id="loadmore" class="" value="Загрузить ещё"></div>