first commit

This commit is contained in:
chorblack
2025-04-22 21:00:46 +08:00
commit 0b54051613
19 changed files with 1199 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

14
app.ux Normal file
View File

@@ -0,0 +1,14 @@
<script>
/**
* 应用级别的配置,供所有页面公用
*/
import brightness from '@blueos.hardware.display.brightness';
export default {
onCreate() { },
onDestroy() {
brightness.setKeepScreenOn({
keepScreenOn: false,
})
},
}
</script>

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/images/.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,5 @@
@mixin flex-box-mixins($direction: row, $justify: center, $align-items: center) {
flex-direction: $direction;
justify-content: $justify;
align-items: $align-items;
}

2
assets/styles/style.scss Normal file
View File

@@ -0,0 +1,2 @@
@import './variables.scss';
@import './mixins.scss';

View File

@@ -0,0 +1,9 @@
$brand: #09ba07;
$white: #ffffff;
$black: #000000;
$grey: #9393aa;
$red: #fa0101;
$green: #ffff00;
$size-factor: 5px;

BIN
common/ATRI_TrueEnding.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
common/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
common/ev000b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
common/text_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

58
manifest.json Normal file
View File

@@ -0,0 +1,58 @@
{
"package": "top.chorblack.atri",
"name": "ATRI",
"versionName": "1.0.1",
"versionCode": 1,
"appCategory": [
"other"
],
"icon": "/assets/images/logo.png",
"features": [
{
"name": "blueos.app.appmanager.router"
},
{
"name": "blueos.storage.storage"
},
{
"name": "blueos.window.prompt"
},
{
"name": "blueos.storage.file"
},
{
"name": "blueos.network.fetch"
},
{ "name": "blueos.hardware.display.brightness" }
],
"deviceTypeList": [
"watch",
"watch-square"
],
"config": {
"designWidth": 390
},
"router": {
"entry": "pages/index",
"pages": {
"pages/index": {
"component": "index"
},
"pages/detail": {
"component": "index"
},
"pages/settings": {
"component": "index"
},
"pages/list": {
"component": "index"
},
"pages/recovery": {
"component": "index"
}
}
},
"display": {
"backgroundColor": "#ffffff"
}
}

BIN
pages/.DS_Store vendored Normal file

Binary file not shown.

409
pages/detail/index.ux Normal file
View File

