pt下载软件遇到的问题

qBittorrent

qBittorrent WebUI 打不开

WebUI 皮肤路径一般是包含有 /public 的那层,如果不小心设置了错的路径,导致 WebUI 打不开,需要修改配置文件

测试发现直接改正确路径无效, 只能先回默认 UI, 在后台设置里修改路径

修改之前一定要把QB先停止了 然后再修改.

配置文件路径参考:/volume1/@appdata/qBittorrent/qBittorrent_conf/config/

在[Preferences]下
把WebUI\AlternativeUIEnabled=true
改为
WebUI\AlternativeUIEnabled=false

transmission

transmission 修改密码

sudo -i获取root账户权限

vim /volume1/@appdata/transmission/settings.json

默认的配置:
“rpc-password”: “{63f0220ad29c3e7e23c810bf5ba61c20d4e222631wsWz5Mi”,
“rpc-username”: “admin”,

后面引号内就是经过加密的密码,不要管他怎么加密的,直接把引号内的内容修改为你的新密码就可以了,比如”rpc-password”:”xxorg.com”
然后按 ESC 键,输入 :wq

实现一个像安卓彩蛋的隐藏功能

像安卓彩蛋一样的隐藏功能,通过多次点击可触发彩蛋

使用

添加依赖

1
2
flutter_egg: ^1.0.3

或者直接复制 lib/flutter_egg.dart 文件

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Egg(
neededNum: 5,
onTap: (int tapNum, int neededNum) {
if (tapNum > 1 && tapNum < 5) {
$warn('再按 ${neededNum - tapNum}次');
}
},
onTrigger: (int tapNum, int neededNum) {
$warn('yo~靓仔你发现了隐藏功能');
},
child: Text(
'You have pushed the\n button this many times:',
),
)

Getting Started

写项目的时候后端同学经常要我打一个测试包,但是又经常需要切换到线上地址查看效果,每次打个包要等几分钟实在太麻烦了.大家都知道安卓彩蛋是通过连续点击版本号来触发,于是便想做个像安卓彩蛋一样的隐藏功能,用来开启开发模式.

首先搭建简单的框架,可以点击,渲染 child

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import 'package:flutter/material.dart';

class Egg extends StatefulWidget {
final Widget child;

Egg({
this.child,
});

@override
_EggState createState() => _EggState();
}

class _EggState extends State<Egg> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: handleOnTap,
child: widget.child,
);
}

void handleOnTap() {
print(111);
}
}

我们的组件想通用就不能写死数据,所以给类加上一些参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Egg extends StatefulWidget {
final Widget child;

/// 总共需要点击的次数
final int neededNum;

/// 两次点击的间隔
final Duration interval;

Egg({
this.child,
this.neededNum = 5,
this.interval = const Duration(seconds: 1),
});

@override
_EggState createState() => _EggState();
}

如何记录连续点击呢?只需要一个数组存储每次点击的时刻,通过对比本次和上次点击的时刻是否在容许间隔内,如果是则把本次时刻存起,用于下次对比;如果否就清空旧数据,只存本次点击时刻

下面是处理点击的逻辑.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
handleOnTap() {
DateTime _lastPressedAt = tapTimeList.length > 0 ? tapTimeList.last : null;
DateTime now = DateTime.now();

print(_lastPressedAt);

// 不超过点击间隔,tapTimeList 添加当前点击时刻
if (_lastPressedAt != null && (now.difference(_lastPressedAt) < widget.interval)) {
tapTimeList.add(now);
$warn('再按 ${widget.neededNum - tapTimeList.length}次');
} else {
// 两次点击间隔超过 时长限制,重新计时
print('超过 时长限制');
tapTimeList.clear();
tapTimeList.add(now);
}

print(tapTimeList);
print('---------');
}

到这一步我们已经可以实现连续点击,超时重置.

然后加一下外部传入点击回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef OnTapCallBack = void Function(int tapNum, int neededNum);

class Egg extends StatefulWidget {

...

final OnTapCallBack onTrigger;
final OnTapCallBack onTap;

Egg({

...

this.onTrigger,
this.onTap,
});

@override
_EggState createState() => _EggState();
}

