tona-plugins 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/index.d.ts +32 -0
- package/package.json +51 -0
- package/src/constants/cdn.js +12 -0
- package/src/index.js +30 -0
- package/src/plugins/background/index.js +50 -0
- package/src/plugins/background/index.scss +0 -0
- package/src/plugins/barrage/index.js +104 -0
- package/src/plugins/barrage/index.scss +16 -0
- package/src/plugins/catalog/index.js +212 -0
- package/src/plugins/catalog/index.scss +0 -0
- package/src/plugins/charts/index.js +60 -0
- package/src/plugins/charts/index.scss +16 -0
- package/src/plugins/clickEffects/index.js +137 -0
- package/src/plugins/clickEffects/index.scss +0 -0
- package/src/plugins/codeCopy/index.js +94 -0
- package/src/plugins/codeCopy/index.scss +65 -0
- package/src/plugins/codeHighlight/index.js +35 -0
- package/src/plugins/codeHighlight/index.scss +216 -0
- package/src/plugins/codeHighlight/themes.js +60 -0
- package/src/plugins/codeLang/index.js +51 -0
- package/src/plugins/codeLang/index.scss +28 -0
- package/src/plugins/codeLinenumbers/index.js +33 -0
- package/src/plugins/codeLinenumbers/index.scss +61 -0
- package/src/plugins/codeTrafficLight/index.js +18 -0
- package/src/plugins/codeTrafficLight/index.scss +0 -0
- package/src/plugins/colorMode/index.js +81 -0
- package/src/plugins/colorMode/index.scss +0 -0
- package/src/plugins/commentsAvatars/index.js +85 -0
- package/src/plugins/commentsAvatars/index.scss +3 -0
- package/src/plugins/darkMode/index.js +115 -0
- package/src/plugins/darkMode/index.scss +67 -0
- package/src/plugins/donation/index.js +45 -0
- package/src/plugins/donation/index.scss +63 -0
- package/src/plugins/emoji/index.js +167 -0
- package/src/plugins/emoji/index.scss +155 -0
- package/src/plugins/footer/index.js +35 -0
- package/src/plugins/footer/index.scss +54 -0
- package/src/plugins/imagePreview/index.js +98 -0
- package/src/plugins/imagePreview/index.scss +51 -0
- package/src/plugins/license/index.js +62 -0
- package/src/plugins/license/index.scss +51 -0
- package/src/plugins/live2d/index.js +67 -0
- package/src/plugins/live2d/index.scss +0 -0
- package/src/plugins/live2d/live2d-models.js +21 -0
- package/src/plugins/lock/index.js +77 -0
- package/src/plugins/lock/index.scss +56 -0
- package/src/plugins/musicPlayer/index.js +81 -0
- package/src/plugins/musicPlayer/index.scss +68 -0
- package/src/plugins/notation/index.js +73 -0
- package/src/plugins/notation/index.scss +12 -0
- package/src/plugins/notice/index.js +17 -0
- package/src/plugins/notice/index.scss +46 -0
- package/src/plugins/postBottomImage/index.js +27 -0
- package/src/plugins/postBottomImage/index.scss +26 -0
- package/src/plugins/postMessage/index.js +89 -0
- package/src/plugins/postMessage/index.scss +81 -0
- package/src/plugins/postTopImage/index.js +28 -0
- package/src/plugins/postTopImage/index.scss +29 -0
- package/src/plugins/qrcode/index.js +42 -0
- package/src/plugins/qrcode/index.scss +10 -0
- package/src/plugins/signature/index.js +47 -0
- package/src/plugins/signature/index.scss +18 -0
- package/src/plugins/toast/index.js +49 -0
- package/src/plugins/tools/index.js +251 -0
- package/src/plugins/tools/index.scss +114 -0
- package/src/plugins/webTag/index.js +40 -0
- package/src/plugins/webTag/index.scss +0 -0
- package/src/utils/cnblog.js +282 -0
- package/src/utils/helpers.js +418 -0
- package/src/utils/shared.js +2 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// 构建代码行号
|
|
2
|
+
import { getCodeLangOptions } from 'tona-options'
|
|
3
|
+
import { isMd, isPostDetailsPage } from '../../utils/cnblog'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 构建代码行号
|
|
7
|
+
*/
|
|
8
|
+
function buildLinenumbers() {
|
|
9
|
+
$('pre code').each(function () {
|
|
10
|
+
const linenumberContainer = $('<ul/>').addClass('awes-linenumber')
|
|
11
|
+
const lines = $(this).text().split('\n').length - 1
|
|
12
|
+
|
|
13
|
+
for (let i = 1; i <= lines; i++) {
|
|
14
|
+
linenumberContainer.append($('<li/>').text(i))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
$(this).before(linenumberContainer)
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function codeLinenumbers(_, devOptions) {
|
|
22
|
+
const { enable } = getCodeLangOptions(devOptions)
|
|
23
|
+
if (!isPostDetailsPage) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
if (!enable) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if (!isMd()) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
buildLinenumbers()
|
|
33
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
|
|
3
|
+
$lineNumbers: () !default;
|
|
4
|
+
$lineNumbers: map.merge(
|
|
5
|
+
(
|
|
6
|
+
color: #999999,
|
|
7
|
+
),
|
|
8
|
+
$lineNumbers
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
$lineNumbersColor: map.get($lineNumbers, color);
|
|
12
|
+
|
|
13
|
+
/* 覆盖博客园bundle css*/
|
|
14
|
+
@media screen and (max-width: 767px) {
|
|
15
|
+
#cnblogs_post_body td {
|
|
16
|
+
white-space: pre;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@media screen and (max-width: 768px) {
|
|
21
|
+
.awes-linenumber {
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Markdown */
|
|
27
|
+
#cnblogs_post_body {
|
|
28
|
+
pre {
|
|
29
|
+
display: flex;
|
|
30
|
+
ul.awes-linenumber {
|
|
31
|
+
margin-top: 0;
|
|
32
|
+
}
|
|
33
|
+
.awes-linenumber {
|
|
34
|
+
margin: 0;
|
|
35
|
+
padding: 16px 16px 8px 16px;
|
|
36
|
+
li {
|
|
37
|
+
font-weight: normal;
|
|
38
|
+
color: $lineNumbersColor;
|
|
39
|
+
list-style: none;
|
|
40
|
+
text-align: right;
|
|
41
|
+
line-height: 1.5;
|
|
42
|
+
font-size: 15px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* 富文本 */
|
|
49
|
+
#cnblogs_post_body .cnblogs_code {
|
|
50
|
+
pre {
|
|
51
|
+
display: block;
|
|
52
|
+
span[style='color: #008080;'] {
|
|
53
|
+
padding: 2px 0;
|
|
54
|
+
border: none;
|
|
55
|
+
text-align: center;
|
|
56
|
+
color: $lineNumbersColor !important;
|
|
57
|
+
word-break: normal;
|
|
58
|
+
white-space: pre;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getCodeTrafficLightOptions } from 'tona-options'
|
|
2
|
+
import { isPostDetailsPage } from '../../utils/cnblog'
|
|
3
|
+
import { insertStyle } from '../../utils/helpers'
|
|
4
|
+
|
|
5
|
+
export function codeTrafficLight(_, devOptions) {
|
|
6
|
+
const { enable } = getCodeTrafficLightOptions(devOptions)
|
|
7
|
+
|
|
8
|
+
if (!enable) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
if (!isPostDetailsPage()) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
insertStyle(
|
|
16
|
+
"pre[class*='language-'].highlighter-prismjs,pre code.hljs{position:relative;padding:2.5em 1em 1em}pre[class*='language-'].highlighter-prismjs::before,pre code.hljs::before{content:'';position:absolute;top:10px;left:12px;width:12px;height:12px;background:#fe5f59;border-radius:50%;box-shadow:20px 0 #febb2c,40px 0 #29c73f;z-index:2;}",
|
|
17
|
+
)
|
|
18
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设置皮肤色
|
|
3
|
+
* 需要皮肤使用相关 css 自定义属性
|
|
4
|
+
*/
|
|
5
|
+
import { getThemeOptions } from 'tona-options'
|
|
6
|
+
import { randomColor } from '../../utils/helpers'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 将 16 进制颜色转成 rgb 或 rgba
|
|
10
|
+
* @param {string} hex
|
|
11
|
+
* @param {number} opacity
|
|
12
|
+
*/
|
|
13
|
+
function hexToRgba(hex, opacity) {
|
|
14
|
+
if (!hex) {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Check if already an RGB value
|
|
19
|
+
if (/^rgb\(/i.test(hex)) {
|
|
20
|
+
return hex
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Use explicit character ranges for better clarity
|
|
24
|
+
const hexReg = /^#(?:[0-9A-F]{3}|[0-9A-F]{6})$/i
|
|
25
|
+
if (!hexReg.test(hex)) {
|
|
26
|
+
return hex
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Remove the # and handle 3-digit hex shorthand
|
|
30
|
+
let hexValue = hex.slice(1)
|
|
31
|
+
if (hexValue.length === 3) {
|
|
32
|
+
hexValue = hexValue
|
|
33
|
+
.split('')
|
|
34
|
+
.map((char) => char + char)
|
|
35
|
+
.join('')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const red = Number.parseInt(hexValue.slice(0, 2), 16)
|
|
39
|
+
const green = Number.parseInt(hexValue.slice(2, 4), 16)
|
|
40
|
+
const blue = Number.parseInt(hexValue.slice(4, 6), 16)
|
|
41
|
+
|
|
42
|
+
if (opacity === undefined || opacity === null) {
|
|
43
|
+
return `rgb(${red},${green},${blue})`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return `rgba(${red},${green},${blue},${opacity})`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 获取皮肤色
|
|
51
|
+
* @param {*} color
|
|
52
|
+
*/
|
|
53
|
+
function buildMainColor(color) {
|
|
54
|
+
const mainColor = color === 'random' ? randomColor('rgba') : color
|
|
55
|
+
return mainColor
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 插入 css 变量
|
|
60
|
+
* @param {*} color
|
|
61
|
+
*/
|
|
62
|
+
function insertStyle(color) {
|
|
63
|
+
const primary = buildMainColor(color)
|
|
64
|
+
const primary8 = hexToRgba(primary, 0.85)
|
|
65
|
+
const primary4 = hexToRgba(primary, 0.4)
|
|
66
|
+
const primary2 = hexToRgba(primary, 0.2)
|
|
67
|
+
|
|
68
|
+
$('head').append(
|
|
69
|
+
`<style class="themeColor">:root{
|
|
70
|
+
--themeColor: ${primary};
|
|
71
|
+
--theme-primary-8: ${primary8};
|
|
72
|
+
--theme-primary-4: ${primary4};
|
|
73
|
+
--theme-primary-2: ${primary2};
|
|
74
|
+
</style>`,
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function colorMode(_, devOptions) {
|
|
79
|
+
const { color } = getThemeOptions(devOptions)
|
|
80
|
+
insertStyle(color)
|
|
81
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { getCurrentPage } from '../../utils/cnblog'
|
|
2
|
+
import { poll } from '../../utils/helpers'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 构建头像
|
|
6
|
+
*/
|
|
7
|
+
function buildAvatars() {
|
|
8
|
+
if ($('.custom-comment-avatar').length) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
$('.feedbackItem').each(function () {
|
|
12
|
+
let avatar = $(this).children('.feedbackCon').children('span:last').html()
|
|
13
|
+
|
|
14
|
+
avatar = avatar
|
|
15
|
+
? avatar.replace('http://', 'https://')
|
|
16
|
+
: 'https://pic.cnblogs.com/face/sample_face.gif'
|
|
17
|
+
|
|
18
|
+
const ele = `<div class='custom-comment-avatar'><img src="${avatar}" class='avatar' /></div>`
|
|
19
|
+
$(this).children('.feedbackCon').prepend(ele)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 调整支持反对按钮位置
|
|
25
|
+
*/
|
|
26
|
+
function moveSupport() {
|
|
27
|
+
$('.comment_vote').each(function () {
|
|
28
|
+
$(this).appendTo($(this).parent().siblings('.feedbackListSubtitle'))
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 作者回复靠右
|
|
34
|
+
*/
|
|
35
|
+
function authorRight() {
|
|
36
|
+
$('.feedbackItem').each(function () {
|
|
37
|
+
const isAuthor = $(this).find('.louzhu').text() === '楼主'
|
|
38
|
+
if (isAuthor) {
|
|
39
|
+
$(this).addClass('custom-comments-author')
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 组合
|
|
46
|
+
*/
|
|
47
|
+
function build() {
|
|
48
|
+
buildAvatars()
|
|
49
|
+
moveSupport()
|
|
50
|
+
authorRight()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 监听 ajax
|
|
55
|
+
*/
|
|
56
|
+
function listener() {
|
|
57
|
+
window.renderCommentsAvatars = build
|
|
58
|
+
$(document).ajaxComplete((_, __, option) => {
|
|
59
|
+
if (
|
|
60
|
+
option.url.includes('PostComment/Add') ||
|
|
61
|
+
option.url.includes('DeleteComment')
|
|
62
|
+
) {
|
|
63
|
+
// eslint-disable-next-line new-cap
|
|
64
|
+
new window.blogCommentManager().renderComments(0)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
$(document).ajaxComplete((_, __, option) => {
|
|
68
|
+
if (option.url.includes('GetComments')) {
|
|
69
|
+
window.renderCommentsAvatars()
|
|
70
|
+
window.buildEmojis()
|
|
71
|
+
window.imagebox()
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
poll(() => $('.feedbackItem').length, build)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function commentsAvatars() {
|
|
78
|
+
if (getCurrentPage() !== 'post') {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
if ($('.custom-comment-avatar').lenght) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
listener()
|
|
85
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { getDarkModeOptions } from 'tona-options'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 覆盖自定义背景色
|
|
5
|
+
* @param {string} mode
|
|
6
|
+
*/
|
|
7
|
+
// function setBackground(mode) {
|
|
8
|
+
// const {
|
|
9
|
+
// enable,
|
|
10
|
+
// value,
|
|
11
|
+
// type,
|
|
12
|
+
// } = window.opts.bodyBackground
|
|
13
|
+
// if (!enable) return
|
|
14
|
+
|
|
15
|
+
// if (mode === 'dark') {
|
|
16
|
+
// if (type !== 'color') return
|
|
17
|
+
// setTimeout(() => {
|
|
18
|
+
// $('body').css('background-color', '#333')
|
|
19
|
+
// }, 0)
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
// if (mode === 'light') {
|
|
23
|
+
// if (type !== 'color') return
|
|
24
|
+
// $('body').css('background-color', `${value}`) // bodybgc设置
|
|
25
|
+
// }
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 切换代码块深色、浅色主题
|
|
30
|
+
* @param {string} mode 'dark' | 'light'
|
|
31
|
+
*/
|
|
32
|
+
function setCodeTheme(mode) {
|
|
33
|
+
mode === 'dark'
|
|
34
|
+
? window.highlighter.setTheme(window.darkModeCodeHighlightTheme)
|
|
35
|
+
: window.highlighter.setTheme(window.codeHighlightTheme)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 在暗色皮肤和亮色皮肤之间切换
|
|
40
|
+
* @param {string} mode 'dark' | 'light'
|
|
41
|
+
* @param {boolean} withTransition
|
|
42
|
+
*/
|
|
43
|
+
function changeMode(mode, withTransition = true) {
|
|
44
|
+
setCodeTheme(mode)
|
|
45
|
+
$('html').attr('theme', mode)
|
|
46
|
+
localStorage.modeType = mode
|
|
47
|
+
|
|
48
|
+
const transitionClassName =
|
|
49
|
+
mode === 'dark' ? 'light-to-dark' : 'dark-to-light'
|
|
50
|
+
|
|
51
|
+
if (withTransition) {
|
|
52
|
+
$('body').addClass(transitionClassName)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
setTimeout(() => $('body').removeClass(transitionClassName), 1200)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 初始化
|
|
60
|
+
* @param {string} darkDefault
|
|
61
|
+
* @param {boolean} autoDark
|
|
62
|
+
* @param {boolean} autoLight
|
|
63
|
+
*/
|
|
64
|
+
function init(darkDefault, autoDark, autoLight) {
|
|
65
|
+
const hour = new Date().getHours()
|
|
66
|
+
const isNight = hour > 19 || hour <= 5
|
|
67
|
+
const storage = localStorage.modeType
|
|
68
|
+
|
|
69
|
+
const followStorage = () => {
|
|
70
|
+
if (storage) {
|
|
71
|
+
changeMode(storage, false)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!storage) {
|
|
76
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
77
|
+
? changeMode('dark', false)
|
|
78
|
+
: changeMode('light', false)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!storage && darkDefault) {
|
|
83
|
+
changeMode('dark', false)
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (isNight) {
|
|
88
|
+
autoDark ? changeMode('dark', false) : followStorage()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!isNight) {
|
|
92
|
+
autoLight ? changeMode('light', false) : followStorage()
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 处理皮肤切换按钮点击事件
|
|
98
|
+
*/
|
|
99
|
+
function listenToggleButtonClick() {
|
|
100
|
+
$(document).on('click', '.mode-change', () => {
|
|
101
|
+
const isDark = $('html').attr('theme') === 'dark'
|
|
102
|
+
isDark ? changeMode('light') : changeMode('dark')
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function darkMode(_, devOptions) {
|
|
107
|
+
const { enable, darkDefault, autoDark, autoLight } =
|
|
108
|
+
getDarkModeOptions(devOptions)
|
|
109
|
+
|
|
110
|
+
if (!enable) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
init(darkDefault, autoDark, autoLight)
|
|
114
|
+
listenToggleButtonClick()
|
|
115
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
|
|
3
|
+
$mode: () !default;
|
|
4
|
+
$mode: map.merge(
|
|
5
|
+
(
|
|
6
|
+
bg-light: #fff,
|
|
7
|
+
bg-dark: #252528,
|
|
8
|
+
),
|
|
9
|
+
$mode
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
$bg-light: map.get($mode, bg-light);
|
|
13
|
+
$bg-dark: map.get($mode, bg-dark);
|
|
14
|
+
|
|
15
|
+
.dark-to-light:after {
|
|
16
|
+
content: '';
|
|
17
|
+
width: 100vw;
|
|
18
|
+
height: 100vh;
|
|
19
|
+
position: fixed;
|
|
20
|
+
z-index: 99999;
|
|
21
|
+
left: 0;
|
|
22
|
+
top: 0;
|
|
23
|
+
margin-left: 0;
|
|
24
|
+
background-color: $bg-dark;
|
|
25
|
+
opacity: 0.7;
|
|
26
|
+
animation: toLight 0.6s linear 0s forwards;
|
|
27
|
+
pointer-events: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.light-to-dark:after {
|
|
31
|
+
content: '';
|
|
32
|
+
width: 100vw;
|
|
33
|
+
height: 100vh;
|
|
34
|
+
position: fixed;
|
|
35
|
+
z-index: 99999;
|
|
36
|
+
left: 0;
|
|
37
|
+
top: 0;
|
|
38
|
+
margin-left: 0;
|
|
39
|
+
background-color: $bg-light;
|
|
40
|
+
opacity: 0.7;
|
|
41
|
+
animation: toDark 0.6s linear 0s forwards;
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@keyframes toLight {
|
|
46
|
+
0% {
|
|
47
|
+
background-color: $bg-dark;
|
|
48
|
+
opacity: 0.7;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
100% {
|
|
52
|
+
background-color: $bg-light;
|
|
53
|
+
opacity: 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes toDark {
|
|
58
|
+
0% {
|
|
59
|
+
background-color: $bg-light;
|
|
60
|
+
opacity: 0.7;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
100% {
|
|
64
|
+
background-color: $bg-dark;
|
|
65
|
+
opacity: 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getDonationOptions } from 'tona-options'
|
|
2
|
+
import { getCurrentPage } from '../../utils/cnblog'
|
|
3
|
+
import { poll } from '../../utils/helpers'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 二维码展开收起操作
|
|
7
|
+
*/
|
|
8
|
+
function qrcodeToggle() {
|
|
9
|
+
$('#custom-donation-btn').click(() => {
|
|
10
|
+
$('#custom-donation-qrcode').toggle('swing')
|
|
11
|
+
})
|
|
12
|
+
$('#custom-donation-qrcode div').click(function () {
|
|
13
|
+
$(this).parent().toggle('linear')
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function donation(_, devOptions) {
|
|
18
|
+
const { enable, qrcodes } = getDonationOptions(devOptions)
|
|
19
|
+
|
|
20
|
+
if (!enable) {
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
if (getCurrentPage() !== 'post') {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
if (!qrcodes.length) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
poll(
|
|
31
|
+
() => $('#green_channel_favorite').length && $('#blog_post_info').length,
|
|
32
|
+
() => {
|
|
33
|
+
const btn = '<a id="custom-donation-btn">打赏</a>'
|
|
34
|
+
const qrcode = $('<div id="custom-donation-qrcode"></div>')
|
|
35
|
+
|
|
36
|
+
qrcodes.forEach((item) => {
|
|
37
|
+
qrcode.append(`<div style="background-image: url(${item})"></div>`)
|
|
38
|
+
})
|
|
39
|
+
$('#green_channel_favorite').after(btn)
|
|
40
|
+
$('#blog_post_info').before(qrcode)
|
|
41
|
+
|
|
42
|
+
qrcodeToggle()
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
|
|
3
|
+
$donation: () !default;
|
|
4
|
+
|
|
5
|
+
$donation: map.merge(
|
|
6
|
+
(
|
|
7
|
+
btnColors: #10ac84,
|
|
8
|
+
qrcodeBackground: #fff,
|
|
9
|
+
),
|
|
10
|
+
$donation
|
|
11
|
+
) !default;
|
|
12
|
+
|
|
13
|
+
$donationBtnColors: map.get($donation, btnColors);
|
|
14
|
+
$donationQrcodeBackground: map.get($donation, qrcodeBackground);
|
|
15
|
+
|
|
16
|
+
#custom-donation-btn {
|
|
17
|
+
background-color: $donationBtnColors !important;
|
|
18
|
+
padding: 4px 10px !important;
|
|
19
|
+
&:hover {
|
|
20
|
+
box-shadow: 0 0 5px #999;
|
|
21
|
+
transform: scale(1.1);
|
|
22
|
+
transform: translateY(-2px);
|
|
23
|
+
transition: all 0.2s;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#custom-donation-qrcode {
|
|
28
|
+
display: none;
|
|
29
|
+
position: relative;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
z-index: 999999999;
|
|
32
|
+
text-align: center;
|
|
33
|
+
& > div {
|
|
34
|
+
display: inline-block;
|
|
35
|
+
margin: 0 auto;
|
|
36
|
+
margin-right: 20px;
|
|
37
|
+
width: 180px;
|
|
38
|
+
height: 180px;
|
|
39
|
+
background-size: contain;
|
|
40
|
+
background-repeat: no-repeat;
|
|
41
|
+
border-radius: 5px;
|
|
42
|
+
background-color: $donationQrcodeBackground;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media screen and (max-width: 767px) {
|
|
47
|
+
#blog_post_info_block #blog_post_info #green_channel {
|
|
48
|
+
justify-content: center;
|
|
49
|
+
}
|
|
50
|
+
#custom-donation-btn {
|
|
51
|
+
margin: 3px !important;
|
|
52
|
+
&:hover {
|
|
53
|
+
transform: none;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
#custom-donation-qrcode {
|
|
57
|
+
& > div {
|
|
58
|
+
margin-right: 0;
|
|
59
|
+
width: 100%;
|
|
60
|
+
height: 320px;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|