@@ -0,0 +1,409 @@
<template>
<div class="page" @swipe="back" @click="nextDialogue">
<image src="internal://files/{{Img}}"></image>
<image style="position: absolute;top: 300px;left: 0;" src="/common/text_bg.png" if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}"></image>
<text style="position: absolute;height: 50px;top: 250px;left: 8px;font-size: 28px;color: #FFFFFF;font-weight: bold" if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}">{{character}}</text>
<scroll scroll-y="true" bounces="true" class="scroll" id="scroll" if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}">
<text style="color: #FFFFFF;font-weight: bold;width: 100%;text-align: left;font-size: {{settings.textSize}}px;">{{showText}}</text>
</scroll>
<div class="page" style="background-color: #000000;" @click="nextDialogue">
</div>
<!--选项页-->
<div class="page" style="position: absolute;" if="{{gameData.scenes[currentScene].choices !== undefined}}">
<!--选项1-->
<text class="choice" @click="selectChoice(0)">{{gameData.scenes[currentScene].choices[0].text}}</text>
<!--选项2-->
<text class="choice" style="top: 210px;" @click="selectChoice(1)">{{gameData.scenes[currentScene].choices[1].text}}</text>
</div>
<!--菜单页-->
<div class="page" style="position: absolute;flex-wrap: nowrap;flex-direction: column;justify-content: center;align-items: center;background-color: #ffffff;" if="{{menu}}">
<text class="menu-btn" @click="toRecoveryPage(1)">保存</text>
<text class="menu-btn" @click="toRecoveryPage(2)">加载</text>
<text class="menu-btn" @click="skipScene(1)">跳过场景</text>
<text class="menu-btn" @click="skipChapter(chapter+1)">跳过章节</text>
<text class="menu-btn" @click="back('m')">返回</text>
</div>
<div class="page" style="position: absolute;background-color: #ffffff;" if="{{recovery===1}}" @swipe="back()">
<scroll scroll-y="true" bounces="true" class="scroll1 page">
<text class="menu-btn">长按删除存档</text>
<text class="menu-btn">点击存档覆盖</text>
<text class="menu-btn" for="{{recoveryData}}" style="font-size: 30px;" @click="saveRecoveryData($idx)" @longpress="deleteRecoveryData($idx)">存档{{$idx+1}}</text>
<text class="menu-btn" @click="saveRecoveryData('new')">+</text>
</scroll>
</div>
<div class="page" style="position: absolute;background-color: #ffffff;" if="{{recovery===2}}" @swipe="back()">
<scroll scroll-y="true" bounces="true" class="scroll1 page">
<text class="menu-btn">点击读取存档</text>
<text class="menu-btn" for="{{recoveryData}}" style="font-size: 30px;" @click="loadRecoveryData($idx)" @longpress="consoleData($idx)">存档{{$idx+1}}</text>
</scroll>
</div>
<div class="page" style="position: absolute;background-color: #ffffff;flex-wrap: nowrap;flex-direction: column;align-items: center;justify-content: center;" if="{{END != ''}}" @swipe="back()">
<text style="font-size: 30px;text-align: center;color: #000000;">达成结局:{{END}}</text>
<text style="font-size: 30px;text-align: center;color: #000000;" @click="back('e')">返回主页</text>
</div>
</div>
</template>
<script>
import router from '@blueos.app.appmanager.router';
import storage from '@blueos.storage.storage';
import prompt from '@blueos.window.prompt';
import file from '@blueos.storage.file';
let t1;
export default {
data: {
gameData: {
scenes: [
]
},
index: 0,
canContinue: true,
currentScene: 0,
currentDialogue: 0,
Img: 'bg.png',
showText: '',
character: '',
settings: {
textSpeed: 40,
textSize: 22
},
chapter: 0,
menu: false,
recovery: 0,
choice: [],
recoveryData: [],
load: null,
END: '',
jsonDataList: [
'b999.json', 'b101.json', 'b102.json', 'b103.json', 'b111.json', 'b112.json', 'b113.json', 'b114.json',
'b121.json', 'b122.json', 'b123.json', 'b124.json', 'b200.json', 'b201.json', 'b202.json', 'b203.json',
'b204.json', 'b205.json', 'b206.json', 'b207.json', 'b301.json', 'b302.json', 'b303.json', 'b304.json',
'b401.json', 'b402.json', 'b403.json', 'b404.json', 'b405.json', 'b406.json', 'b407.json', 'b501.json',
'b601.json', 'b701.json'
],
},
onInit(){
//
router.clear();
storage.get({
key: 'recoveryData',
success: (data) => {
if(data){
this.recoveryData = JSON.parse(data);
if(this.load){
if(this.load === 'TE'){
this.loadData("TE");
this.loadScene(this.currentScene);
}
else{this.loadRecoveryData(this.load)}
}
else{
this.loadData(this.chapter);
this.loadScene(this.currentScene);
}
}else{
this.loadData(this.chapter);
this.loadScene(this.currentScene);
}
},
fail:()=>{},
});
storage.get({
key: 'settings',
success: (data) => {
if(data){
this.settings = JSON.parse(data);
}
},
fail:()=>{},
});
},
async loadData(chapter){
let num;
if (chapter == "BE") {
num = 'b601.json';
} else if (chapter == "TE") {
num = 'b701.json';
} else {
num = this.jsonDataList[chapter];
}
console.log(num);
await file.readText({
uri: `internal://files/${num}`,
success: (data) =>{
this.gameData.scenes = JSON.parse(data.text);
//storage.getSync({ key: 'data' });
},
fail: function (_, code) {
prompt.showToast({message: code.toString()});
},
})
},
// 显示背景图
showBackground(image) {
this.Img = image;
},
// 显示对话
showDialogue(dialogue) {
this.showText = '';
this.character = dialogue.character;
this.canContinue = false;
this.index = 0;
this.zhuzi(dialogue.text);
},
zhuzi(text){
if (this.index < text.length){
this.showText += text.charAt(this.index);
this.index++;
t1 = setTimeout(() => {this.zhuzi(text);}, this.settings.textSpeed);
}
else{this.canContinue=true;}
},
onDestroy() {
// 解除内存占用
clearTimeout(t1);
},
// 加载场景
loadScene(sceneIndex) {
const scene = this.gameData.scenes[sceneIndex];
this.showBackground(scene.background);
this.currentDialogue = 0;
if(scene.choices){return}
this.showDialogue(scene.dialogues[this.currentDialogue]);
},
// 下一段对话
nextDialogue() {
if (this.canContinue) {
this.scrollToTop();//避免显示bug
this.canContinue = false;
const scene = this.gameData.scenes[this.currentScene];
if (this.currentDialogue < scene.dialogues.length - 1) {
this.currentDialogue++;
this.showDialogue(scene.dialogues[this.currentDialogue]);
} else if (this.currentScene < this.gameData.scenes.length - 1) {
if(scene.dialogues[this.currentDialogue].toScenes !== undefined){
console.log('跳转场景[选项]')
this.currentScene += scene.dialogues[this.currentDialogue].toScenes;
this.loadScene(this.currentScene);
}else{
console.log('跳转场景')
this.currentScene++;
this.loadScene(this.currentScene);
}
} else {
if(scene.dialogues[this.currentDialogue].END !== undefined){
this.END = scene.dialogues[this.currentDialogue].END;
this.getFin(this.END);
// 分支
}else if(scene.dialogues[this.currentDialogue].branch !== undefined){
console.log(this.choice)
console.log(scene.dialogues[this.currentDialogue].branch.choices)
if(JSON.stringify(this.choice)===JSON.stringify(scene.dialogues[this.currentDialogue].branch.choices)){
console.log('跳转章节[HE]')
this.chapter = scene.dialogues[this.currentDialogue].branch.toChapter;
this.loadData(this.chapter);
this.currentScene = 0;
this.currentDialogue = 0;
this.loadScene(this.currentScene);
}
else{
console.log('跳转章节[BE]')
this.chapter = "BE";
this.loadData(this.chapter);
this.currentScene = 0;
this.currentDialogue = 0;
this.loadScene(this.currentScene);
}
}else{
this.Img = 'bg.png';
setTimeout(() => {
this.chapter++;
this.loadData(this.chapter);
this.currentScene = 0;
this.currentDialogue = 0;
this.loadScene(this.currentScene);
}, 3000);
}
}
}
},
back(a){
if(a=='m'&&this.menu){this.menu = false}
else if(a.direction=='right'&&this.recovery!==0){this.recovery = 0}
else if(a.direction=='right'||a=='e'){router.replace({uri: "/pages/index"})}
else if(a.direction=='left'){this.menu = true}
},
// 选择选项
selectChoice(choiceIndex) {
console.log('选择选项', choiceIndex)
this.choice.push(choiceIndex);
console.log(this.choice)
const nextSceneIndex = this.gameData.scenes[this.currentScene].choices[choiceIndex].nextScene;
this.currentScene += nextSceneIndex;
this.loadScene(this.currentScene);
},
toRecoveryPage(a){
this.recovery = a;
},
saveRecoveryData(idx){
const data = {
chapter: this.chapter,
currentScene: this.currentScene,
currentDialogue: this.currentDialogue,
choice: this.choice,
}
if(idx === 'new'){
this.recoveryData.push(data);
}else{
this.recoveryData[idx] = data;
}
this.saveData()
prompt.showToast({
message:"存档成功"
})
},
deleteRecoveryData(idx){
this.recoveryData.splice(idx, 1);
this.saveData()
prompt.showToast({message: '删除成功'})
},
loadRecoveryData(idx){
const data = this.recoveryData[parseInt(idx)];
console.log('加载存档', data)
this.chapter = data.chapter;
this.currentScene = data.currentScene;
this.currentDialogue = data.currentDialogue;
this.choice = data.choice;
this.recovery = 0;
this.menu = false;
this.loadData(this.chapter);
this.loadScene(this.currentScene);
},
skipScene(a){
if(this.gameData.scenes[this.currentScene].dialogues[this.gameData.scenes[this.currentScene].dialogues.length-1].toScenes ==undefined && this.gameData.scenes[this.currentScene].choices==undefined && this.gameData.scenes[this.currentScene].dialogues[this.gameData.scenes[this.currentScene].dialogues.length-1].END==undefined && this.gameData.scenes[this.currentScene].dialogues[this.gameData.scenes[this.currentScene].dialogues.length-1].branch==undefined&&this.currentScene+a<this.gameData.scenes.length){
this.currentScene+=a;
this.loadScene(this.currentScene);
this.menu = false;
}else{
this.menu = false;
prompt.showToast({message: '无法跳过'})
}
},
skipChapter(a){
this.Img = 'bg.png';
this.menu = false;
setTimeout(() => {
this.chapter=a;
this.loadData(this.chapter);
this.currentScene = 0;
this.currentDialogue = 0;
this.loadScene(this.currentScene);
}, 3000);
},
saveData(){
storage.set({
key: 'recoveryData',
value: JSON.stringify(this.recoveryData),
success: () => {},
fail:()=>{},
})
},
getFin(a){
let fin = {};
storage.get({
key: 'fin',
success: (data) => {
if(data){
fin = JSON.parse(data);
}else{
fin = {"HE": false, "BE": false}
}
if(a=="Happy Ending"){
fin.HE = true;
}else if(a=="Bad Ending"){
fin.BE = true;
}
this.saveFin(fin);
},
fail:()=>{},
});
},
saveFin(a){
storage.set({
key: 'fin',
value: JSON.stringify(a),
success: () => {},
fail:()=>{},
})
},
consoleData(idx){
console.log('存档数据', this.recoveryData[idx])
},
scrollToTop() {
this.$element('scroll').scrollTo({
top: 0,
left: 0,
behavior: 'instant'
})
},
}
</script>
<style>
.page {
width: 390px;
height: 450px;
}
.scroll{
position: absolute;
bottom: 0;
top: 300px;
left: 8px;
right: 8px;
width: 390px;
height: 155px;
text-overflow: ellipsis;
flex-wrap: wrap;
}
.scroll1{
position: absolute;
bottom: 0;
top: 0;
left: 0;
right: 0;
text-overflow: ellipsis;
flex-wrap: nowrap;
flex-direction: column;
align-items: center;
}
.choice {
position: absolute;
width: 250px;
height: 61px;
left: 43px;
top: 100px;
background-color: rgba(80, 192, 231, 0.7);
color: #ffffff;
font-size: 24px;
font-weight: bold;
text-align: center;
}
.menu-btn {
width: 250px;
height: 61px;
background-color: rgba(80, 192, 231, 0.7);
color: #ffffff;
font-size: 24px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
</style>

271
pages/index/index.ux Normal file
View File

@@ -0,0 +1,271 @@
<template>
<div class="page" @swipe="ban">
<image src="/common/bg.png"></image>
<image
style="position: absolute;top: 0;left: 0;"
if="{{trueEnd}}"
src="/common/ATRI_TrueEnding.png"
></image>
<text
class="btn"
style="top: 150px;"
if="{{trueEnd}}"
@click="loadRecoveryData('TE')"
>TRUE END</text
>
<text class="btn" style="top: 200px;" @click="toPage('detail')">START</text>
<text class="btn" style="top: 250px;" @click="toRecovery()">LOAD</text>
<text class="btn" style="top: 300px;" @click="toSettings()">SYSTEM</text>
<text class="btn" style="top: 350px;" @click="exit">EXIT</text>
<div
class="page"
style="position: absolute;background-color: #ffffff;"
if="{{recovery}}"
@swipe="back()"
>
<scroll scroll-y="true" bounces="true" class="scroll1 page">
<text
class="menu-btn"
for="{{recoveryData}}"
style="font-size: 30px;"
@click="loadRecoveryData($idx)"
>存档{{ $idx + 1 }}</text
>
</scroll>
</div>
<div
class="page"
style="position: absolute;background-color: #ffffff;flex-wrap: nowrap;flex-direction: column;align-items: center;justify-content: center;"
if="{{tips}}"
@swipe="ban()"
>
<text class="font24">在"SYSTEM"中调整显示速度和文字大小</text>
<text class="font24">游戏中左滑进入菜单,右滑返回</text>
<text class="font24" style="color: #ff0000;"
>请先到SYSTEM界面下载文本和图像资源</text
>
<text class="font24">---------------</text>
<text class="font24">移植:@chorblack</text>
<text class="font24">感谢:@Wxz226@liuyuze61</text>
<text class="font24">---------------</text>
<text class="font24" style="color: #00a2ff;" @click="closeTips()"
>确定</text
>
</div>
</div>
</template>
<script>
import router from '@blueos.app.appmanager.router';
import storage from '@blueos.storage.storage';
import prompt from '@blueos.window.prompt';
export default {
data: {
recovery: false,
recoveryData: [],
settingsPage: false,
settings: {
textSpeed: 40,
textSize: 22
},
showText: '',
index: 0,
tips: false,
trueEnd: false,
},
onInit() {
storage.get({
key: 'recoveryData',
success: (data) => {
if (data) {
this.recoveryData = JSON.parse(data);
}
},
fail: () => { },
});
storage.get({
key: 'settings',
success: (data) => {
if (data) {
this.settings = JSON.parse(data);
}
},
fail: () => { },
});
storage.get({
key: 'tips',
success: (data) => {
if (data) {
if (JSON.parse(data) !== 61) {
this.tips = true;
}
} else {
this.tips = true;
}
},
fail: () => { },
});
storage.get({
key: 'fin',
success: (data) => {
if (data) {
const fin = JSON.parse(data);
console.log(fin)
if (fin.HE === true && fin.BE === true) { this.trueEnd = true }
}
},
fail: () => { },
});
},
toPage(page) {
router.push({ uri: `pages/${page}` })
},
exit() {
this.$app.exit()
},
ban() {
console.log('ban')
},
toRecovery() {
if (this.recoveryData.length > 0) {
router.push({
uri: `pages/recovery`,
})
this.recovery = true
}
else {
prompt.showToast({
message: "无存档"
})
}
},
toSettings() {
router.replace({
uri: 'pages/settings'
})
//this.settingsPage = true;
//this.zhuzi();
},
back(a) {
if (a.direction == 'right' && this.recovery) { this.recovery = false }
else if (this.settingsPage) { this.settingsPage = false }
},
loadRecoveryData(idx) {
router.push({
uri: `pages/detail`,
params: {
load: idx
}
})
},
changeTextSize(e) {
this.settings.textSize = e.progress;
},
changeTextSpeed(e) {
this.settings.textSpeed = e.progress;
},
zhuzi() {
const text = `Atri -My Dear Moments-\n文字显示样本`
if (this.index < text.length) {
this.showText += text.charAt(this.index);
this.index++;
setTimeout(() => { this.zhuzi() }, this.settings.textSpeed)
}
else {
if (this.settingsPage) {
setTimeout(() => {
this.index = 0;
this.showText = '';
this.zhuzi()
}, 2000);
}
}
},
saveSettings() {
storage.set({
key: 'settings',
value: JSON.stringify(this.settings),
success: () => { prompt.showToast({ message: '保存成功' }) },
fail: () => { },
})
},
closeTips() {
this.tips = false;
storage.set({
key: 'tips',
value: JSON.stringify(61),
success: () => { },
fail: () => { },
})
},
}
</script>
<style>
.page {
width: 390px;
height: 450px;
}
.btn {
position: absolute;
font-size: 36px;
left: 32px;
height: 50px; /* 新增高度限制 */
font-weight: bold;
color: #0a55bc;
}
.scroll1 {
position: absolute;
bottom: 0;
top: 0;
left: 0;
right: 0;
text-overflow: ellipsis;
flex-wrap: nowrap;
flex-direction: column;
align-items: center;
}
.menu-btn {
width: 250px;
height: 61px;
background-color: rgba(80, 192, 231, 0.7);
color: #ffffff;
font-size: 24px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
.scroll {
position: absolute;
bottom: 0;
top: 325px;
left: 8px;
right: 0;
width: 328px;
height: 155px;
text-overflow: ellipsis;
}
.slider {
position: absolute;
width: 230px;
top: 125px;
left: 53px;
}
.text {
position: absolute;
font-size: 24px;
color: #ffffff;
top: 71px;
left: 18px;
font-weight: bold;
}
.font24 {
font-size: 23px;
color: #000000;
font-weight: bold;
text-align: center;
}
</style>

54
pages/list/index.ux Normal file
View File

@@ -0,0 +1,54 @@
<template>
<div class="wrapper">
<list class="list" bounces="false">
<list-item type="ceiling">
<text class="title">文件总数{{ fileList.length }}</text>
</list-item>
<list-item type="item" for="{{ fileList }}">
<text class="text">{{ $item.uri.split('/').pop() }}</text>
</list-item>
</list>
</div>
</template>
<script>
import file from '@blueos.storage.file'
export default {
data: {
fileList:null
},
onInit() {
file.list({
uri: 'internal://files/',
success: (data) => {
this.fileList = data.fileList;
console.log(data.fileList);
}
})
},
}
</script>
<style>
.wrapper {
flex-direction: column;
}
.title,
.text {
height: 180px;
width: 400px;
text-align: center;
font-size: 40px;
background-color: #203a43;
color: #ffffff;
border-bottom: 1px solid #2c5364;
}
.title {
background-color: #0f2027;
}
.ceiling {
position: fixed;
top: 0;
left: 0;
}
</style>

75
pages/recovery/index.ux Normal file
View File

@@ -0,0 +1,75 @@
<template>
<div class="page" style="position: absolute;background-color: #ffffff;">
<scroll scroll-y="true" bounces="true" class="scroll1 page">
<text
class="menu-btn"
for="{{recoveryData}}"
style="font-size: 30px;"
@click="loadRecoveryData($idx)"
>存档{{ $idx + 1 }}</text
>
</scroll>
</div>
</template>
<script>
import router from '@blueos.app.appmanager.router';
import storage from '@blueos.storage.storage';
export default {
data: {
recovery: false,
recoveryData: [],
},
onInit() {
storage.get({
key: 'recoveryData',
success: (data) => {
if (data) {
this.recoveryData = JSON.parse(data);
}
},
fail: () => { },
});
},
ban() {
console.log('ban');
},
loadRecoveryData(idx) {
router.replace({
uri: `pages/detail`,
params: {
load: idx
}
})
}
}
</script>
<style>
.page {
width: 390px;
height: 450px;
}
.scroll1 {
position: absolute;
bottom: 0;
top: 0;
left: 0;
right: 0;
text-overflow: ellipsis;
flex-wrap: nowrap;
flex-direction: column;
align-items: center;
}
.menu-btn {
width: 250px;
height: 61px;
background-color: rgba(80, 192, 231, 0.7);
color: #ffffff;
font-size: 24px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
</style>

302
pages/settings/index.ux Normal file
View File

@@ -0,0 +1,302 @@
<template>
<div class="page" @swipe="ban()">
<image src="/common/ev000b.png"></image>
<image
style="position: absolute;top: 325px;left: 0;"
src="/common/text_bg.png"
></image>
<text class="text">显示速度({{ settings.textSpeed }})</text>
<slider
class="slider"
min="20"
max="60"
step="1"
onchange="changeTextSpeed()"
></slider>
<text class="text" style="top: 163px"
>文字大小({{ settings.textSize }})</text
>
<slider
class="slider"
style="top: 210px"
min="20"
max="32"
step="1"
onchange="changeTextSize()"
></slider>
<text class="text" style="top: 15px;left: 60px;" @click="saveSettings()"
>保存</text
>
<text class="text" style="top: 15px;left: 175px;" @click="back()"
>退出</text
>
<text class="text" style="top: 15px;left: 280px;" @click="gotolist()"
>去目录</text
>
<text
class="text"
style="top: 250px;left:40px;color:red;"
onclick="downloadFile(jsonDataList)"
>下载文本</text
>
<text
class="text"
style="top: 250px;left:250px;color:red;"
onclick="downloadFile(jsonList)"
>下载图像</text
>
<scroll scroll-y="true" bounces="true" class="scroll">
<text
style="color: #FFFFFF;font-weight: bold;width: 100%;text-align: left;font-size: {{settings.textSize}}px;"
>{{ showText }}</text
>
</scroll>
</div>
</template>
<script>
import storage from '@blueos.storage.storage';
import prompt from '@blueos.window.prompt';
import router from '@blueos.app.appmanager.router';
import file from '@blueos.storage.file';
import fetch from '@blueos.network.fetch';
import brightness from '@blueos.hardware.display.brightness';
var send = async (url, data, method = 'GET', responseType = 'text') => {
console.log('send', url, method, responseType);
return new Promise((resolve, reject) => {
fetch.fetch({
url: url,
data: method === 'GET' ? data : JSON.stringify(data),
method,
responseType,
success: function (response) {
console.log(`the status code of the response: ${response.code}`)
resolve(response.data);
},
fail: function (data, code) {
console.log(`${url} handling fail, errMsg = ${data}`);
console.log(`handling fail, errCode = ${code}`)
reject(data);
}
});
});
};
let t1, t2;
export default {
data: {
recovery: false,
settingsPage: true,
settings: {
textSpeed: 40,
textSize: 22
},
showText: '',
index: 0,
tips: false,
trueEnd: false,
jsonList: ['ATd1p1f1.png', 'ATRI_TrueEnding.png', 'bg.png', 'bg001.png', 'bg001d.png', 'bg001de.png', 'bg001e.png', 'bg001n.png', 'bg001y.png', 'bg002.png', 'bg002n2.png', 'bg003a.png', 'bg003an.png', 'bg004.png', 'bg004n2.png', 'bg005.png', 'bg005a.png', 'bg005n2.png', 'bg006.png', 'bg007.png', 'bg007c.png', 'bg007n.png', 'bg008.png', 'bg009.png', 'bg009e.png', 'bg009n.png', 'bg010.png', 'bg011a.png', 'bg011e.png', 'bg012.png', 'bg013.png', 'bg014a.png', 'bg015.png', 'bg015c.png', 'bg015n.png', 'bg015t.png', 'bg016a.png', 'bg017a.png', 'bg017b.png', 'bg017c.png', 'bg017n.png', 'bg017z.png', 'ev000b.png', 'ev001a.png', 'ev002b.png', 'ev003a.png', 'ev003b.png', 'ev003d.png', 'ev003f.png', 'ev004a.png', 'ev005a.png', 'ev006a.png', 'ev007a.png', 'ev008c.png', 'ev009a.png', 'ev010b.png', 'ev011c.png', 'ev012c.png', 'ev013a.png', 'ev014b.png', 'ev015a.png', 'ev016a.png', 'ev017a.png', 'ev018a.png', 'ev019a.png', 'ev020a.png', 'ev021a.png', 'ev101a.png', 'ev102a.png', 'ev103a.png', 'hurt.png', 'item020a.png', 'item028.png', 'item032a_0.png', 'item033b.png', 'item039b.png', 'item059b.png', 'item069a.png', 'item069b.png', 'item091a.png', 'item099.png', 'itemATRI.png', 'mask_dageki02ji.png', 'mask_yuge.png', 'none.png', 'none1.png', 'none2.png', 'sd004a.png', 'sd005a.png'],
fileList: null,
jsonDataList: [
'b999.json', 'b101.json', 'b102.json', 'b103.json', 'b111.json', 'b112.json', 'b113.json', 'b114.json',
'b121.json', 'b122.json', 'b123.json', 'b124.json', 'b200.json', 'b201.json', 'b202.json', 'b203.json',
'b204.json', 'b205.json', 'b206.json', 'b207.json', 'b301.json', 'b302.json', 'b303.json', 'b304.json',
'b401.json', 'b402.json', 'b403.json', 'b404.json', 'b405.json', 'b406.json', 'b407.json', 'b501.json',
'b601.json', 'b701.json'
]
,
missingFiles: []
},
async downloadJson(name) {
var cb;
var p = new Promise(resolve => cb = resolve);
// let byteSize = await send(`/photobyte/${id}`, null, 'GET', 'json')
await send(`http://download.chorblack.top/pd/local/atri/${name}`, null, 'GET', 'json').then(res => {
cb(res);
file.writeText({
uri: `internal://files/${name}`,
text: JSON.stringify(res),
success: function () {
},
fail: function (_, code) {
prompt.showToast({
message: `下载失败:${code}`
})
}
});
});
return await p;
},
async getFile(fileName) {
return new Promise((resolve, reject) => {
file.get({
uri: `internal://files/${fileName}`,
success: () => {
resolve(true);
},
fail: (_, code) => {
reject(`handling fail, code = ${code}`);
},
});
});
},
async downloadFile(data) {
prompt.showToast({ message: "开始下载" });
//await this.downloadJson('b999.json');
for (let i = 0; i < data.length; i++) {
const fileName = data[i];
let isInFile = false;
try {
isInFile = await this.getFile(fileName);
} catch (error) {
console.log(error);
}
if (!isInFile) {
try {
if (fileName.includes('.json')) {
await this.downloadJson(fileName);
} else {
await this.downloadPhoto(fileName);
}
prompt.showToast({
message: `还剩${data.length - i - 1}`
})
} catch (error) {
console.error(`下载失败: ${fileName}`, error);
}
}
}
prompt.showToast({
message: `下载完成`
})
},
async downloadPhoto(name) {
var cb;
var p = new Promise(resolve => cb = resolve);
// let byteSize = await send(`/photobyte/${id}`, null, 'GET', 'json')
await send(`http://download.chorblack.top/pd/local/atri/${name}`, null, 'GET', 'arraybuffer').then(res => {
if (res.byteLength === 0) {
throw new Error('empty image');
}
cb(res);
file.writeArrayBuffer({
uri: `internal://files/${name}`,
buffer: new Uint8Array(res),
success: function () {
},
fail: function (_, code) {
prompt.showToast({
message: `下载失败:${code}`
})
}
});
});
return await p;
},
gotolist() {
router.push({
uri: '/pages/list',
})
},
onInit() {
brightness.setKeepScreenOn({
keepScreenOn: true,
});
storage.get({
key: 'settings',
success: (data) => {
if (data) {
this.settings = JSON.parse(data);
}
},
fail: () => { },
});
this.zhuzi();
},
zhuzi() {
const text = `Atri -My Dear Moments-\n文字显示样本`
if (this.index < text.length) {
this.showText += text.charAt(this.index);
this.index++;
t1 = setTimeout(() => { this.zhuzi() }, this.settings.textSpeed)
}
else {
if (this.settingsPage) {
t2 = setTimeout(() => {
this.index = 0;
this.showText = '';
this.zhuzi()
}, 2000);
}
}
},
onDestroy() {
// 解除内存占用
clearTimeout(t1)
clearInterval(t2)
},
exit() {
this.$app.exit()
},
ban() {
console.log('ban')
},
back() {
brightness.setKeepScreenOn({
keepScreenOn: false,
})
router.replace({ uri: `pages/index` })
},
changeTextSize(e) {
this.settings.textSize = e.progress;
},
changeTextSpeed(e) {
this.settings.textSpeed = e.progress;
},
saveSettings() {
storage.set({
key: 'settings',
value: JSON.stringify(this.settings),
success: () => { prompt.showToast({ message: '保存成功' }) },
fail: () => { },
})
},
}
</script>
<style>
.page {
width: 390px;
height: 450px;
}
.scroll {
position: absolute;
bottom: 0;
top: 325px;
left: 8px;
right: 0;
width: 390px;
height: 155px;
text-overflow: ellipsis;
}
.slider {
position: absolute;
width: 230px;
height: 50px; /* 新增高度限制 */
top: 125px;
left: 53px;
opacity: 0.5;
}
.text {
position: absolute;
font-size: 24px;
height: 50px; /* 新增高度限制 */
color: #ffffff;
top: 71px;
left: 18px;
font-weight: bold;
}
</style>