完善点击和触发彩蛋的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  handleOnTap() {
DateTime lastPressedAt = tapTimeList.length > 0 ? tapTimeList.last : null;
DateTime now = DateTime.now();

// 不超过点击间隔,tapTimeList 添加当前点击时刻
if (lastPressedAt != null && (now.difference(lastPressedAt) < widget.interval)) {
tapTimeList.add(now);
// $warn('再按 ${widget.neededNum - tapTimeList.length}次');

// 到达条件,触发隐藏功能
if (tapTimeList.length >= widget.neededNum) {
if (widget.onTrigger != null) {
widget.onTrigger(tapTimeList.length, widget.neededNum);
}
// 清空记录点击列表
tapTimeList.clear();
}
} else {
// 两次点击间隔超过 时长限制,重新计时
tapTimeList.clear();
tapTimeList.add(now);
}

// 每次都触发的 tap 事件
if (widget.onTap != null) {
widget.onTap(tapTimeList.length, widget.neededNum);
}
}

这样一个朴实无华的彩蛋组件就完成了

消息列表向上滚动加载

效果

客服系统的聊天列表,需求是向上滚动加载更多,直到没有消息.先看效果:

监听滚动

在消息容器上添加监听滚动,距离顶部 200px 就触发加载.这里注意要去抖,防止频繁触发导致浏览器卡顿

1
2
3
4
5
6
7
8
9
10
11
this.$refs.chatWrapper.addEventListener("scroll", debounce(this.handleScroll))

handleScroll() {
// 消息数过少不触发
if (this.chatList.length <= 5) return
let scrollPosition = this.$refs.chatWrapper.scrollTop
if (scrollPosition < 200) {
log("滚动距离: " + scrollPosition + ",触发加载更多聊天记录")
this.queryChatToChatList(this.activeContactUUid, 20, this.nextPage)
}
}

加载更多

聊天消息列表是一个数组,所有内容用v-for输出.添加内容只要往数组头部 concat 即可

1
2
3
4
5
6
<div v-for="(chatItem,idx) in chatList "
:class="['msg_item',chatItem.isMeSend?'my_msg':'you_msg']"
:key="idx"
>
<!--聊天项代码-->
</div>

保存原来位置

如果直接把新内容添加到数组头部,我们的滚动距离仍然在消息容器的顶部,这样鼠标稍微移动就会再次触发加载

所以我们要保存原来的位置,在消息记录渲染出来后跳到原来的位置

1
2
3
4
5
6
7
8
9
10
// scrollHeight - scrollTop 为聊天列表需要保留的高度
this.readHeight = this.$refs.chatWrapper.scrollHeight - this.$refs.chatWrapper.scrollTop

// watch 消息数组
// 消息窗口自动滚到底部
this.$nextTick(() => {
// 跳转到上次阅读的高度
this.$refs.chatWrapper.scrollTop = this.$refs.chatWrapper.scrollHeight - this.readHeight
this.readHeight = 0
})

scrollHeight - scrollTop 为聊天列表需要保留的高度,在watch里监听数组变化,等到数组渲染成具体的dom,在$nextTick里把容器滚回原来的位置.由于速度很快用户无法察觉列表已经从顶部闪现回来

hexo 引入图片问题

未开启 post_asset_folder,引用 /images
图片测试

开启,用标签插件而不是 markdown :

开启,用 md 语法相对路径
图片测试

开启,用 md 语法绝对路径
图片测试

引用图片,这个目前是最完美的在主页和 Archives 都能用

1
{% img [class names] /path/to/image [width] [height] [title text [alt text]] %}

github page 解析到自己的域名

在 github setting 设置 Custom domain 为 blog.en20.ga

先在域名服务商的 DNS 设置 A 记录指向github 官方设置列出的 IP,下面这些是我的:

1
2
3
4
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153

再添加 BLOGCNAME 指向 tyrone2333.github.io/

CNAME

但是完成后点击 Tyrone2333.github.io 跳到 http://www.en20.ga/ 显示404

只能从 blog.en20.ga 打开博客