image lazy load

This commit is contained in:
xiaomlove
2022-08-31 23:08:26 +08:00
parent 8d3d404141
commit 138ee2b86a
7 changed files with 100 additions and 7 deletions

View File

@@ -82,13 +82,16 @@ class UserProfile extends Page
private function buildEnableDisableAction(): Actions\Action private function buildEnableDisableAction(): Actions\Action
{ {
return Actions\Action::make($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_btn') : __('admin.resources.user.actions.enable_modal_btn')) return Actions\Action::make('enable_disable')
->label($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_btn') : __('admin.resources.user.actions.enable_modal_btn'))
->modalHeading($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_title') : __('admin.resources.user.actions.enable_modal_title')) ->modalHeading($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_title') : __('admin.resources.user.actions.enable_modal_title'))
->form([ ->form([
Forms\Components\TextInput::make('reason')->label(__('admin.resources.user.actions.enable_disable_reason'))->placeholder(__('admin.resources.user.actions.enable_disable_reason_placeholder')), Forms\Components\TextInput::make('reason')->label(__('admin.resources.user.actions.enable_disable_reason'))->placeholder(__('admin.resources.user.actions.enable_disable_reason_placeholder')),
Forms\Components\Hidden::make('action')->default($this->record->enabled == 'yes' ? 'disable' : 'enable'), Forms\Components\Hidden::make('action')->default($this->record->enabled == 'yes' ? 'disable' : 'enable'),
Forms\Components\Hidden::make('uid')->default($this->record->id), Forms\Components\Hidden::make('uid')->default($this->record->id),
]) ])
// ->visible(false)
// ->hidden(true)
->action(function ($data) { ->action(function ($data) {
$userRep = $this->getRep(); $userRep = $this->getRep();
try { try {

View File

@@ -216,7 +216,7 @@ class Torrent extends NexusModel
public static function getFieldsForList($appendTableName = false): array|bool public static function getFieldsForList($appendTableName = false): array|bool
{ {
$fields = 'id, sp_state, promotion_time_type, promotion_until, banned, picktype, pos_state, category, source, medium, codec, standard, processing, team, audiocodec, leechers, seeders, name, small_descr, times_completed, size, added, comments,anonymous,owner,url,cache_stamp, pt_gen, hr, approval_status'; $fields = 'id, sp_state, promotion_time_type, promotion_until, banned, picktype, pos_state, category, source, medium, codec, standard, processing, team, audiocodec, leechers, seeders, name, small_descr, times_completed, size, added, comments,anonymous,owner,url,cache_stamp, pt_gen, hr, approval_status, cover';
$fields = preg_split('/[,\s]+/', $fields); $fields = preg_split('/[,\s]+/', $fields);
if ($appendTableName) { if ($appendTableName) {
foreach ($fields as &$value) { foreach ($fields as &$value) {

View File

@@ -1,6 +1,6 @@
<?php <?php
defined('VERSION_NUMBER') || define('VERSION_NUMBER', '1.7.24'); defined('VERSION_NUMBER') || define('VERSION_NUMBER', '1.7.24');
defined('RELEASE_DATE') || define('RELEASE_DATE', '2022-08-30'); defined('RELEASE_DATE') || define('RELEASE_DATE', '2022-08-31');
defined('IN_TRACKER') || define('IN_TRACKER', false); defined('IN_TRACKER') || define('IN_TRACKER', false);
defined('PROJECTNAME') || define("PROJECTNAME","NexusPHP"); defined('PROJECTNAME') || define("PROJECTNAME","NexusPHP");
defined('NEXUSPHPURL') || define("NEXUSPHPURL","https://nexusphp.org"); defined('NEXUSPHPURL') || define("NEXUSPHPURL","https://nexusphp.org");

View File

@@ -3301,6 +3301,7 @@ function torrenttable($rows, $variant = "torrent") {
$torrent = new Nexus\Torrent\Torrent(); $torrent = new Nexus\Torrent\Torrent();
$torrentRep = new \App\Repositories\TorrentRepository(); $torrentRep = new \App\Repositories\TorrentRepository();
$imdb = new \Nexus\Imdb\Imdb();
$torrentIdArr = array_column($rows, 'id'); $torrentIdArr = array_column($rows, 'id');
$torrentSeedingLeechingStatus = $torrent->listLeechingSeedingStatus($CURUSER['id'], $torrentIdArr); $torrentSeedingLeechingStatus = $torrent->listLeechingSeedingStatus($CURUSER['id'], $torrentIdArr);
$tagRep = new \App\Repositories\TagRepository(); $tagRep = new \App\Repositories\TagRepository();
@@ -3487,7 +3488,20 @@ foreach ($rows as $row)
$sp_torrent = get_torrent_promotion_append($row['sp_state'],"",true,$row["added"], $row['promotion_time_type'], $row['promotion_until'], $row['__ignore_global_sp_state'] ?? false); $sp_torrent = get_torrent_promotion_append($row['sp_state'],"",true,$row["added"], $row['promotion_time_type'], $row['promotion_until'], $row['__ignore_global_sp_state'] ?? false);
$hrImg = get_hr_img($row); $hrImg = get_hr_img($row);
print("<td class=\"rowfollow\" width=\"100%\" align=\"left\"><table class=\"torrentname\" width=\"100%\"><tr" . $sphighlight . "><td class=\"embedded\">".$stickyicon."<a $short_torrent_name_alt $mouseovertorrent href=\"details.php?id=".$id."&amp;hit=1\"><b>".htmlspecialchars($dispname)."</b></a>"); //cover
$coverSrc = '';
if ($imdb_id = parse_imdb_id($row["url"])) {
try {
$coverSrc = $imdb->getMovie($imdb_id)->photo(false);
} catch (\Exception $exception) {
do_log("torrent: {$row['id']} get cover from imdb error: ".$exception->getMessage() . "\n[stacktrace]\n" . $exception->getTraceAsString(), 'error');
}
}
if (empty($coverSrc) && !empty($row['cover'])) {
$coverSrc = $row['cover'];
}
$tdCover = sprintf('<td class="embedded" style="text-align: center;width: 46px;height: 46px"><img src="pic/misc/spinner.svg" data-src="%s" class="nexus-lazy-load" style="max-height: 46px;max-width: 46px" /></td>', $coverSrc);
print("<td class=\"rowfollow\" width=\"100%\" align=\"left\" style='padding: 0px'><table class=\"torrentname\" width=\"100%\"><tr" . $sphighlight . ">$tdCover<td class=\"embedded\" style='padding-left: 5px'>".$stickyicon."<a $short_torrent_name_alt $mouseovertorrent href=\"details.php?id=".$id."&amp;hit=1\"><b>".htmlspecialchars($dispname)."</b></a>");
$picked_torrent = ""; $picked_torrent = "";
if ($CURUSER['appendpicked'] != 'no'){ if ($CURUSER['appendpicked'] != 'no'){
if($row['picktype']=="hot") if($row['picktype']=="hot")
@@ -3547,7 +3561,7 @@ foreach ($rows as $row)
$act .= ($act ? "<br />" : "")."<a id=\"bookmark".$counter."\" ".$bookmark." >".get_torrent_bookmark_state($CURUSER['id'], $id)."</a>"; $act .= ($act ? "<br />" : "")."<a id=\"bookmark".$counter."\" ".$bookmark." >".get_torrent_bookmark_state($CURUSER['id'], $id)."</a>";
} }
print("<td width=\"20\" class=\"embedded\" style=\"text-align: right; \" valign=\"middle\">".$act."</td>\n"); print("<td width=\"20\" class=\"embedded\" style=\"text-align: right;padding-right: 5px\" valign=\"middle\">".$act."</td>\n");
print("</tr></table></td>"); print("</tr></table></td>");
if ($wait) if ($wait)

View File

@@ -91,7 +91,7 @@ class Update extends Install
*/ */
foreach (['adminpanel', 'modpanel', 'sysoppanel'] as $table) { foreach (['adminpanel', 'modpanel', 'sysoppanel'] as $table) {
$columnInfo = NexusDB::getMysqlColumnInfo($table, 'id'); $columnInfo = NexusDB::getMysqlColumnInfo($table, 'id');
if ($columnInfo['DATA_TYPE'] == 'tinyint') { if ($columnInfo['DATA_TYPE'] == 'tinyint' || empty($columnInfo['EXTRA']) || $columnInfo['EXTRA'] != 'auto_increment') {
sql_query("alter table $table modify id int(11) unsigned not null AUTO_INCREMENT"); sql_query("alter table $table modify id int(11) unsigned not null AUTO_INCREMENT");
} }
} }

37
public/js/nexus.js vendored
View File

@@ -8,9 +8,21 @@ jQuery(document).ready(function () {
} }
}) })
// preview
function getPosition(e, imgEle) { function getPosition(e, imgEle) {
let imgWidth = imgEle.prop('naturalWidth') let imgWidth = imgEle.prop('naturalWidth')
let imgHeight = imgEle.prop("naturalHeight") let imgHeight = imgEle.prop("naturalHeight")
console.log(`imgWidth: ${imgWidth}, imgHeight: ${imgHeight}`)
let ratio = imgWidth / imgHeight;
if (imgWidth > window.innerWidth) {
imgWidth = window.innerWidth;
imgHeight = imgWidth / ratio;
}
if (imgHeight > window.innerHeight) {
imgHeight = window.innerHeight;
imgWidth = imgHeight * ratio;
}
let width = imgWidth, height= imgHeight;
let left = e.pageX + 10; let left = e.pageX + 10;
if (left + imgWidth > window.innerWidth) { if (left + imgWidth > window.innerWidth) {
left = e.pageX - 10 - imgWidth left = e.pageX - 10 - imgWidth
@@ -19,7 +31,9 @@ jQuery(document).ready(function () {
if (top + imgHeight > window.innerHeight) { if (top + imgHeight > window.innerHeight) {
top = e.pageY - imgHeight / 2 top = e.pageY - imgHeight / 2
} }
return {left, top} let result = {left, top, width, height}
console.log(result)
return result
} }
var previewEle = jQuery('#nexus-preview') var previewEle = jQuery('#nexus-preview')
var imgEle, selector = '.preview' var imgEle, selector = '.preview'
@@ -37,4 +51,25 @@ jQuery(document).ready(function () {
previewEle.css(position) previewEle.css(position)
}) })
// lazy load
if ("IntersectionObserver" in window) {
const imgList = [...document.querySelectorAll('.nexus-lazy-load')]
var io = new IntersectionObserver((entries) =>{
entries.forEach(item => {
// isIntersecting是一个Boolean值判断目标元素当前是否可见
if (item.isIntersecting) {
item.target.src = item.target.dataset.src
item.target.classList.add('preview')
// 图片加载后即停止监听该元素
io.unobserve(item.target)
}
})
}, {
root: document.querySelector('body')
})
// observe遍历监听所有img节点
imgList.forEach(img => io.observe(img))
}
}) })

View File

@@ -0,0 +1,41 @@
<svg class="lds-spinner" width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" style="background: none;"><g transform="rotate(0 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(36 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(72 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.7s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(108 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(144 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(180 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(216 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.3s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(252 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.2s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(288 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.1s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(324 50 50)">
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#b8da0b">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
</rect>
</g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB