Upload all files.
commit
b58080c51e
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
$magicWords = [];
|
||||
|
||||
$magicWords['en'] = [
|
||||
'nocreditbox' => [1, '__NOCREDITBOX__'],
|
||||
];
|
||||
|
||||
$magicWords['zh-hans'] = [
|
||||
'nocreditbox' => [1, '__无编辑者框__'],
|
||||
];
|
||||
|
||||
$magicWords['zh-hant'] = [
|
||||
'nocreditbox' => [1, '__無編輯者框__'],
|
||||
];
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "IsekaiContributors",
|
||||
"namemsg": "isekaicontrib-name",
|
||||
"author": "Hyperzlib",
|
||||
"requires": {
|
||||
"MediaWiki": ">= 1.35.0"
|
||||
},
|
||||
"url": "/",
|
||||
"descriptionmsg": "isekaicontrib-desc",
|
||||
"license-name": "MIT",
|
||||
"type": "other",
|
||||
"APIPropModules": {
|
||||
"pagecredit": "Isekai\\Contributors\\Api\\ApiPageCredit"
|
||||
},
|
||||
"Hooks": {
|
||||
"SidebarBeforeOutput": "Isekai\\Contributors\\Hooks::onSidebarBeforeOutput",
|
||||
"SkinTemplateOutputPageBeforeExec": "Isekai\\Contributors\\Hooks::onSkinTemplateOutputPageBeforeExec",
|
||||
"BeforePageDisplay": "Isekai\\Contributors\\Hooks::onBeforePageDisplay",
|
||||
"ResourceLoaderGetConfigVars": "Isekai\\Contributors\\Hooks::onResourceLoaderGetConfigVars",
|
||||
"GetDoubleUnderscoreIDs": "Isekai\\Contributors\\Hooks::onGetDoubleUnderscoreIDs"
|
||||
},
|
||||
"ExtensionMessagesFiles": {
|
||||
"IsekaiContributorsMagic": "IsekaiContributors.i18n.magic.php"
|
||||
},
|
||||
"MessagesDirs": {
|
||||
"IsekaiContributors": [
|
||||
"i18n",
|
||||
"i18n/api"
|
||||
]
|
||||
},
|
||||
"AutoloadNamespaces": {
|
||||
"Isekai\\Contributors\\": "includes/"
|
||||
},
|
||||
"ResourceModules": {
|
||||
"ext.isekai.contrib.styles": {
|
||||
"styles": ["ext.isekai.contributor.panel.less"],
|
||||
"targets": [ "desktop", "mobile" ]
|
||||
},
|
||||
"ext.isekai.contrib.dialog": {
|
||||
"scripts": ["ext.isekai.contributor.dialog.js"],
|
||||
"styles": ["ext.isekai.contributor.dialog.less"],
|
||||
"targets": [ "desktop", "mobile" ],
|
||||
"dependencies": [
|
||||
"oojs-ui-core",
|
||||
"oojs-ui-windows",
|
||||
"oojs-ui-widgets"
|
||||
],
|
||||
"messages": [
|
||||
"isekaicontrib-dialog-title",
|
||||
"isekaicontrib-dialog-cancel",
|
||||
"isekaicontrib-dialog-subtitle-creator",
|
||||
"isekaicontrib-dialog-subtitle-last-editor",
|
||||
"isekaicontrib-dialog-subtitle-contributors"
|
||||
]
|
||||
},
|
||||
"ext.isekai.contrib.images": {
|
||||
"selector": ".isekai-img-{name}",
|
||||
"class": "ResourceLoaderImageModule",
|
||||
"images": {
|
||||
"more-contrib": "more.svg"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ResourceFileModulePaths": {
|
||||
"localBasePath": "modules",
|
||||
"remoteExtPath": "IsekaiContributors"
|
||||
},
|
||||
"config": {
|
||||
"IsekaiContributorAvatar": {
|
||||
"value": "/avatar/%s"
|
||||
}
|
||||
},
|
||||
"manifest_version": 2
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"apihelp-query+pagecredit-description": "获得页面的贡献者列表。",
|
||||
"apihelp-query+pagecredit-summary": "获得页面的贡献者列表。",
|
||||
"apihelp-query+pagecredit-param-limit": "获取的贡献者数量限制"
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"isekaicontrib-name": "异世界百科 编写者信息",
|
||||
"isekaicontrib-desc": "在页面上显示一个所有编写者的信息框",
|
||||
"isekaicontrib-sidebar-contrib": "编写者",
|
||||
"isekaicontrib-viewall": "查看所有编写者",
|
||||
"isekai-contrib": "编写者",
|
||||
"isekaicontrib-dialog-title": "本页面的编写者",
|
||||
"isekaicontrib-dialog-cancel": "关闭",
|
||||
"isekaicontrib-dialog-subtitle-creator": "创建者",
|
||||
"isekaicontrib-dialog-subtitle-last-editor": "最后编写者",
|
||||
"isekaicontrib-dialog-subtitle-contributors": "其他编写者"
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Isekai\Contributors\Api;
|
||||
|
||||
use ApiBase;
|
||||
use ApiQueryBase;
|
||||
use ApiQuery;
|
||||
use Config;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use WANObjectCache;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use Exception;
|
||||
|
||||
use Isekai\Contributors\PageCreditHelper;
|
||||
|
||||
class ApiPageCredit extends ApiQueryBase {
|
||||
private const CACHE_VERSION = 2;
|
||||
|
||||
private const PREFIX = 'pc';
|
||||
|
||||
private $params;
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
/**
|
||||
* @var WANObjectCache
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var PageCreditHelper
|
||||
*/
|
||||
private $helper;
|
||||
|
||||
/**
|
||||
* @param ApiQuery $query API query module object
|
||||
* @param string $moduleName Name of this query module
|
||||
*/
|
||||
public function __construct($query, $moduleName) {
|
||||
parent::__construct($query, $moduleName, self::PREFIX);
|
||||
$this->config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'textextracts' );
|
||||
$this->cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
|
||||
$this->helper = new PageCreditHelper($this->getContext());
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$titles = $this->getPageSet()->getGoodTitles();
|
||||
if (empty($titles)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isXml = $this->getMain()->isInternalMode()
|
||||
|| $this->getMain()->getPrinter()->getFormat() == 'XML';
|
||||
$result = $this->getResult();
|
||||
$params = $this->params = $this->extractRequestParams();
|
||||
$limit = intval($params['limit']);
|
||||
$limit = ($limit < 0) ? false : $limit;
|
||||
|
||||
foreach ($titles as $id => $title) {
|
||||
try {
|
||||
$credit = $this->helper->getContributors($title, $limit);
|
||||
if ($isXml) {
|
||||
$result->addValue(['query', 'pages', $id], 'pagecredit', ['*' => $credit]);
|
||||
} else {
|
||||
$result->addValue(['query', 'pages', $id], 'pagecredit', $credit);
|
||||
}
|
||||
} catch(Exception $e){
|
||||
$result->addValue(['query', 'pages', $id], 'pagecredit', ['error' => $e->getTraceAsString()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params Ignored parameters
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheMode($params) {
|
||||
return 'public';
|
||||
}
|
||||
|
||||
public function getAllowedParams() {
|
||||
return [
|
||||
'limit' => [
|
||||
ParamValidator::PARAM_DEFAULT => -1,
|
||||
ApiBase::PARAM_TYPE => 'limit',
|
||||
ApiBase::PARAM_MIN => -1,
|
||||
ApiBase::PARAM_MAX => 100,
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace Isekai\Contributors;
|
||||
|
||||
use Html;
|
||||
use IContextSource;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Title;
|
||||
|
||||
class ContributorsBox {
|
||||
private $context;
|
||||
private $title;
|
||||
private $helper;
|
||||
private $contributors;
|
||||
|
||||
public function __construct(IContextSource $context, Title $title){
|
||||
$this->context = $context;
|
||||
$this->title = $title;
|
||||
$this->helper = new PageCreditHelper($context);
|
||||
|
||||
$this->contributors = $this->helper->getContributors($this->title, 5);
|
||||
}
|
||||
|
||||
public function getSideboxPanelHtml(){
|
||||
global $wgIsekaiContributorAvatar;
|
||||
if(empty($this->contributors)) return '';
|
||||
$userList = array_merge([$this->contributors['last_editor']], [$this->contributors['creator']],
|
||||
$this->contributors['contributors']);
|
||||
$userHtml = [];
|
||||
$exportedUser = [];
|
||||
foreach ($userList as $user){
|
||||
if(!in_array($user['user_name'], $exportedUser)) {
|
||||
$displayName = $user['display_name'];
|
||||
if($user['user_name'] != $displayName) $displayName .= ' [@' . $user['user_name'] . ']';
|
||||
$userHtml[] = Html::element('a', [
|
||||
'href' => $user['user_page']->getLinkURL(),
|
||||
'target' => '_blank',
|
||||
'title' => $displayName,
|
||||
'style' => "background-image: url('" . sprintf($wgIsekaiContributorAvatar, urlencode($user['user_name'])) . "')",
|
||||
]);
|
||||
$exportedUser[] = $user['user_name'];
|
||||
}
|
||||
}
|
||||
$userHtml[] = Html::element('a', [
|
||||
'href' => 'javascript:;',
|
||||
'title' => wfMessage('isekaicontrib-viewall')->text(),
|
||||
'class' => 'isekai-img-more-contrib isekai-contrib-open-dialog',
|
||||
]);
|
||||
return Html::openElement('div', ['class' => 'isekai-contrib-sidebox-panel']) .
|
||||
Html::openElement('div', ['class' => 'isekai-contrib-panel']) .
|
||||
implode('', $userHtml) . Html::closeElement('div') . Html::closeElement('div');
|
||||
}
|
||||
|
||||
public function getTopPanelHtml(){
|
||||
global $wgIsekaiContributorAvatar;
|
||||
if(empty($this->contributors)) return '';
|
||||
$userList = array_merge([$this->contributors['last_editor']], [$this->contributors['creator']],
|
||||
$this->contributors['contributors']);
|
||||
$userHtml = [
|
||||
Html::openElement('div', ['class' => 'avatar-zone']),
|
||||
Html::element('span', ['class' => 'isekai-contrib-panel-title'], wfMessage('isekai-contrib')->text())
|
||||
];
|
||||
$exportedUser = [];
|
||||
foreach ($userList as $user){
|
||||
if(!in_array($user['user_name'], $exportedUser)) {
|
||||
$displayName = $user['display_name'];
|
||||
if($user['user_name'] != $displayName) $displayName .= ' [@' . $user['user_name'] . ']';
|
||||
$userHtml[] = Html::element('a', [
|
||||
'href' => $user['user_page']->getLinkURL(),
|
||||
'target' => '_blank',
|
||||
'title' => $displayName,
|
||||
'style' => "background-image: url('" . sprintf($wgIsekaiContributorAvatar, urlencode($user['user_name'])) . "')",
|
||||
]);
|
||||
$exportedUser[] = $user['user_name'];
|
||||
}
|
||||
}
|
||||
$userHtml[] = Html::closeElement('div');
|
||||
$userHtml[] = Html::element('div', ['class' => 'spacer']);
|
||||
$userHtml[] = Html::element('a', [
|
||||
'href' => 'javascript:;',
|
||||
'title' => wfMessage('isekaicontrib-viewall')->text(),
|
||||
'class' => 'isekai-img-more-contrib isekai-contrib-open-dialog',
|
||||
]);
|
||||
return Html::openElement('div', ['class' => 'isekai-contrib-top-panel isekai-contrib-panel']) .
|
||||
implode('', $userHtml) . Html::closeElement('div');
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace Isekai\Contributors;
|
||||
|
||||
use OutputPage;
|
||||
use Skin;
|
||||
use Config;
|
||||
use Title;
|
||||
use PageProps;
|
||||
use Exception;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class Hooks {
|
||||
public static function onBeforePageDisplay(OutputPage $outputPage){
|
||||
$outputPage->addModuleStyles('ext.isekai.contrib.styles');
|
||||
$outputPage->addModules(['ext.isekai.contrib.images', 'ext.isekai.contrib.dialog']);
|
||||
}
|
||||
|
||||
public static function onSidebarBeforeOutput(Skin $skin, array &$sidebar){
|
||||
if(!$skin->getOutput()->isArticle()) return;
|
||||
|
||||
$title = $skin->getTitle();
|
||||
if($title && !in_array($title->getNamespace(), [NS_MAIN, NS_CATEGORY, NS_FILE, NS_HELP, NS_PROJECT])){
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$sidebar['isekai-contrib'] = (new ContributorsBox($skin->getContext(), $title))->getSideboxPanelHtml();
|
||||
} catch(Exception $e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static function onSkinTemplateOutputPageBeforeExec(\SkinTemplate &$skin, \QuickTemplate &$template){
|
||||
if(!$skin->getOutput()->isArticle()) return;
|
||||
|
||||
$title = $skin->getTitle();
|
||||
if($title && !in_array($title->getNamespace(), [NS_MAIN, NS_CATEGORY, NS_FILE, NS_HELP, NS_PROJECT])){
|
||||
return;
|
||||
}
|
||||
|
||||
$props = self::getPageProp($title);
|
||||
if(!isset($props['nocreditbox'])){
|
||||
try {
|
||||
$template->extend('subtitle', (new ContributorsBox($skin->getContext(), $title))->getTopPanelHtml());;
|
||||
} catch(Exception $e){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function onGetDoubleUnderscoreIDs(array &$ids){
|
||||
$ids[] = 'nocreditbox';
|
||||
}
|
||||
|
||||
public static function onResourceLoaderGetConfigVars(array &$vars, string $skin, Config $config){
|
||||
$vars['wgIsekaiContributorAvatar'] = $config->get('IsekaiContributorAvatar');
|
||||
}
|
||||
|
||||
public static function getPageProp(Title $title){
|
||||
$id = $title->getArticleID();
|
||||
$props = PageProps::getInstance()->getAllProperties( $title );
|
||||
return $props[$id] ?? [];
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Isekai\Contributors;
|
||||
|
||||
use Article;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use SpecialPage;
|
||||
use Title;
|
||||
use User;
|
||||
|
||||
class PageCreditHelper {
|
||||
private $cache;
|
||||
private $context;
|
||||
|
||||
public function __construct($context){
|
||||
$this->cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function getContributors(Title $title, $limit = false){
|
||||
return $this->cache->getWithSetCallback(
|
||||
$this->cache->makeKey('isekai_page_credit', $title->getArticleID(), $title->getLatestRevID()),
|
||||
$this->cache::TTL_MINUTE * 10,
|
||||
function() use($title, $limit){
|
||||
$wikiPage = Article::newFromTitle($title, $this->context)->getPage();
|
||||
if(!$wikiPage->exists()) return [];
|
||||
|
||||
$creator = $wikiPage->getCreator();
|
||||
$contributors = $wikiPage->getContributors();
|
||||
$lastEditor = User::newFromName($wikiPage->getUserText());
|
||||
|
||||
$contributorInfo = [];
|
||||
$count = 0;
|
||||
foreach ($contributors as $user) {
|
||||
$contributorInfo[] = $this->getUserInfo($user);
|
||||
$count++;
|
||||
if ($limit !== false && $count > $limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'creator' => $this->getUserInfo($creator),
|
||||
'last_editor' => $this->getUserInfo($lastEditor),
|
||||
'contributors' => $contributorInfo,
|
||||
'count' => $contributors->count(),
|
||||
];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function onPageEdit(Title $title){
|
||||
$this->cache->delete($this->cache->makeKey('isekai_page_credit', $title->getArticleID(), $title->getLatestRevID()));
|
||||
}
|
||||
|
||||
public function getUserInfo(User $user){
|
||||
$userInfo = [];
|
||||
if ($user->getRealName()) {
|
||||
$userInfo['display_name'] = $user->getRealName();
|
||||
} else {
|
||||
$userInfo['display_name'] = $user->getName();
|
||||
}
|
||||
$userInfo['user_name'] = $user->getName();
|
||||
$userInfo['user_page'] = $this->getUserPage($user);
|
||||
return $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a link to $user's user page
|
||||
* @param User $user
|
||||
* @return string Html
|
||||
*/
|
||||
protected function getUserPage( User $user ) {
|
||||
$page = $user->isAnon()
|
||||
? SpecialPage::getTitleFor( 'Contributions', $user->getName() )
|
||||
: $user->getUserPage();
|
||||
|
||||
return $page;
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
if (!('isekai' in window)) window.isekai = {};
|
||||
|
||||
/**
|
||||
* @class isekai.ContribDialog
|
||||
* @param {*} config
|
||||
*/
|
||||
isekai.ContribDialog = function IsekaiContribDialog(config) {
|
||||
isekai.ContribDialog.super.call(this, config);
|
||||
this.broken = false;
|
||||
};
|
||||
|
||||
OO.inheritClass(isekai.ContribDialog, OO.ui.ProcessDialog);
|
||||
isekai.ContribDialog.static.name = 'isekaicontrib-dialog';
|
||||
isekai.ContribDialog.static.title = mw.msg('isekaicontrib-dialog-title');
|
||||
|
||||
isekai.ContribDialog.static.actions = [
|
||||
{ action: 'cancel', label: mw.msg('isekaicontrib-dialog-cancel'), flags: ['safe', 'close'] }
|
||||
];
|
||||
|
||||
isekai.ContribDialog.prototype.initialize = function () {
|
||||
isekai.ContribDialog.super.prototype.initialize.apply(this, arguments);
|
||||
this.api = new mw.Api();
|
||||
|
||||
this.content = new OO.ui.PanelLayout({ padded: false });
|
||||
|
||||
//加载动画
|
||||
this.loadingWidget = new OO.ui.ProgressBarWidget({
|
||||
progress: false,
|
||||
classes: ['isekai-contrib-loading']
|
||||
});
|
||||
this.content.$element.append(this.loadingWidget.$element);
|
||||
//贡献者列表容器
|
||||
this.content.$element.append('<div class="isekai-contrib-list"></div>');
|
||||
this.contribContainer = this.content.$element.find('.isekai-contrib-list');
|
||||
|
||||
this.$body.append(this.content.$element);
|
||||
}
|
||||
|
||||
isekai.ContribDialog.prototype.getUserAvatar = function (userName) {
|
||||
var template = mw.config.get('wgIsekaiContributorAvatar');
|
||||
if (template) {
|
||||
return template.replace(/\%s/g, userName);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成用户栏目html
|
||||
* @param {any} userData - 用户信息
|
||||
* @returns {string} 生成的html
|
||||
*/
|
||||
isekai.ContribDialog.prototype.getUserListItem = function (userData) {
|
||||
return '<a class="isekai-list-item" href="' + mw.util.getUrl(userData.user_page) + '" target="_blank">' +
|
||||
'<div class="isekai-list-item-avatar"><img src="' + this.getUserAvatar(userData.user_name) + '"></div>' +
|
||||
'<div class="isekai-list-item-content">' +
|
||||
'<div class="isekai-list-item-title">' + userData.display_name + '</div>' +
|
||||
'<div class="isekai-list-item-text">@' + userData.user_name + '</div>' +
|
||||
'</div>' +
|
||||
'</a>';
|
||||
};
|
||||
|
||||
/**
|
||||
* 加载贡献者列表
|
||||
*/
|
||||
isekai.ContribDialog.prototype.loadContributors = function () {
|
||||
var currentPageId = mw.config.get('wgArticleId');
|
||||
this.api.get({
|
||||
action: 'query',
|
||||
prop: 'pagecredit',
|
||||
pageids: currentPageId,
|
||||
}).done((data) => {
|
||||
if('query' in data && 'pages' in data.query){
|
||||
if(currentPageId in data.query.pages){
|
||||
var pageData = data.query.pages[currentPageId];
|
||||
if('missing' in pageData) return;
|
||||
if(!pageData.pagecredit || 'error' in pageData.pagecredit) return;
|
||||
|
||||
var creditData = pageData.pagecredit;
|
||||
this.loadingWidget.toggle(false);
|
||||
this.contribContainer.empty();
|
||||
if('creator' in creditData){
|
||||
this.contribContainer.append('<div class="isekai-list-item-sub">' + mw.msg('isekaicontrib-dialog-subtitle-creator') + '</div>');
|
||||
this.contribContainer.append(this.getUserListItem(creditData.creator));
|
||||
}
|
||||
if('last_editor' in creditData){
|
||||
this.contribContainer.append('<div class="isekai-list-item-sub">' + mw.msg('isekaicontrib-dialog-subtitle-last-editor') + '</div>');
|
||||
this.contribContainer.append(this.getUserListItem(creditData.last_editor));
|
||||
}
|
||||
if(('contributors' in creditData) && creditData.contributors.length > 0){
|
||||
this.contribContainer.append('<div class="isekai-list-item-sub">' + mw.msg('isekaicontrib-dialog-subtitle-contributors') + '</div>');
|
||||
creditData.contributors.forEach((editor) => {
|
||||
this.contribContainer.append(this.getUserListItem(editor));
|
||||
this.contribContainer.append('<hr class="isekai-list-item-divider">');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
isekai.ContribDialog.prototype.getBodyHeight = function () {
|
||||
return 400;
|
||||
};
|
||||
|
||||
isekai.ContribDialog.prototype.getSetupProcess = function (data) {
|
||||
var _this = this;
|
||||
return isekai.ContribDialog.super.prototype.getSetupProcess.call(this, data).next(function(){
|
||||
_this.loadContributors();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
isekai.ContribDialog.prototype.getActionProcess = function (action) {
|
||||
var dialog = this;
|
||||
return new OO.ui.Process(function () {
|
||||
dialog.close({ action: action });
|
||||
});
|
||||
};
|
||||
|
||||
// ==============================================================
|
||||
var contribDialog = new isekai.ContribDialog({});
|
||||
var windowManager = new OO.ui.WindowManager();
|
||||
$(document.body).append(windowManager.$element);
|
||||
windowManager.addWindows([contribDialog]);
|
||||
|
||||
$('.isekai-contrib-open-dialog').click(function () {
|
||||
windowManager.openWindow(contribDialog);
|
||||
return false;
|
||||
});
|
@ -0,0 +1,109 @@
|
||||
.isekai-contrib-loading {
|
||||
margin: 20px 16px;
|
||||
}
|
||||
|
||||
.isekai-contrib-list {
|
||||
margin: 0;
|
||||
padding: 0 0 8px 0;
|
||||
list-style: none;
|
||||
background-color: transparent;
|
||||
|
||||
.isekai-list-item {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
min-height: 48px;
|
||||
padding: 0 16px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,.08);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.isekai-list-item-sub {
|
||||
background-color: #e6e6e6;
|
||||
color: #000;
|
||||
padding-left: 20px;
|
||||
min-height: 28px;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.isekai-list-item-divider {
|
||||
background-color: rgba(0,0,0,.12);
|
||||
height: 1px;
|
||||
margin: 0 0 0 72px;
|
||||
border: none;
|
||||
|
||||
&:last-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.isekai-list-item-avatar {
|
||||
min-width: 40px;
|
||||
max-width: 40px;
|
||||
height: 40px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
color: #fff;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&~.isekai-list-item-content {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.isekai-list-item-secondary {
|
||||
margin-left: 4px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.isekai-list-item-content {
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex-positive: 1;
|
||||
flex-grow: 1;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 14px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.isekai-list-item-title~.isekai-list-item-text {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.isekai-list-item-text {
|
||||
font-size: 14px;
|
||||
opacity: .54;
|
||||
-webkit-line-clamp: 1;
|
||||
height: 20px;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
.isekai-contrib-panel {
|
||||
text-align: left;
|
||||
line-height: 0;
|
||||
|
||||
a {
|
||||
margin: 3px 2px;
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 3px;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.isekai-contrib-top-panel {
|
||||
padding: .25rem 0.5rem;
|
||||
margin-bottom: 0;
|
||||
background-color: rgba(0,0,0,0.03);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.25rem;
|
||||
border: 1px solid rgba(0,0,0,0.125);
|
||||
|
||||
.spacer {
|
||||
height: 100%;
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex-positive: 1;
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.isekai-contrib-panel-title {
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
padding: 0 10px;
|
||||
line-height: 30px;
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
margin: 3px 0;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.isekai-contrib-open-dialog {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1100px) {
|
||||
.isekai-contrib-top-panel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.isekai-contrib-sidebox-panel {
|
||||
padding-bottom: 10px;
|
||||
min-width: 150px;
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
.skin-timeless .isekai-contrib-sidebox-panel {
|
||||
margin-top: -8px;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
<svg id="e1c67992-10f2-4b29-a57d-cb41e8ffbd1d" data-name="pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.b4d6abb5-d0c3-464f-a432-d7852fd7ae6f{fill:#ccc;}.b79d9a3f-d2af-4218-91ec-f36af9a01dfe{fill:#fff;}</style></defs><rect class="b4d6abb5-d0c3-464f-a432-d7852fd7ae6f" width="100" height="100"/><circle class="b79d9a3f-d2af-4218-91ec-f36af9a01dfe" cx="49.53" cy="50.06" r="8.77"/><circle class="b79d9a3f-d2af-4218-91ec-f36af9a01dfe" cx="18.84" cy="50.06" r="8.77"/><circle class="b79d9a3f-d2af-4218-91ec-f36af9a01dfe" cx="80.23" cy="50.06" r="8.77"/></svg>
|
After Width: | Height: | Size: 583 B |
Loading…
Reference in New Issue