mirror of
https://gitee.com/openharmony/xts_tools
synced 2024-11-23 07:50:08 +00:00
!306 【Sample】仿应用参考示例-D
Merge pull request !306 from zhaoxin/appsample_d
This commit is contained in:
commit
fd2e5ed283
12
sample/AppSampleD/.gitignore
vendored
Normal file
12
sample/AppSampleD/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/local.properties
|
||||
/oh-package-lock.json5
|
||||
/.idea
|
||||
**/build
|
||||
/.hvigor
|
||||
.cxx
|
||||
/.clangd
|
||||
/.clang-format
|
||||
/.clang-tidy
|
||||
**/.test
|
24
sample/AppSampleD/AppScope/app.json5
Normal file
24
sample/AppSampleD/AppScope/app.json5
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"app": {
|
||||
"bundleName": "com.samples.appsampled",
|
||||
"vendor": "example",
|
||||
"versionCode": 1000000,
|
||||
"versionName": "1.0.0",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:app_name"
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "仿应用"
|
||||
}
|
||||
]
|
||||
}
|
BIN
sample/AppSampleD/AppScope/resources/base/media/app_icon.png
Normal file
BIN
sample/AppSampleD/AppScope/resources/base/media/app_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
122
sample/AppSampleD/README_zh.md
Normal file
122
sample/AppSampleD/README_zh.md
Normal file
@ -0,0 +1,122 @@
|
||||
# 仿应用示例
|
||||
|
||||
### 介绍
|
||||
|
||||
本示例主要展示了网络连接、文件上传、音视频播放等媒体方面的应用。
|
||||
|
||||
使用说明
|
||||
|
||||
1. 搭建服务器环境:https://help.jeecg.com/java/setup/tools.html 。
|
||||
|
||||
2. 启动服务器:[服务器前端目录](../../../../jeecgboot-vue3-master),[服务器后端目录](../../../../jeecg-boot-master)。
|
||||
|
||||
3. 打开应用,此时为仿应用主页,循环播放视频,可点击暂停或者播放。
|
||||
|
||||
4. 点击右上角**搜索图标**,可进入搜索页面,默认展示**综合类**结果页面,由于搜索历史记录及对应搜索结果都是静态模拟数据,所以可点击前三个任意一条记录以展示不同搜索结果,也可输入与前三条记录一致的结果以展示不同搜索结果。
|
||||
|
||||
5. 点击**头像**可播放音乐,下滑点击**播放**按钮可播放视频。
|
||||
|
||||
6. 点击**视频**展示**视频类**结果页面,点击左上角返回图标回到**首页**。
|
||||
|
||||
7. 点击首页**消息**进入好友列表,好友列表为模拟数据,只可点击第一位进入聊天页面。
|
||||
|
||||
8. 进入聊天页面,输入文字,点击**发送**图标可发送消息至好友,点击返回回到首页。
|
||||
|
||||
9. 点击首页**加号**图标进入**录制视频**页面,首先进行授权,每条权限等待上一条权限授权成功后再继续授权,点击**红色按钮**录制,等待若干秒后再次点击停止录制,点击**下一步**进入发布页面。
|
||||
|
||||
10. 在发布页面点击右下角**发布按钮**,则发布视频至服务端,发布成功后回到首页。
|
||||
|
||||
### 工程目录
|
||||
|
||||
```
|
||||
/Socket
|
||||
├── entry # 主entry模块目录
|
||||
│ └── src
|
||||
│ ├── main
|
||||
│ ├── ets # ets模块目录
|
||||
│ ├── components # 组件目录
|
||||
│ ├── ChatComponent.ets # 聊天
|
||||
│ ├── MessageComponent.ets # 首页中消息组件
|
||||
│ ├── SearchComponent.ets # 搜索
|
||||
│ ├── SearchPlayMusicComponent.ets # 搜索结果综合类音频
|
||||
│ ├── SearchPlayVideoComponent.ets # 搜索结果综合类视频
|
||||
│ ├── SearchResultComponent.ets # 搜索结果组件
|
||||
│ ├── SearchSynthesizeComponent.ets # 搜索结果综合类
|
||||
│ ├── SearchVideoComponent.ets # 搜索结果视频类
|
||||
│ ├── VideoComponent.ets # 首页中视频组件
|
||||
│ ├── controller
|
||||
│ ├── ChatController.ts # 负责聊天发送消息
|
||||
│ ├── LoginController.ts # 负责登录
|
||||
│ ├── UploadController.ts # 负责上传文件
|
||||
│ ├── entryability
|
||||
│ ├── appsampled
|
||||
│ ├── data # 实体类目录
|
||||
│ ├── ChatBox.ts # 消息信息实体
|
||||
│ ├── DataSource.ts # 数据源,懒加载使用
|
||||
│ ├── LoginResult.ts # 登录信息实体
|
||||
│ ├── R.ts # 返回结果信息实体
|
||||
│ ├── SearchResult.ts # 搜索结果信息实体
|
||||
│ ├── Tool.ts # 工具类实体
|
||||
│ ├── User.ts # 用户类实体
|
||||
│ ├── pages # 数据源实体
|
||||
│ ├── CameraPage.ets # 相机录制页面
|
||||
│ ├── ChatPage.ets # 聊天页面
|
||||
│ ├── Login.ets # 登录页面
|
||||
│ ├── PublishPage.ets # 发布页面
|
||||
│ ├── SearchPage.ets # 搜索页面
|
||||
│ ├── mock # 模拟数据
|
||||
│ ├── model
|
||||
│ ├── AVPlayerModel.ts # 负责音视频播放
|
||||
│ ├── CameraModel.ts # 负责相机预览和录制等管理
|
||||
│ ├── MediaModel.ts # 负责媒体查询等媒体文件操作
|
||||
│ ├── NetworkModel.ts # 负责网络通信等操作
|
||||
│ ├── pages
|
||||
│ ├── Index.ets # 首页
|
||||
│ ├── utils # 工具类目录
|
||||
```
|
||||
|
||||
### 具体实现
|
||||
|
||||
- 网络连接合请求:@ohos.net.http
|
||||
- 消息接收:@ohos.net.webSocket
|
||||
- 文件上传:@ohos.request
|
||||
- 文件操作:@ohos.multimedia.mediaLibrary
|
||||
- 音视频播放:@ohos.multimedia.media
|
||||
|
||||
### 相关权限
|
||||
|
||||
网络权限: ohos.permission.INTERNET
|
||||
相机权限: ohos.permission.CAMERA
|
||||
麦克风权限: ohos.permission.MICROPHONE
|
||||
媒体位置权限: ohos.permission.MEDIA_LOCATION
|
||||
媒体文件写入权限: ohos.permission.WRITE_MEDIA
|
||||
媒体文件读取权限: ohos.permission.READ_MEDIA
|
||||
|
||||
### 依赖
|
||||
|
||||
1. windows上启动服务器前端代码,模拟消息转发服务器[服务器前端目录](../../../../jeecgboot-vue3-master)
|
||||
2. windows上启动服务器后端代码,模拟消息转发服务器[服务器后端目录](../../../../jeecg-boot-master)
|
||||
|
||||
### 约束与限制
|
||||
|
||||
1. 本示例仅支持标准系统上运行,支持设备:RK3568。
|
||||
|
||||
2. 本示例为Stage模型,仅支持API10版本SDK,版本号:4.0.7.5,镜像版本号: OpenHarmony 4.0.7.5。
|
||||
|
||||
3. 本示例需要使用DevEco Studio 3.1 Release (Build Version: 3.1.0.500, built on April 28, 2023)才可编译运行。
|
||||
|
||||
4. 本示例在启动前需搭建服务端环境,需与客户端处于同一局域网,成功启动服务端后再运行客户端,服务端代码([服务器前端代码](../../../../jeecgboot-vue3-master),[服务器后端代码](../../../../jeecg-boot-master))。
|
||||
|
||||
5. 在进入录制页面授权时,在授权第三条权限之前等待若干秒,等待上一条权限授权成功后再继续授权,否则可能授权失败。
|
||||
|
||||
### 下载
|
||||
|
||||
如需单独下载本工程,执行如下命令:
|
||||
|
||||
```
|
||||
git init
|
||||
git config core.sparsecheckout true
|
||||
echo sample/AppSampleD/ > .git/info/sparse-checkout
|
||||
git remote add origin https://gitee.com/openharmony/xts_tools.git
|
||||
git pull origin master
|
||||
```
|
41
sample/AppSampleD/build-profile.json5
Normal file
41
sample/AppSampleD/build-profile.json5
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"app": {
|
||||
"signingConfigs": [],
|
||||
"compileSdkVersion": 11,
|
||||
"compatibleSdkVersion": 10,
|
||||
"products": [
|
||||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default"
|
||||
}
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "entry",
|
||||
"srcPath": "./entry",
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"applyToProducts": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
6
sample/AppSampleD/entry/.gitignore
vendored
Normal file
6
sample/AppSampleD/entry/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/.preview
|
||||
/build
|
||||
/.cxx
|
||||
/.test
|
28
sample/AppSampleD/entry/build-profile.json5
Normal file
28
sample/AppSampleD/entry/build-profile.json5
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"apiType": 'stageMode',
|
||||
"buildOption": {
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"runtimeOS": "OpenHarmony"
|
||||
},
|
||||
{
|
||||
"name": "ohosTest",
|
||||
}
|
||||
]
|
||||
}
|
2
sample/AppSampleD/entry/hvigorfile.ts
Normal file
2
sample/AppSampleD/entry/hvigorfile.ts
Normal file
@ -0,0 +1,2 @@
|
||||
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
|
||||
export { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
24
sample/AppSampleD/entry/oh-package.json5
Normal file
24
sample/AppSampleD/entry/oh-package.json5
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"license": "",
|
||||
"devDependencies": {},
|
||||
"author": "",
|
||||
"name": "entry",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class ChatBox {
|
||||
isSend: boolean;
|
||||
message: string;
|
||||
userIcon: Resource;
|
||||
|
||||
constructor(isSend: boolean, message: string, userIcon: Resource) {
|
||||
this.isSend = isSend;
|
||||
this.message = message;
|
||||
this.userIcon = userIcon;
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
import type { ChatBox } from './ChatBox';
|
||||
import Logger from '../../utils/Logger';
|
||||
|
||||
class BasicDataSource implements IDataSource {
|
||||
private listeners: DataChangeListener[] = [];
|
||||
|
||||
public totalCount(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public getData(index: number): ChatBox {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
Logger.info('add listener');
|
||||
this.listeners.push(listener);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
Logger.info('remove listener');
|
||||
this.listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataReload(): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener.onDataReloaded();
|
||||
});
|
||||
}
|
||||
|
||||
notifyDataAdd(index: number): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener.onDataAdd(index);
|
||||
});
|
||||
}
|
||||
|
||||
notifyDataChange(index: number): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener.onDataChange(index);
|
||||
});
|
||||
}
|
||||
|
||||
notifyDataDelete(index: number): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener.onDataDelete(index);
|
||||
});
|
||||
}
|
||||
|
||||
notifyDataMove(from: number, to: number): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener.onDataMove(from, to);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ChatSource extends BasicDataSource {
|
||||
private chatsArray: Array<ChatBox> = [];
|
||||
|
||||
public totalCount(): number {
|
||||
return this.chatsArray.length;
|
||||
}
|
||||
|
||||
public getData(index: number): ChatBox {
|
||||
return this.chatsArray[index];
|
||||
}
|
||||
|
||||
public addData(index: number, data: ChatBox): void {
|
||||
this.chatsArray.splice(index, 0, data);
|
||||
this.notifyDataAdd(index);
|
||||
}
|
||||
|
||||
public pushData(data: ChatBox): void {
|
||||
this.chatsArray.push(data);
|
||||
this.notifyDataAdd(this.chatsArray.length - 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default class LoginResult{
|
||||
private token: string;
|
||||
private id: string;
|
||||
private username: string;
|
||||
private realName: string;
|
||||
private avatar: string;
|
||||
|
||||
public getToken(): string{
|
||||
return this.token;
|
||||
}
|
||||
public setToken(token: string){
|
||||
this.token = token;
|
||||
}
|
||||
public getId(): string{
|
||||
return this.id;
|
||||
}
|
||||
public setId(id: string){
|
||||
this.id = id;
|
||||
}
|
||||
public getUsername(): string{
|
||||
return this.username;
|
||||
}
|
||||
public setUsername(username: string){
|
||||
this.username = username;
|
||||
}
|
||||
public getRealName(): string{
|
||||
return this.realName;
|
||||
}
|
||||
public setRealName(realName: string){
|
||||
this.realName = realName;
|
||||
}
|
||||
public getAvatar(): string{
|
||||
return this.avatar;
|
||||
}
|
||||
public setAvatar(avatar: string){
|
||||
this.avatar = avatar;
|
||||
}
|
||||
}
|
45
sample/AppSampleD/entry/src/main/ets/appsampled/data/R.ts
Normal file
45
sample/AppSampleD/entry/src/main/ets/appsampled/data/R.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default class R{
|
||||
private success: boolean;
|
||||
private message: string;
|
||||
private code: number;
|
||||
private data: any;
|
||||
|
||||
public getSuccess(): boolean{
|
||||
return this.success;
|
||||
}
|
||||
public setSuccess(success: boolean){
|
||||
this.success = success;
|
||||
}
|
||||
public getMessage(): string{
|
||||
return this.message;
|
||||
}
|
||||
public setMessage(message: string){
|
||||
this.message = message;
|
||||
}
|
||||
public getCode(): number{
|
||||
return this.code;
|
||||
}
|
||||
public setCode(code: number){
|
||||
this.code = code;
|
||||
}
|
||||
public getData(): any{
|
||||
return this.data;
|
||||
}
|
||||
public setData(data: any){
|
||||
this.data = data;
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 综合类下的音频信息
|
||||
*/
|
||||
export class AudioInfo{
|
||||
public audioId: number; // 音频ID
|
||||
public audioName: string; // 音频名称
|
||||
public audioIcon: Resource; // 音频图片
|
||||
public audioAuthorName: string; // 音频作者名称
|
||||
public audioTime: string; // 音频时间
|
||||
public audioNum: string; // 音频使用人数
|
||||
public audio: string; // 播放音频的文件名称
|
||||
|
||||
constructor(audioId?: number, audioName?: string, audioIcon?: Resource, audioAuthorName?: string, audioTime?: string, audioNum?: string, audio?: string) {
|
||||
this.audioId = audioId;
|
||||
this.audioName = audioName;
|
||||
this.audioIcon = audioIcon;
|
||||
this.audioAuthorName = audioAuthorName;
|
||||
this.audioTime = audioTime;
|
||||
this.audioNum = audioNum;
|
||||
this.audio = audio;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 综合类下的视频信息
|
||||
*/
|
||||
export class VideoDetailInfo{
|
||||
public videoDetailId: number; // 视频ID
|
||||
public videoDetailAuthorName: string; // 视频作者名称
|
||||
public videoDetailAuthorIcon: Resource; // 视频作者头像
|
||||
public videoDetailTime: string; // 视频发布时间
|
||||
public videoDetailTitle: string; // 视频标题
|
||||
public videoDetailLabel: string; // 视频标签
|
||||
public videoDetailLike: string; // 视频点赞数
|
||||
public videoDetailComment: string; // 视频评论数
|
||||
public videoDetailCollect: string; // 视频收藏数
|
||||
public videoDetailTransmit: string; // 视频评论数
|
||||
public videoDetail: string; // 播放视频的文件名称
|
||||
public commenterName: string; // 评论人名称
|
||||
public commenterIcon: Resource; // 评论人头像
|
||||
public commenterContent: string; // 评论内容
|
||||
public commenterLike: string; // 评论点赞数
|
||||
|
||||
constructor(videoDetailId?: number, videoDetailAuthorName?: string, videoDetailAuthorIcon?: Resource, videoDetailTime?: string, videoDetailTitle?: string, videoDetailLabel?: string,
|
||||
videoDetailLike?: string, videoDetailComment?: string, videoDetailCollect?: string, videoDetailTransmit?: string, videoDetail?: string,
|
||||
commenterName?: string, commenterIcon?: Resource, commenterContent?: string, commenterLike?: string) {
|
||||
this.videoDetailId = videoDetailId;
|
||||
this.videoDetailAuthorName = videoDetailAuthorName;
|
||||
this.videoDetailAuthorIcon = videoDetailAuthorIcon;
|
||||
this.videoDetailTime = videoDetailTime;
|
||||
this.videoDetailTitle = videoDetailTitle;
|
||||
this.videoDetailLabel = videoDetailLabel;
|
||||
this.videoDetailLike = videoDetailLike;
|
||||
this.videoDetailComment = videoDetailComment;
|
||||
this.videoDetailCollect = videoDetailCollect;
|
||||
this.videoDetailTransmit = videoDetailTransmit;
|
||||
this.videoDetail = videoDetail;
|
||||
this.commenterName = commenterName;
|
||||
this.commenterIcon = commenterIcon;
|
||||
this.commenterContent = commenterContent;
|
||||
this.commenterLike = commenterLike;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频类下的视频信息
|
||||
*/
|
||||
export class VideoInfo{
|
||||
public videoAuthorName: string; // 视频作者名称
|
||||
public videoAuthorIcon: Resource; // 视频作者头像
|
||||
public videoLikeNum: string; // 视频点赞数
|
||||
public videoTitle: string; // 视频标题
|
||||
public video: Resource; // 视频展示图片的文件名称
|
||||
|
||||
constructor(videoAuthorName?: string, videoAuthorIcon?: Resource, videoLikeNum?: string, videoTitle?: string, video?: Resource) {
|
||||
this.videoAuthorName = videoAuthorName;
|
||||
this.videoAuthorIcon = videoAuthorIcon;
|
||||
this.videoLikeNum = videoLikeNum;
|
||||
this.videoTitle = videoTitle;
|
||||
this.video = video;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 一条搜索的搜索结果模板
|
||||
*/
|
||||
export class SearchResult{
|
||||
public labelList: Array<string>;
|
||||
public audioInfoList: Array<AudioInfo>;
|
||||
public videoDetailInfo: Array<VideoDetailInfo>;
|
||||
public videoInfo: Array<VideoInfo>;
|
||||
|
||||
constructor(labelList?: Array<string>, audioInfoList?: Array<AudioInfo>, videoDetailInfo?: Array<VideoDetailInfo>, videoInfo?: Array<VideoInfo>) {
|
||||
this.labelList = labelList;
|
||||
this.audioInfoList = audioInfoList;
|
||||
this.videoDetailInfo = videoDetailInfo;
|
||||
this.videoInfo = videoInfo;
|
||||
}
|
||||
}
|
36
sample/AppSampleD/entry/src/main/ets/appsampled/data/Tool.ts
Normal file
36
sample/AppSampleD/entry/src/main/ets/appsampled/data/Tool.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default class Tool{
|
||||
private toolName: string;
|
||||
private toolIcon: Resource;
|
||||
|
||||
constructor(toolName?: string, toolIcon?: Resource) {
|
||||
this.toolName = toolName;
|
||||
this.toolIcon = toolIcon;
|
||||
}
|
||||
|
||||
public getToolName(): string{
|
||||
return this.toolName;
|
||||
}
|
||||
public setToolName(toolName: string){
|
||||
this.toolName = toolName;
|
||||
}
|
||||
public getToolIcon(): Resource{
|
||||
return this.toolIcon;
|
||||
}
|
||||
public setToolIcon(toolIcon: Resource){
|
||||
this.toolIcon = toolIcon;
|
||||
}
|
||||
}
|
36
sample/AppSampleD/entry/src/main/ets/appsampled/data/User.ts
Normal file
36
sample/AppSampleD/entry/src/main/ets/appsampled/data/User.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default class User{
|
||||
private username: string;
|
||||
private userIcon: Resource;
|
||||
|
||||
constructor(username?: string, userIcon?: Resource) {
|
||||
this.username = username;
|
||||
this.userIcon = userIcon;
|
||||
}
|
||||
|
||||
public getUsername(): string{
|
||||
return this.username;
|
||||
}
|
||||
public setUsername(username: string){
|
||||
this.username = username;
|
||||
}
|
||||
public getUserIcon(): Resource{
|
||||
return this.userIcon;
|
||||
}
|
||||
public setUserIcon(userIcon: Resource){
|
||||
this.userIcon = userIcon;
|
||||
}
|
||||
}
|
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { Permissions } from '@ohos.abilityAccessCtrl'
|
||||
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
|
||||
import router from '@ohos.router'
|
||||
import Logger from '../../utils/Logger'
|
||||
import CameraModel from '../../model/CameraModel'
|
||||
import User from '../data/User'
|
||||
|
||||
const TAG: string = '[CameraPage]'
|
||||
const PERMISSIONS: Array<Permissions> = ['ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.MEDIA_LOCATION', 'ohos.permission.MICROPHONE', 'ohos.permission.CAMERA']
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct CameraPage {
|
||||
// 底部特效模拟图片资源数组
|
||||
private imageList: Array<Resource> = [$r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon')];
|
||||
// 文字资源数组
|
||||
private textList: Array<Resource> = [$r('app.string.Word'), $r('app.string.Subsection'), $r('app.string.Video'), $r('app.string.Photo'), $r('app.string.Everyday'), $r('app.string.Live_streaming')];
|
||||
// 侧边图标资源数组
|
||||
private sidebarList_1: Array<Resource> = [$r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon')];
|
||||
private sidebarList_2: Array<Resource> = [$r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon'), $r('app.media.app_icon')];
|
||||
private xComponentController: XComponentController = new XComponentController();
|
||||
private textTimerController: TextTimerController = new TextTimerController();
|
||||
private cameraModel: CameraModel = new CameraModel(getContext(this))
|
||||
private scrollerHorText: Scroller = new Scroller();
|
||||
private scrollerHorImage: Scroller = new Scroller();
|
||||
private currentUser: User = null; // 当前用户信息
|
||||
@State recordingStatus: number = 0; // 0:未录制 1:正在录制 2:结束录制
|
||||
@State surfaceId: string = '-1';
|
||||
@State format: string = 'mm:ss';
|
||||
@State uploadFile: string = '';
|
||||
|
||||
pageTransition() {
|
||||
// 登录页面从底部滑入滑出
|
||||
PageTransitionEnter({ type: RouteType.Push, duration: 200 })
|
||||
.slide(SlideEffect.Bottom)
|
||||
PageTransitionExit({ type: RouteType.Pop, duration: 200 })
|
||||
.slide(SlideEffect.Bottom)
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
|
||||
try {
|
||||
atManager.requestPermissionsFromUser(getContext(this), PERMISSIONS).then((data) => {
|
||||
this.cameraModel.createCamera(this.surfaceId);
|
||||
Logger.info(TAG, 'requestPermissionsFromUser success')
|
||||
}).catch((err) => {
|
||||
Logger.info(TAG, `requestPermissionsFromUser err: ${JSON.stringify(err)}`)
|
||||
})
|
||||
} catch (err) {
|
||||
Logger.info(TAG, `requestPermissionsFromUser catch err->${JSON.stringify(err)}`);
|
||||
}
|
||||
if (globalThis.currentUser) {
|
||||
this.currentUser = globalThis.currentUser;
|
||||
}
|
||||
}
|
||||
|
||||
onPageHide() {
|
||||
Logger.info(TAG, 'page onPageHide');
|
||||
this.stopVideo();
|
||||
this.cameraModel.releaseCamera();
|
||||
}
|
||||
|
||||
onPageShow() {
|
||||
Logger.info(TAG, 'page onPageHide');
|
||||
this.cameraModel.createCamera(this.surfaceId);
|
||||
}
|
||||
|
||||
startVideo() {
|
||||
Logger.info(TAG, 'page startVideo');
|
||||
this.recordingStatus = 1;
|
||||
this.textTimerController.reset();
|
||||
this.textTimerController.start();
|
||||
this.cameraModel.startVideo();
|
||||
}
|
||||
|
||||
async stopVideo() {
|
||||
Logger.info(TAG, 'page stopVideo');
|
||||
this.recordingStatus = 2;
|
||||
this.textTimerController.pause();
|
||||
this.uploadFile = await this.cameraModel.stopVideo();
|
||||
Logger.info(TAG, `page stopVideo uploadFile = ${this.uploadFile}`);
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Stack() {
|
||||
XComponent({
|
||||
id: 'xComponentId',
|
||||
type: 'surface',
|
||||
controller: this.xComponentController
|
||||
})
|
||||
.onLoad(() => {
|
||||
Logger.info(TAG, 'onLoad is called')
|
||||
// 设置XComponent创建的曲面宽为640vp,高为480vp
|
||||
this.xComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 })
|
||||
this.surfaceId = this.xComponentController.getXComponentSurfaceId()
|
||||
Logger.info(TAG, `onLoad surfaceId: ${this.surfaceId}`)
|
||||
this.cameraModel.createCamera(this.surfaceId)
|
||||
})
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
|
||||
Column() {
|
||||
Row() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(50)
|
||||
.height(50)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
router.back()
|
||||
})
|
||||
.visibility(this.recordingStatus !== 1 ? Visibility.Visible : Visibility.None) // 正在录制时不显示
|
||||
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(14)
|
||||
Text($r('app.string.Select_music'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.width(132)
|
||||
.height(48)
|
||||
.borderRadius(12)
|
||||
.backgroundColor($r('app.color.COLOR_669F9B9B'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.visibility(this.recordingStatus !== 1 ? Visibility.Visible : Visibility.None) // 正在录制时不显示
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(26)
|
||||
.height(26)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.visibility(this.recordingStatus !== 2 ? Visibility.Visible : Visibility.None) // 非录制结束情况下显示
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(26)
|
||||
.height(26)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.visibility(this.recordingStatus === 2 ? Visibility.Visible : Visibility.None) // 录制结束情况时显示
|
||||
}
|
||||
.width(42)
|
||||
.height(42)
|
||||
}
|
||||
.width('100%')
|
||||
.height('8%')
|
||||
.justifyContent(this.recordingStatus !== 1 ? FlexAlign.SpaceBetween : FlexAlign.End)
|
||||
|
||||
Column({ space: 18 }) {
|
||||
if (this.recordingStatus === 0) {
|
||||
ForEach(this.sidebarList_1, (sidebar: Resource, index: number) => {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Contain)
|
||||
if (index === 1) {
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(1)
|
||||
.width(22)
|
||||
.color($r('app.color.COLOR_FFFFFF'))
|
||||
.margin({ right: 4 })
|
||||
}
|
||||
})
|
||||
} else if (this.recordingStatus === 2) {
|
||||
ForEach(this.sidebarList_2, (sidebar: Resource, index: number) => {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Contain)
|
||||
if (index === 0) {
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(1)
|
||||
.width(22)
|
||||
.color($r('app.color.COLOR_FFFFFF'))
|
||||
.margin({ right: 4 })
|
||||
}
|
||||
if (index === 1) {
|
||||
Text($r('app.string.Wen'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ right: 4 })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('50%')
|
||||
.padding({ top: 4, right: 14 })
|
||||
.alignItems(HorizontalAlign.End)
|
||||
.visibility(this.recordingStatus === 1 ? Visibility.None : Visibility.Visible) // 正在录制时不显示
|
||||
|
||||
Blank()
|
||||
|
||||
Column() {
|
||||
Column() {
|
||||
Column() {
|
||||
TextTimer({ isCountDown: false, count: 60000, controller: this.textTimerController })
|
||||
.height('100%')
|
||||
.fontSize(18)
|
||||
.format(this.format)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
}
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.visibility(this.recordingStatus === 1 ? Visibility.Visible : Visibility.Hidden)
|
||||
.width('100%')
|
||||
.height('30%')
|
||||
|
||||
// 文字列表
|
||||
Scroll(this.scrollerHorText) {
|
||||
Row({ space: 42 }) {
|
||||
ForEach(this.textList, (text: Resource, index: number) => {
|
||||
Text(text)
|
||||
.height('100%')
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor(index === 2 ? $r('app.color.COLOR_EEC934') : $r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.alignItems(VerticalAlign.Bottom)
|
||||
}
|
||||
.width('70%')
|
||||
.height('100%')
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.visibility(this.recordingStatus === 0 ? Visibility.Visible : Visibility.Hidden)
|
||||
}
|
||||
.width('100%')
|
||||
.height('15%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
Row() {
|
||||
if (this.recordingStatus === 0) {
|
||||
Column({ space: 6 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(56)
|
||||
.height(56)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(12)
|
||||
Text($r('app.string.Special'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
}
|
||||
.width(64)
|
||||
.height(64)
|
||||
|
||||
this.StartRecordComponent()
|
||||
|
||||
Column({ space: 6 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(56)
|
||||
.height(56)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(12)
|
||||
Text($r('app.string.Album'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
}
|
||||
.width(64)
|
||||
.height(64)
|
||||
} else if (this.recordingStatus === 1) {
|
||||
this.RecordingComponent()
|
||||
} else {
|
||||
this.PointComponent()
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('85%')
|
||||
.justifyContent(FlexAlign.SpaceEvenly)
|
||||
}
|
||||
.width('100%')
|
||||
.height('25%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('91%')
|
||||
.borderRadius(12)
|
||||
|
||||
Row({ space: 12 }) {
|
||||
if (this.recordingStatus === 0) {
|
||||
Scroll(this.scrollerHorImage) {
|
||||
Row({ space: 14 }) {
|
||||
ForEach(this.imageList, (img: Resource) => {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(56)
|
||||
.height(56)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(10)
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.alignItems(VerticalAlign.Bottom)
|
||||
.margin({ bottom: 1 })
|
||||
}
|
||||
.width('70%')
|
||||
.height('100%')
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
} else if (this.recordingStatus === 1) {
|
||||
|
||||
} else if (this.recordingStatus === 2) {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Fill)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.height('80%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.borderRadius(12)
|
||||
|
||||
Row({ space: 8 }) {
|
||||
if (this.currentUser) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(14)
|
||||
}
|
||||
Text($r('app.string.Send_everyday'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.layoutWeight(2)
|
||||
.height('80%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.borderRadius(12)
|
||||
|
||||
Row() {
|
||||
Text($r('app.string.Next'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.id('next')
|
||||
.layoutWeight(2)
|
||||
.height('80%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_FC2B55'))
|
||||
.borderRadius(12)
|
||||
.onClick(e => {
|
||||
this.recordingStatus = 0;
|
||||
router.pushUrl({
|
||||
url: 'appsampled/pages/PublishPage',
|
||||
params: {
|
||||
uploadFile: this.uploadFile
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('9%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.padding({ left: 12, right: 12 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
|
||||
@Builder
|
||||
StartRecordComponent() {
|
||||
Column() {
|
||||
Column()
|
||||
.width(80)
|
||||
.height(80)
|
||||
.backgroundColor(Color.Red)
|
||||
.borderRadius(40)
|
||||
}
|
||||
.id('startVideo')
|
||||
.width(100)
|
||||
.height(100)
|
||||
.border({ width: 5, color: $r('app.color.COLOR_FFFFFF'), radius: 50 })
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
this.startVideo();
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
RecordingComponent() {
|
||||
Stack() {
|
||||
Column()
|
||||
.width(60)
|
||||
.height(60)
|
||||
.borderRadius(30)
|
||||
.backgroundColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
Column()
|
||||
.width(20)
|
||||
.height(20)
|
||||
.borderRadius(4)
|
||||
.backgroundColor(Color.Red)
|
||||
}
|
||||
.id('stopVideo')
|
||||
.width(120)
|
||||
.height(120)
|
||||
.borderRadius(60)
|
||||
.backgroundColor($r('app.color.COLOR_80FFFFFF'))
|
||||
.onClick(e => {
|
||||
this.stopVideo();
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
PointComponent() {
|
||||
Row({ space: 8 }) {
|
||||
Text()
|
||||
.width(4)
|
||||
.height(4)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(2)
|
||||
Text()
|
||||
.width(6)
|
||||
.height(6)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(3)
|
||||
Text()
|
||||
.width(8)
|
||||
.height(8)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(4)
|
||||
|
||||
Text()
|
||||
.width(10)
|
||||
.height(10)
|
||||
.backgroundColor($r('app.color.COLOR_FFFFFF'))
|
||||
.borderRadius(5)
|
||||
|
||||
Text()
|
||||
.width(8)
|
||||
.height(8)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(4)
|
||||
Text()
|
||||
.width(6)
|
||||
.height(6)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(3)
|
||||
Text()
|
||||
.width(4)
|
||||
.height(4)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(2)
|
||||
}
|
||||
.width(100)
|
||||
.height(30)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../../utils/Logger';
|
||||
import { ChatSource } from '../data/DataSource';
|
||||
import ChatComponent from '../../component/ChatComponent'
|
||||
import { ChatBox } from '../data/ChatBox'
|
||||
import { getMockTool } from '../../mock/MockData'
|
||||
import Tool from '../data/Tool'
|
||||
import User from '../data/User'
|
||||
import ChatController from '../../controller/ChatController';
|
||||
import LoginResult from '../data/LoginResult';
|
||||
|
||||
const TAG: string = '[ChatPage]';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct ChatPage {
|
||||
private scroller: Scroller = new Scroller();
|
||||
private scrollerTool: Scroller = new Scroller();
|
||||
@State chats: ChatSource = new ChatSource();
|
||||
private toolArr: Array<Tool> = getMockTool(); // 用户信息模拟数据
|
||||
@State isSend: boolean = true; // 是否为发送消息
|
||||
@State isInput: boolean = false; // 是否正在输入
|
||||
private currentUser: User = null; // 当前用户信息
|
||||
private oppositeUser: User = null; // 对端用户信息
|
||||
private userInfo: LoginResult = null; // 登录返回结果信息
|
||||
private chatController: ChatController = new ChatController();
|
||||
@State inputValue: string = '';
|
||||
|
||||
aboutToAppear() {
|
||||
if (globalThis.currentUser) {
|
||||
this.currentUser = globalThis.currentUser;
|
||||
}
|
||||
if (globalThis.oppositeUser) {
|
||||
this.oppositeUser = globalThis.oppositeUser;
|
||||
}
|
||||
if (globalThis.userInfo) {
|
||||
this.userInfo = globalThis.userInfo
|
||||
}
|
||||
|
||||
this.chatController.onMessage(this.userInfo.getId(), (value) => {
|
||||
Logger.info(TAG, `ChatPage onMessage begin msg value: ${value}`);
|
||||
if (value) {
|
||||
this.chats.pushData(new ChatBox(false, value, this.oppositeUser.getUserIcon()));
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.id('chatBack')
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 16 })
|
||||
.onClick(e=>{
|
||||
router.back();
|
||||
})
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(50)
|
||||
.height(50)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 16, right: 16 })
|
||||
.borderRadius(25)
|
||||
Text(this.oppositeUser.getUsername())
|
||||
.height(30)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(20)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 20 })
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 20 })
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 20, right: 20 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('8%')
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(2)
|
||||
.color($r('app.color.COLOR_1E1E1E'))
|
||||
|
||||
// 消息滚动面板
|
||||
Column() {
|
||||
Scroll(this.scroller) {
|
||||
Column() {
|
||||
LazyForEach(this.chats, (item, index) => {
|
||||
Row() {
|
||||
ChatComponent({ item: item })
|
||||
}
|
||||
.margin({ top: 5, bottom: 10 })
|
||||
}, item => item.message)
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ top: 10 })
|
||||
}
|
||||
.scrollable(ScrollDirection.Vertical)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({ bottom: 8 })
|
||||
.align(Alignment.Top)
|
||||
}
|
||||
.width('100%')
|
||||
.height('75%')
|
||||
|
||||
Column() {
|
||||
// 工具栏
|
||||
Row() {
|
||||
// 横向工具栏列表
|
||||
Scroll(this.scrollerTool) {
|
||||
Row() {
|
||||
ForEach(this.toolArr, (tool: Tool) => {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 8 })
|
||||
Text(tool.getToolName())
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.width(120)
|
||||
.height('80%')
|
||||
.margin({ left: 12 })
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.borderRadius(18)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('95%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('40%')
|
||||
|
||||
// 消息输入框
|
||||
Row() {
|
||||
this.inputComponent()
|
||||
}
|
||||
.width('100%')
|
||||
.height('60%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('17%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
|
||||
@Builder
|
||||
inputComponent() {
|
||||
Stack() {
|
||||
Row()
|
||||
.width('95%')
|
||||
.height('70%')
|
||||
.borderRadius(32)
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
|
||||
if (this.isInput) {
|
||||
Row() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(26)
|
||||
.height(26)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(44)
|
||||
.height(44)
|
||||
.margin({ left: 5 })
|
||||
.borderRadius(22)
|
||||
.backgroundColor($r('app.color.COLOR_168CF6'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(42)
|
||||
.height(42)
|
||||
.objectFit(ImageFit.Contain)
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.id('msgSend')
|
||||
.width(36)
|
||||
.height(36)
|
||||
.margin({ left: 15, right: 10 })
|
||||
.borderRadius(22)
|
||||
.backgroundColor($r('app.color.COLOR_FE2B54'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, 'onClick send');
|
||||
if (this.inputValue) {
|
||||
this.chats.pushData(new ChatBox(true, this.inputValue, this.currentUser.getUserIcon()));
|
||||
this.chatController.sendMessage(this.oppositeUser.getUsername(), this.inputValue);
|
||||
this.inputValue = '';
|
||||
}
|
||||
})
|
||||
}
|
||||
.width('95%')
|
||||
.height('70%')
|
||||
} else {
|
||||
Row() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(28)
|
||||
.height(28)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(44)
|
||||
.height(44)
|
||||
.margin({ left: 5 })
|
||||
.borderRadius(22)
|
||||
.backgroundColor($r('app.color.COLOR_AE4EF7'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(42)
|
||||
.height(42)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(42)
|
||||
.height(42)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 15, right: 15 })
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(36)
|
||||
.height(36)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 10 })
|
||||
}
|
||||
.width('95%')
|
||||
.height('70%')
|
||||
}
|
||||
|
||||
TextInput({ placeholder: $r('app.string.Send_Message'), text: this.inputValue })
|
||||
.id('chatInput')
|
||||
.width('50%')
|
||||
.height('65%')
|
||||
.placeholderColor($r('app.color.COLOR_99F1F3F5'))
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.offset({ x: -50 })
|
||||
.padding({ left: 0 })
|
||||
.onChange(value => {
|
||||
Logger.info(TAG, `TextInput onChange value= ${value}`);
|
||||
this.inputValue = value;
|
||||
if (this.inputValue) {
|
||||
this.isInput = true;
|
||||
} else {
|
||||
this.isInput = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
.alignContent(Alignment.Center)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
}
|
141
sample/AppSampleD/entry/src/main/ets/appsampled/pages/Login.ets
Normal file
141
sample/AppSampleD/entry/src/main/ets/appsampled/pages/Login.ets
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import promptAction from '@ohos.promptAction';
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../../utils/Logger';
|
||||
import LoginController from '../../controller/LoginController';
|
||||
import LoginResult from '../data/LoginResult';
|
||||
import User from '../data/User';
|
||||
|
||||
const TAG: string = '[Login]';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Login {
|
||||
private loginController: LoginController = new LoginController();
|
||||
@State phoneNumber: string = '13111111111';
|
||||
@State password: string = '123456';
|
||||
@State isLoginSuccess: boolean = false;
|
||||
|
||||
pageTransition(){
|
||||
// 登录页面从底部滑入滑出
|
||||
PageTransitionEnter({ type: RouteType.Push, duration: 300 })
|
||||
.slide(SlideEffect.Bottom)
|
||||
PageTransitionExit({ type: RouteType.Pop, duration: 300 })
|
||||
.slide(SlideEffect.Bottom)
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Text($r('app.string.LoginByPhone'))
|
||||
.height('100%')
|
||||
.fontColor($r('app.color.COLOR_E6000000'))
|
||||
.fontSize(24)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
}
|
||||
.width('80%')
|
||||
.height('8%')
|
||||
.margin({ bottom: 10 })
|
||||
.justifyContent(FlexAlign.Start)
|
||||
|
||||
Column({ space: 10 }) {
|
||||
Stack() {
|
||||
TextInput({ placeholder: $r('app.string.Input_phone') })
|
||||
.width('100%')
|
||||
.height(50)
|
||||
.borderRadius(5)
|
||||
.type(InputType.PhoneNumber)
|
||||
.onChange(value => {
|
||||
this.phoneNumber = value;
|
||||
})
|
||||
}
|
||||
.width('80%')
|
||||
.height(50)
|
||||
|
||||
TextInput({ placeholder: $r('app.string.Input_password') })
|
||||
.width('80%')
|
||||
.height(50)
|
||||
.borderRadius(5)
|
||||
.type(InputType.Password)
|
||||
.onChange(value => {
|
||||
this.password = value;
|
||||
})
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(240)
|
||||
.height(25)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width('80%')
|
||||
.height(20)
|
||||
.justifyContent(FlexAlign.Start)
|
||||
|
||||
Text($r('app.string.Login'))
|
||||
.id('login')
|
||||
.width('80%')
|
||||
.height(50)
|
||||
.borderRadius(10)
|
||||
.textAlign(TextAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_FF785F'))
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(20)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.loginController.login(this.phoneNumber, this.password).then(res => {
|
||||
Logger.info(TAG, `login then: ${JSON.stringify(res)}`);
|
||||
// 提示服务端返回的登录信息
|
||||
promptAction.showToast({ message: res.getMessage(), duration: 1000, bottom: 500 });
|
||||
setTimeout(() => {
|
||||
if (res.getCode() === 200) {
|
||||
let data: LoginResult = res.getData();
|
||||
Logger.info(TAG, `login success: ${JSON.stringify(data.getToken())}`);
|
||||
// 存储用户信息, 包括token
|
||||
globalThis.userInfo = data;
|
||||
|
||||
// 分别存储当前用户和对端用户的用户名和头像
|
||||
if (data.getUsername() === '13111111111') {
|
||||
let currUser = new User(data.getUsername(),$r('app.media.app_icon'))
|
||||
let oppositeUser = new User('13122222222',$r('app.media.app_icon'))
|
||||
globalThis.currentUser = currUser;
|
||||
globalThis.oppositeUser = oppositeUser;
|
||||
}else{
|
||||
let currentUser = new User(data.getUsername(),$r('app.media.app_icon'))
|
||||
let oppositeUser = new User('13111111111',$r('app.media.app_icon'))
|
||||
globalThis.currentUser = currentUser;
|
||||
globalThis.oppositeUser = oppositeUser;
|
||||
}
|
||||
|
||||
// 跳转页面
|
||||
router.pushUrl({ url: 'pages/Index' });
|
||||
return;
|
||||
}
|
||||
Logger.info(TAG, `login failed: ${JSON.stringify(res)}`);
|
||||
}, 800)
|
||||
}).catch(err => {
|
||||
Logger.info(TAG, `login err: ${JSON.stringify(err)}`);
|
||||
promptAction.showToast({ message: $r('app.string.Connection_timesout'), duration: 1000, bottom: 500 });
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('92%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_FFFFFF'))
|
||||
}
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import promptAction from '@ohos.promptAction';
|
||||
import router from '@ohos.router';
|
||||
import UploadController from '../../controller/UploadController';
|
||||
import User from '../data/User';
|
||||
import Logger from '../../utils/Logger';
|
||||
|
||||
const TAG: string = '[PublishPage]';
|
||||
|
||||
type Item = {
|
||||
res: Resource,
|
||||
name: Resource
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct PublishPage {
|
||||
private itemList: Array<Item> = [{ res: $r('app.media.app_icon'), name: $r('app.string.Where_are_you') },
|
||||
{ res: $r('app.media.app_icon'), name: $r('app.string.Add_applet') },
|
||||
{ res: $r('app.media.app_icon'), name: $r('app.string.Publicly_visible') },
|
||||
{ res: $r('app.media.app_icon'), name: $r('app.string.Advanced_setup') }];
|
||||
private uploadController: UploadController = new UploadController();
|
||||
private uploadFile: string = router.getParams()['uploadFile']; // 需要上传的文件名
|
||||
private currentUser: User = null; // 当前用户信息
|
||||
@State uploadState: boolean = false;
|
||||
|
||||
pageTransition() {
|
||||
// 登录页面从底部滑入滑出
|
||||
PageTransitionEnter({ type: RouteType.Push, duration: 10 })
|
||||
.slide(SlideEffect.Right);
|
||||
PageTransitionExit({ type: RouteType.Pop, duration: 10 })
|
||||
.slide(SlideEffect.Right);
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
if (globalThis.currentUser) {
|
||||
this.currentUser = globalThis.currentUser;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row({ space: 12 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Fill)
|
||||
Text($r('app.string.Return_edit'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.width('100%')
|
||||
.height('8%')
|
||||
.padding({ left: 12 })
|
||||
.onClick(e => {
|
||||
router.back();
|
||||
})
|
||||
|
||||
Row() {
|
||||
Column() {
|
||||
TextArea({ placeholder: $r('app.string.Add_work_description') })
|
||||
.id('textArea')
|
||||
.width('100%')
|
||||
.height('50%')
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.placeholderColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
Blank()
|
||||
Row({ space: 6 }) {
|
||||
Text($r('app.string.Topic'))
|
||||
.width(88)
|
||||
.height(42)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.backgroundColor($r('app.color.COLOR_669F9B9B'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(12)
|
||||
Text($r('app.string.Well_Number_Friend'))
|
||||
.width(88)
|
||||
.height(42)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_669F9B9B'))
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(12)
|
||||
}
|
||||
.width('100%')
|
||||
.height(48)
|
||||
}
|
||||
.width('70%')
|
||||
.height('100%')
|
||||
.padding({ left: 12 })
|
||||
|
||||
Blank()
|
||||
Stack() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width('80%')
|
||||
.height('90%')
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(12)
|
||||
Text($r('app.string.Select_cover'))
|
||||
.width('80%')
|
||||
.height(32)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_669F9B9B'))
|
||||
.borderRadius(12)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
}
|
||||
.width('30%')
|
||||
.height('100%')
|
||||
.borderRadius(12)
|
||||
.alignContent(Alignment.Bottom)
|
||||
}
|
||||
.width('100%')
|
||||
.height('22%')
|
||||
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(1)
|
||||
.width('92%')
|
||||
.color($r('app.color.COLOR_5A5B63'))
|
||||
.margin({ top: 12 })
|
||||
|
||||
Column({ space: 2 }) {
|
||||
ForEach(this.itemList, (item: Item) => {
|
||||
Row({ space: 12 }) {
|
||||
Image(item.res)
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(4)
|
||||
Text(item.name)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.objectFit(ImageFit.Fill)
|
||||
}
|
||||
.width('100%')
|
||||
.height(64)
|
||||
.padding({ left: 12, right: 12 })
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('40%')
|
||||
|
||||
Blank()
|
||||
// 发布成功的提示
|
||||
if (this.uploadState) {
|
||||
Row({ space: 8 }) {
|
||||
if (this.currentUser) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(36)
|
||||
.height(36)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(18)
|
||||
}
|
||||
Text($r('app.string.Publish_Success'))
|
||||
.fontColor($r('app.color.COLOR_000000'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.fontSize(18)
|
||||
}
|
||||
.width('96%')
|
||||
.height(64)
|
||||
.backgroundColor($r('app.color.COLOR_FFFFFF'))
|
||||
.margin({ left: 8, right: 8, bottom: 12 })
|
||||
.padding({ left: 12, right: 12 })
|
||||
.borderRadius(12)
|
||||
}
|
||||
Row({ space: 8 }) {
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(14)
|
||||
Text($r('app.string.Save_Draft'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.height('80%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.borderRadius(12)
|
||||
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(14)
|
||||
Text($r('app.string.Publish'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
}
|
||||
.id('upload')
|
||||
.layoutWeight(1)
|
||||
.height('80%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.COLOR_FC2B55'))
|
||||
.borderRadius(12)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `uploadFile = ${this.uploadFile}`);
|
||||
this.uploadController.uploadFile(this.uploadFile).then(res => {
|
||||
Logger.info(TAG, `uploadFile success= ${JSON.stringify(res)}`);
|
||||
this.uploadState = true;
|
||||
setTimeout(() => {
|
||||
this.uploadState = false;
|
||||
router.pushUrl({ url: 'pages/Index' })
|
||||
}, 500)
|
||||
}).catch(err => {
|
||||
Logger.info(TAG, `uploadFile faild= ${JSON.stringify(err)}`);
|
||||
router.pushUrl({ url: 'pages/Index' })
|
||||
})
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('9%')
|
||||
.padding({ left: 8, right: 8 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../../utils/Logger';
|
||||
import { getMockSearch } from '../../mock/MockData';
|
||||
import SearchComponent from '../../component/SearchComponent';
|
||||
import SearchResultComponent from '../../component/SearchResultComponent';
|
||||
|
||||
const TAG: string = '[SearchPage]';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SearchPage {
|
||||
private searchArr: Array<string> = getMockSearch();
|
||||
@State inputValue: string = '';
|
||||
@State isInput: boolean = false;
|
||||
@State isShowResult: boolean = false;
|
||||
|
||||
pageTransition(){
|
||||
// 登录页面从底部滑入滑出
|
||||
PageTransitionEnter({ type: RouteType.Push, duration: 10 })
|
||||
.slide(SlideEffect.Right)
|
||||
PageTransitionExit({ type: RouteType.Pop, duration: 10 })
|
||||
.slide(SlideEffect.Right)
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(22)
|
||||
.height(22)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.id('searchBack')
|
||||
.width(50)
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `ic_cancel_cir onClick`);
|
||||
// 如果在搜索结果界面,则返回至搜索界面
|
||||
if (this.isShowResult) {
|
||||
this.isShowResult = false;
|
||||
}else {
|
||||
// 在搜索界面直接返回上一级页面
|
||||
router.back();
|
||||
}
|
||||
})
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.margin({ left: 10, right: 10 })
|
||||
.objectFit(ImageFit.Contain)
|
||||
TextInput({ placeholder: this.searchArr[0], text: this.inputValue })
|
||||
.width('75%')
|
||||
.height('80%')
|
||||
.placeholderColor($r('app.color.COLOR_99F1F3F5'))
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.padding({ left: 0 })
|
||||
.onChange(value => {
|
||||
Logger.info(TAG, `TextInput onChange value= ${value}`);
|
||||
this.inputValue = value;
|
||||
if (this.inputValue) {
|
||||
this.isInput = true;
|
||||
} else {
|
||||
this.isInput = false;
|
||||
}
|
||||
})
|
||||
|
||||
Row() {
|
||||
Image(this.isInput ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.margin({ left: 10, right: 10 })
|
||||
.objectFit(ImageFit.Contain)
|
||||
.opacity(0.8)
|
||||
}
|
||||
.width(50)
|
||||
.height('100%')
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `ic_cancel_cir onClick`);
|
||||
if (this.inputValue) {
|
||||
this.inputValue = '';
|
||||
}
|
||||
})
|
||||
}
|
||||
.width('75%')
|
||||
.height('65%')
|
||||
.backgroundColor($r('app.color.COLOR_393939'))
|
||||
.borderRadius(4)
|
||||
|
||||
Column(){
|
||||
Text($r('app.string.Search'))
|
||||
.fontColor($r('app.color.COLOR_E3163D'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(64)
|
||||
.height('100%')
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e=>{
|
||||
this.isShowResult = true;
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('10%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
|
||||
Column() {
|
||||
if (this.isShowResult){
|
||||
// 搜索结果界面
|
||||
SearchResultComponent({ inputSearch: this.inputValue })
|
||||
}else{
|
||||
// 搜索界面
|
||||
SearchComponent({inputValue: $inputValue, isShowResult: $isShowResult})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('90%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ChatBox } from '../appsampled/data/ChatBox';
|
||||
|
||||
@Component
|
||||
export default struct ChatComponent {
|
||||
private item: ChatBox = undefined;
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
if (!this.item.isSend) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(50)
|
||||
.height(50)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(25)
|
||||
.margin({ left: 10, right: 10 })
|
||||
}
|
||||
Column() {
|
||||
Text(this.item.message)
|
||||
.maxLines(5)
|
||||
.padding(10)
|
||||
.fontSize(18)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.borderRadius(14)
|
||||
.alignSelf(this.item.isSend ? ItemAlign.End : ItemAlign.Start)
|
||||
.backgroundColor(this.item.isSend ? $r('app.color.COLOR_3DA0F1') : $r('app.color.COLOR_393939'))
|
||||
}
|
||||
.width('85%')
|
||||
|
||||
if (this.item.isSend) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(50)
|
||||
.height(50)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(25)
|
||||
.margin({ left: 10, right: 10 })
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height(40)
|
||||
}
|
||||
}
|
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@ohos.router';
|
||||
import User from '../appsampled/data/User';
|
||||
import { getMockUser } from '../mock/MockData'
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG: string = '[MessagePage]';
|
||||
|
||||
@Component
|
||||
export default struct MessagePage {
|
||||
@State selectDownIndex: number = 2; // 底部选择索引
|
||||
private scrollerHor: Scroller = new Scroller();
|
||||
private scrollerVer: Scroller = new Scroller();
|
||||
private userArr: Array<User> = getMockUser(); // 用户信息模拟数据
|
||||
|
||||
private currentUser: User = null; // 当前用户信息
|
||||
private oppositeUser: User = null; // 对端用户信息
|
||||
|
||||
aboutToAppear(){
|
||||
// globalThis.oppositeUser = new User('13222222222',$r('app.media.ic_headphoto_2'));
|
||||
|
||||
if (globalThis.currentUser) {
|
||||
this.currentUser = globalThis.currentUser;
|
||||
}
|
||||
if (globalThis.oppositeUser) {
|
||||
this.oppositeUser = globalThis.oppositeUser;
|
||||
// 将模拟数据中的第一条替换成真实对端数据
|
||||
this.userArr[0].setUsername(this.oppositeUser.getUsername());
|
||||
this.userArr[0].setUserIcon(this.oppositeUser.getUserIcon());
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 15 })
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(40)
|
||||
.height(40)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 15 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('7%')
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
|
||||
Column() {
|
||||
Scroll(this.scrollerVer) {
|
||||
Column() {
|
||||
// 横向列表
|
||||
Scroll(this.scrollerHor) {
|
||||
Row() {
|
||||
ForEach(this.userArr, (user) => {
|
||||
Column(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(70)
|
||||
.height(70)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(35)
|
||||
.margin({bottom: 8})
|
||||
Text(user.getUsername())
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.width(90)
|
||||
.height(90)
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height(120)
|
||||
|
||||
// 新朋友
|
||||
Row(){
|
||||
Column(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.backgroundColor($r('app.color.COLOR_57A9FE'))
|
||||
.borderRadius(30)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.margin({left: 15, right: 15})
|
||||
Column({space: 8}){
|
||||
Text($r('app.string.NewFriend'))
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
Text($r('app.string.No_new_notice'))
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
}
|
||||
.height(70)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({right: 20})
|
||||
}
|
||||
.width('100%')
|
||||
.height(80)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
|
||||
// 互动消息
|
||||
Row(){
|
||||
Column(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(50)
|
||||
.height(50)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.rotate({angle: -90})
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.backgroundColor($r('app.color.COLOR_FF689F'))
|
||||
.borderRadius(30)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.margin({left: 15, right: 15})
|
||||
Column({space: 8}){
|
||||
Text($r('app.string.Interactive_message'))
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
Text($r('app.string.Interactive_message_content'))
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
}
|
||||
.height(70)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({right: 20})
|
||||
}
|
||||
.width('100%')
|
||||
.height(80)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
|
||||
// 竖向列表
|
||||
ForEach(this.userArr, (user: User, index: number) => {
|
||||
Row(){
|
||||
Column(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(60)
|
||||
.height(60)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(30)
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.borderRadius(30)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.margin({left: 15, right: 15})
|
||||
Column({space: 8}){
|
||||
Text(user.getUsername())
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
Text($r('app.string.Greet'))
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
}
|
||||
.height(70)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.id(`userID_${index+1}`)
|
||||
.width('100%')
|
||||
.height(80)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.onClick(e=>{
|
||||
if (index !== 0) {
|
||||
return;
|
||||
}
|
||||
router.pushUrl({url: 'appsampled/pages/ChatPage'})
|
||||
})
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.scrollable(ScrollDirection.Vertical)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('93%')
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Logger from '../utils/Logger';
|
||||
import { getMockSearch } from '../mock/MockData'
|
||||
|
||||
const TAG: string = '[SearchComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchComponent {
|
||||
private scroller: Scroller = new Scroller();
|
||||
private searchArr: Array<string> = getMockSearch();
|
||||
@Link inputValue: string
|
||||
@Link isShowResult: boolean // 点击Item改变此值以展示搜索结果页面
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Scroll(this.scroller) {
|
||||
Column({ space: 4 }) {
|
||||
ForEach(this.searchArr, (item, index) => {
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 14, right: 10 })
|
||||
.opacity(0.8)
|
||||
Text(item)
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(20)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ right: 12 })
|
||||
Blank()
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(16)
|
||||
.height(16)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 14 })
|
||||
.opacity(0.7)
|
||||
}
|
||||
.id(`searchItem_${index+1}`)
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.onClick(e => {
|
||||
// 只有前三条拥有对应的假数据,其他item不做处理
|
||||
if (index < 3) {
|
||||
this.inputValue = item;
|
||||
this.isShowResult = true;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.scrollable(ScrollDirection.Vertical)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('45%')
|
||||
.align(Alignment.Top)
|
||||
|
||||
Column({ space: 12 }) {
|
||||
Text($r('app.string.Clear_all_search_record'))
|
||||
.fontColor($r('app.color.COLOR_5A5B63'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(1)
|
||||
.width('90%')
|
||||
.color($r('app.color.COLOR_5A5B63'))
|
||||
}
|
||||
.width('100%')
|
||||
.height(30)
|
||||
.margin({ top: 10 })
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import Logger from '../utils/Logger';
|
||||
import { AudioInfo } from '../appsampled/data/SearchResult';
|
||||
import AVPlayerModel from '../model/AVPlayerModel'
|
||||
import Constant from '../utils/Constant';
|
||||
|
||||
const TAG: string = '[SearchPlayMusicComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchPlayMusicComponent {
|
||||
private audioInfo: AudioInfo;
|
||||
private avPlayerModel: AVPlayerModel = new AVPlayerModel(getContext(this));
|
||||
@State isCollect: boolean = false;
|
||||
@State isPlay: boolean = false;
|
||||
@State isInit: boolean = false;
|
||||
|
||||
aboutToAppear() {
|
||||
// 监听暂停事件,当有其他音乐播放时当前播放
|
||||
emitter.on({ eventId: Constant.EVENT_PAUSED_AUDIO }, data => {
|
||||
Logger.info(TAG, `emitter on data = ${JSON.stringify(data)}`)
|
||||
if (data) {
|
||||
// 拿出传过来的ID
|
||||
let audioId = data.data.audioId;
|
||||
Logger.info(TAG, `emitter on data audioId= ${JSON.stringify(audioId)}`)
|
||||
// 不与当前ID相同则暂停,规避自身也会暂停的问题
|
||||
if (audioId && audioId !== this.audioInfo.audioId) {
|
||||
Logger.info(TAG, `emitter on data this.isPlay= ${JSON.stringify(this.isPlay)}`)
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
this.isPlay = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
// 音乐头像
|
||||
Stack() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(74)
|
||||
.height(74)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(10)
|
||||
Image(this.isPlay ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(26)
|
||||
.height(26)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.id(`musicID_${this.audioInfo.audioId}`)
|
||||
.width(74)
|
||||
.height(74)
|
||||
.margin({ right: 12 })
|
||||
.alignContent(Alignment.Center)
|
||||
.onClick(e => {
|
||||
// 播放的音乐点击则暂停
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
} else {
|
||||
// 播放当前音乐时发送事件暂停其他音乐播放事件
|
||||
emitter.emit({ eventId: Constant.EVENT_PAUSED_AUDIO }, {
|
||||
data: {
|
||||
['audioId']: this.audioInfo.audioId
|
||||
}
|
||||
});
|
||||
// 第一次点击播放先初始化音乐
|
||||
if (!this.isInit) {
|
||||
this.avPlayerModel.avPlayerFdSrcDemo(this.audioInfo.audio);
|
||||
this.isInit = !this.isInit;
|
||||
} else {
|
||||
// 初始化过的直接播放
|
||||
this.avPlayerModel.play();
|
||||
}
|
||||
}
|
||||
this.isPlay = !this.isPlay;
|
||||
})
|
||||
|
||||
// 音乐信息
|
||||
Column({ space: 2 }) {
|
||||
Row({ space: 2 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(10)
|
||||
Text(this.audioInfo.audioName)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Start)
|
||||
}
|
||||
.height(30)
|
||||
|
||||
Text(this.audioInfo.audioAuthorName)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
|
||||
Row({ space: 5 }) {
|
||||
Text(this.audioInfo.audioTime)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
Text()
|
||||
.width(2)
|
||||
.height(2)
|
||||
.backgroundColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.borderRadius(1)
|
||||
Text(this.audioInfo.audioNum)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.height(20)
|
||||
}
|
||||
.height(70)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
Blank()
|
||||
|
||||
Column() {
|
||||
Image(this.isCollect ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 12 })
|
||||
}
|
||||
.width(40)
|
||||
.height(40)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.onClick(e => {
|
||||
this.isCollect = !this.isCollect;
|
||||
})
|
||||
}
|
||||
.height(90)
|
||||
.width('100%')
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import emitter from '@ohos.events.emitter';
|
||||
|
||||
import { VideoDetailInfo } from '../appsampled/data/SearchResult';
|
||||
import AVPlayerModel from '../model/AVPlayerModel'
|
||||
import Constant from '../utils/Constant';
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG: string = '[SearchPlayVideoComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchPlayVideoComponent {
|
||||
private videoDetailInfo: VideoDetailInfo;
|
||||
private xComponentController: XComponentController = new XComponentController();
|
||||
private avPlayerModel: AVPlayerModel = new AVPlayerModel(getContext(this));
|
||||
@State surfaceId: string = '-1';
|
||||
@State isPlay: boolean = false;
|
||||
@State isInit: boolean = false;
|
||||
|
||||
aboutToAppear() {
|
||||
// 监听暂停事件,当有其他音乐播放时当前播放
|
||||
emitter.on({ eventId: Constant.EVENT_PAUSED_VIDEO }, data => {
|
||||
Logger.info(TAG, `emitter on data = ${JSON.stringify(data)}`)
|
||||
if (data) {
|
||||
// 拿出传过来的ID
|
||||
let videoDetailId = data.data.videoDetailId;
|
||||
Logger.info(TAG, `emitter on data videoId= ${JSON.stringify(videoDetailId)}`)
|
||||
// 不与当前ID相同则暂停,规避自身也会暂停的问题
|
||||
if (videoDetailId && videoDetailId !== this.videoDetailInfo.videoDetailId) {
|
||||
Logger.info(TAG, `emitter on data this.isPlay= ${JSON.stringify(this.isPlay)}`)
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
this.isPlay = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
// 作者信息
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(48)
|
||||
.height(48)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(24)
|
||||
Column({ space: 5 }) {
|
||||
Text(this.videoDetailInfo.videoDetailAuthorName)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Start)
|
||||
Text(this.videoDetailInfo.videoDetailTime)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
}
|
||||
.height(80)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
Blank()
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(22)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 5 })
|
||||
}
|
||||
.width('100%')
|
||||
.height(70)
|
||||
|
||||
// 视频Title
|
||||
Column({ space: 5 }) {
|
||||
Text(this.videoDetailInfo.videoDetailTitle)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
Text(this.videoDetailInfo.videoDetailLabel)
|
||||
.fontColor($r('app.color.COLOR_EEC934'))
|
||||
.fontSize(18)
|
||||
.maxLines(3)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.width('100%')
|
||||
.height(60)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
// 视频
|
||||
Stack() {
|
||||
XComponent({
|
||||
id: 'xComponentId',
|
||||
type: 'surface',
|
||||
controller: this.xComponentController
|
||||
})
|
||||
.onLoad(() => {
|
||||
Logger.info(TAG, 'onLoad is called')
|
||||
this.xComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 })
|
||||
this.surfaceId = this.xComponentController.getXComponentSurfaceId()
|
||||
Logger.info(TAG, `onLoad surfaceId: ${this.surfaceId}`)
|
||||
})
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
.borderRadius(14)
|
||||
Row() {
|
||||
Image(this.isPlay ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(56)
|
||||
.height(56)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `onClick this.isPlay= ${JSON.stringify(this.isPlay)}`)
|
||||
// 播放的视频点击则暂停
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
} else {
|
||||
// 播放当前视频时发送事件暂停其他视频播放事件
|
||||
emitter.emit({ eventId: Constant.EVENT_PAUSED_VIDEO }, {
|
||||
data: {
|
||||
['videoDetailId']: this.videoDetailInfo.videoDetailId
|
||||
}
|
||||
});
|
||||
|
||||
// 第一次点击播放先初始化音乐
|
||||
if (!this.isInit) {
|
||||
this.avPlayerModel.avPlayerFdSrcDemo(this.videoDetailInfo.videoDetail, this.surfaceId);
|
||||
this.isInit = !this.isInit;
|
||||
} else {
|
||||
Logger.info(TAG, `onClick Play= ${JSON.stringify(this.isInit)}`)
|
||||
// 初始化过的直接播放
|
||||
this.avPlayerModel.play();
|
||||
}
|
||||
}
|
||||
this.isPlay = !this.isPlay;
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height(300)
|
||||
.alignContent(Alignment.BottomEnd)
|
||||
|
||||
// 视频点赞等信息
|
||||
Row() {
|
||||
this.Item($r('app.media.app_icon'), this.videoDetailInfo.videoDetailLike)
|
||||
this.Item($r('app.media.app_icon'), this.videoDetailInfo.videoDetailComment)
|
||||
this.Item($r('app.media.app_icon'), this.videoDetailInfo.videoDetailCollect)
|
||||
this.Item($r('app.media.app_icon'), this.videoDetailInfo.videoDetailTransmit)
|
||||
}
|
||||
.width('100%')
|
||||
.height(50)
|
||||
.padding({ left: 10, right: 10 })
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
|
||||
// 视频具体评论信息
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(36)
|
||||
.height(36)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(18)
|
||||
Column({ space: 5 }) {
|
||||
Text(this.videoDetailInfo.commenterName)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Start)
|
||||
Text(this.videoDetailInfo.commenterContent)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
}
|
||||
.height(60)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
Blank()
|
||||
Column() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(22)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text(this.videoDetailInfo.commenterLike)
|
||||
.height(18)
|
||||
.fontColor($r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
}
|
||||
.width(48)
|
||||
.height(48)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
.width('100%')
|
||||
.height(70)
|
||||
.padding({ left: 10, right: 10 })
|
||||
}
|
||||
.width('100%')
|
||||
.height(550)
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
|
||||
@Builder
|
||||
Item(img: Resource, num: string) {
|
||||
Row({ space: 8 }) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text(num)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(64)
|
||||
.height(48)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../utils/Logger';
|
||||
import { getMockSearchResult, MockInput } from '../mock/MockData';
|
||||
import { SearchResult } from '../appsampled/data/SearchResult';
|
||||
import SearchSynthesizeComponent from './SearchSynthesizeComponent';
|
||||
import SearchVideoComponent from './SearchVideoComponent';
|
||||
|
||||
const TAG: string = '[SearchResultComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchResultComponent {
|
||||
private scrollerHor_1: Scroller = new Scroller();
|
||||
private titleList: Array<Resource> = [$r('app.string.Synthesize'), $r('app.string.Video'), $r('app.string.Music'),
|
||||
$r('app.string.User'), $r('app.string.Commodity'), $r('app.string.Live_streaming')];
|
||||
private searchResultList: Array<SearchResult> = getMockSearchResult(); // mock
|
||||
private inputSearch: string = ''; // 搜索输入框输入的字符串
|
||||
@State currSearchResult: SearchResult = this.searchResultList[0]; // mock
|
||||
@State selectTopIndex: number = 0; // 综合、视频等title选择索引
|
||||
|
||||
aboutToAppear() {
|
||||
// 默认值
|
||||
if (this.inputSearch === '') {
|
||||
this.inputSearch = MockInput.TEST_INPUT_CONTENT_1;
|
||||
}
|
||||
// 依据不同的搜索展示不同的模拟数据
|
||||
Logger.info(TAG, `this.inputSearch: ${JSON.stringify(this.inputSearch)}`);
|
||||
if (this.inputSearch.indexOf(MockInput.TEST_INPUT_CONTENT_1) !== -1) {
|
||||
// 输入"黑夜问白天"的模拟数据
|
||||
this.currSearchResult = this.searchResultList[0];
|
||||
} else if (this.inputSearch.indexOf(MockInput.TEST_INPUT_CONTENT_2) !== -1) {
|
||||
// 输入"哦想"的模拟数据
|
||||
this.currSearchResult = this.searchResultList[1];
|
||||
} else if (this.inputSearch.indexOf(MockInput.TEST_INPUT_CONTENT_3) !== -1) {
|
||||
// 输入"我不愿让你一个人"的模拟数据
|
||||
this.currSearchResult = this.searchResultList[2];
|
||||
}
|
||||
Logger.info(TAG, `this.currSearchResult: ${JSON.stringify(this.currSearchResult)}`);
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
// 横向Label列表
|
||||
Scroll(this.scrollerHor_1) {
|
||||
Row() {
|
||||
ForEach(this.titleList, (title: Resource, index: number) => {
|
||||
Column() {
|
||||
Text(title)
|
||||
.width(60)
|
||||
.height(20)
|
||||
.fontColor(this.selectTopIndex === index ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(20)
|
||||
.width(60)
|
||||
.strokeWidth(3)
|
||||
.color($r('app.color.COLOR_D7B837'))
|
||||
.visibility(this.selectTopIndex === index ? Visibility.Visible : Visibility.Hidden)
|
||||
}
|
||||
.id(`titleID_${index+1}`)
|
||||
.width(78)
|
||||
.height('100%')
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = index;
|
||||
})
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('90%')
|
||||
.height('100%')
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 4, top: 2 })
|
||||
}
|
||||
.width('10%')
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(VerticalAlign.Top)
|
||||
}
|
||||
.width('100%')
|
||||
.height('6%')
|
||||
.padding({ left: 8, right: 6 })
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(1)
|
||||
.width('100%')
|
||||
.color($r('app.color.COLOR_5A5B63'))
|
||||
|
||||
|
||||
Column() {
|
||||
if (this.selectTopIndex === 0){
|
||||
SearchSynthesizeComponent({currSearchResult: this.currSearchResult})
|
||||
}else if (this.selectTopIndex === 1){
|
||||
SearchVideoComponent({currSearchResult: this.currSearchResult})
|
||||
}
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('94%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AudioInfo, SearchResult, VideoDetailInfo } from '../appsampled/data/SearchResult';
|
||||
import SearchPlayMusicComponent from './SearchPlayMusicComponent';
|
||||
import SearchPlayVideoComponent from './SearchPlayVideoComponent';
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG: string = '[SearchSynthesizeComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchSynthesizeComponent {
|
||||
private scrollerHor: Scroller = new Scroller();
|
||||
private scrollerVer: Scroller = new Scroller();
|
||||
private currSearchResult: SearchResult;
|
||||
@State selectTopIndex: number = 0;
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Scroll(this.scrollerVer) {
|
||||
Column() {
|
||||
// 横向Label列表
|
||||
Row() {
|
||||
Scroll(this.scrollerHor) {
|
||||
Row({ space: 8 }) {
|
||||
// 全部
|
||||
Column() {
|
||||
Text($r('app.string.All'))
|
||||
.height(20)
|
||||
.fontColor(this.selectTopIndex === 0 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.padding({ left: 16, right: 16 })
|
||||
}
|
||||
.height(40)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor(this.selectTopIndex === 0 ? $r('app.color.COLOR_393939') : $r('app.color.COLOR_99393939'))
|
||||
.borderRadius(4)
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 0;
|
||||
})
|
||||
// 模拟数据 label列表
|
||||
ForEach(this.currSearchResult.labelList, (title: string, index: number) => {
|
||||
Column() {
|
||||
Text(title)
|
||||
.height(20)
|
||||
.fontColor(this.selectTopIndex === (index + 1) ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.padding({ left: 16, right: 16 })
|
||||
}
|
||||
.height(40)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor(this.selectTopIndex === (index + 1) ? $r('app.color.COLOR_393939') : $r('app.color.COLOR_99393939'))
|
||||
.borderRadius(4)
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = index + 1;
|
||||
})
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height(60)
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.padding({ left: 14, right: 8 })
|
||||
|
||||
// 音乐列表
|
||||
Column() {
|
||||
// 音乐 Title
|
||||
Row() {
|
||||
Text($r('app.string.Music'))
|
||||
.width(60)
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Start)
|
||||
|
||||
Blank()
|
||||
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(22)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 25, right: 14 })
|
||||
}
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.margin({ top: 10 })
|
||||
|
||||
// 模拟数据 音乐列表
|
||||
ForEach(this.currSearchResult.audioInfoList, (audioInfo: AudioInfo) => {
|
||||
SearchPlayMusicComponent({ audioInfo: audioInfo })
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.padding({ left: 14, right: 14 })
|
||||
|
||||
// 模拟数据 视频详细信息列表
|
||||
Column() {
|
||||
|
||||
ForEach(this.currSearchResult.videoDetailInfo, (videoDetailInfo: VideoDetailInfo) => {
|
||||
Divider()
|
||||
.vertical(false)
|
||||
.height(10)
|
||||
.width('100%')
|
||||
.strokeWidth(8)
|
||||
.color($r('app.color.COLOR_000000'))
|
||||
Column() {
|
||||
SearchPlayVideoComponent({ videoDetailInfo: videoDetailInfo })
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ left: 14, right: 14 })
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.scrollable(ScrollDirection.Vertical)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.align(Alignment.Top)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../utils/Logger';
|
||||
import { SearchResult, VideoInfo } from '../appsampled/data/SearchResult';
|
||||
|
||||
const TAG: string = '[SearchVideoComponent]';
|
||||
|
||||
@Component
|
||||
export default struct SearchVideoComponent {
|
||||
private scrollerHor: Scroller = new Scroller();
|
||||
private scrollerVer: Scroller = new Scroller();
|
||||
private currSearchResult: SearchResult;
|
||||
@State selectTopIndex: number = 0;
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Scroll(this.scrollerVer) {
|
||||
Column() {
|
||||
// 横向Label列表
|
||||
Row() {
|
||||
Scroll(this.scrollerHor) {
|
||||
Row({ space: 8 }) {
|
||||
// 全部
|
||||
Column() {
|
||||
Text($r('app.string.All'))
|
||||
.height(20)
|
||||
.fontColor(this.selectTopIndex === 0 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.padding({ left: 16, right: 16 })
|
||||
}
|
||||
.height(40)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor(this.selectTopIndex === 0 ? $r('app.color.COLOR_393939') : $r('app.color.COLOR_99393939'))
|
||||
.borderRadius(4)
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 0;
|
||||
})
|
||||
// 模拟数据 label列表
|
||||
ForEach(this.currSearchResult.labelList, (title: string, index: number) => {
|
||||
Column() {
|
||||
Text(title)
|
||||
.height(20)
|
||||
.fontColor(this.selectTopIndex === (index + 1) ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(16)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.textAlign(TextAlign.Center)
|
||||
.padding({ left: 16, right: 16 })
|
||||
}
|
||||
.height(40)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor(this.selectTopIndex === (index + 1) ? $r('app.color.COLOR_393939') : $r('app.color.COLOR_99393939'))
|
||||
.borderRadius(4)
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = index + 1;
|
||||
})
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height(60)
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.padding({ left: 14, right: 8 })
|
||||
|
||||
// 视频列表
|
||||
GridRow({columns: 2}) {
|
||||
// 模拟数据 音乐列表
|
||||
ForEach(this.currSearchResult.videoInfo, (videoInfo: VideoInfo) => {
|
||||
GridCol() {
|
||||
this.VideoItem(videoInfo)
|
||||
}
|
||||
.width('100%')
|
||||
.margin({right: 1,bottom:1})
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.scrollable(ScrollDirection.Vertical)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.align(Alignment.Top)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_151724'))
|
||||
}
|
||||
|
||||
@Builder
|
||||
VideoItem(videoInfo: VideoInfo) {
|
||||
Stack() {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(4)
|
||||
Column() {
|
||||
Text(videoInfo.videoTitle)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.padding({ left: 6, right: 6 })
|
||||
Row({space: 5}) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(12)
|
||||
Text(videoInfo.videoAuthorName)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
Blank()
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(12)
|
||||
Text(videoInfo.videoLikeNum)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(18)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Start)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.width('100%')
|
||||
.height(30)
|
||||
.padding({ left: 6, right: 6 })
|
||||
}
|
||||
.width('100%')
|
||||
.height(56)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.width('100%')
|
||||
.height(280)
|
||||
.backgroundColor(Color.Pink)
|
||||
.alignContent(Alignment.Bottom)
|
||||
}
|
||||
}
|
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../utils/Logger';
|
||||
import AVPlayerModel from '../model/AVPlayerModel';
|
||||
import Constant from '../utils/Constant';
|
||||
import emitter from '@ohos.events.emitter';
|
||||
|
||||
const TAG: string = '[VideoComponent]';
|
||||
|
||||
@Component
|
||||
export default struct VideoComponent {
|
||||
private xComponentController: XComponentController = new XComponentController();
|
||||
private avPlayerModel: AVPlayerModel = new AVPlayerModel(getContext(this));
|
||||
@State surfaceId: string = '-1';
|
||||
@State selectTopIndex: number = 4; // 顶部选择索引
|
||||
@State isLike: boolean = false; // 是否喜欢
|
||||
@State isCollect: boolean = false; // 是否收藏
|
||||
@State isPlay: boolean = true; // 是否播放
|
||||
|
||||
aboutToAppear() {
|
||||
// 监听暂停事件,当有其他音乐播放时当前播放
|
||||
emitter.on({ eventId: Constant.EVENT_PAUSED_INDEX }, data => {
|
||||
Logger.info(TAG, `emitter on data = ${JSON.stringify(data)}`)
|
||||
Logger.info(TAG, `emitter on data this.isPlay= ${JSON.stringify(this.isPlay)}`)
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
this.isPlay = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Stack() {
|
||||
XComponent({
|
||||
id: 'xComponentId',
|
||||
type: 'surface',
|
||||
controller: this.xComponentController
|
||||
})
|
||||
.onLoad(() => {
|
||||
Logger.info(TAG, 'onLoad is called')
|
||||
// 设置XComponent创建的曲面宽为640vp,高为480vp
|
||||
this.xComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 })
|
||||
this.surfaceId = this.xComponentController.getXComponentSurfaceId()
|
||||
Logger.info(TAG, `onLoad surfaceId: ${this.surfaceId}`)
|
||||
this.avPlayerModel.avPlayerFdSrcDemo(Constant.TEST_NAME_DEMO_VIDEO, this.surfaceId)
|
||||
})
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
|
||||
Column() {
|
||||
Row({space:28}) {
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text($r('app.string.Stroll'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectTopIndex === 0 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 0;
|
||||
})
|
||||
Text($r('app.string.Experience'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectTopIndex === 1 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 1;
|
||||
})
|
||||
Text($r('app.string.Attention'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectTopIndex === 2 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 2;
|
||||
})
|
||||
Text($r('app.string.Store'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectTopIndex === 3 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 3;
|
||||
})
|
||||
Text($r('app.string.Recommend'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectTopIndex === 4 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCFFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.onClick(e => {
|
||||
this.selectTopIndex = 4;
|
||||
})
|
||||
Row(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.id('search')
|
||||
.width(30)
|
||||
.height(30)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(40)
|
||||
.height(50)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `search_white onClick`);
|
||||
emitter.emit({ eventId: Constant.EVENT_PAUSED_INDEX });
|
||||
router.pushUrl({url: 'appsampled/pages/SearchPage'})
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('8%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
Blank()
|
||||
|
||||
Row() {
|
||||
Column() {
|
||||
Text($r('app.string.UserNick'))
|
||||
.height(30)
|
||||
.fontColor($r('app.color.COLOR_FFFFFF'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ left: 15, bottom: 10 })
|
||||
Text($r('app.string.TikContent'))
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(20)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.margin({ left: 15, bottom: 20 })
|
||||
}
|
||||
.width('85%')
|
||||
.height('100%')
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.justifyContent(FlexAlign.End)
|
||||
|
||||
Column({space: 10}) {
|
||||
Stack(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(60)
|
||||
.height(60)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(30)
|
||||
.border({color: $r('app.color.COLOR_FFFFFF'), width: 2})
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.borderRadius(10)
|
||||
.offset({y: 10})
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.margin({bottom: 10})
|
||||
.alignContent(Alignment.Bottom)
|
||||
|
||||
Column(){
|
||||
Image(this.isLike ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(35)
|
||||
.height(35)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(e=>{
|
||||
this.isLike = !this.isLike;
|
||||
Logger.info(TAG, `isLike= ${this.isLike}`);
|
||||
})
|
||||
Text($r('app.string.Num',"273.1"))
|
||||
.width(60)
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
|
||||
this.Item($r('app.media.app_icon'),$r('app.string.Num','36.3'),()=> {
|
||||
Logger.info(TAG, 'ic_message');
|
||||
})
|
||||
|
||||
Column(){
|
||||
Image(this.isCollect ? $r('app.media.app_icon') : $r('app.media.app_icon'))
|
||||
.width(35)
|
||||
.height(35)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(e=>{
|
||||
this.isCollect = !this.isCollect;
|
||||
Logger.info(TAG, `isCollect= ${this.isCollect}`);
|
||||
})
|
||||
Text($r('app.string.Num','18.9'))
|
||||
.width(60)
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
|
||||
this.Item($r('app.media.app_icon'),$r('app.string.Num','40.2'),()=> {
|
||||
Logger.info(TAG, 'ic_transmit');
|
||||
})
|
||||
Column(){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.width(50)
|
||||
.height(50)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.borderRadius(25)
|
||||
.margin({bottom: 20})
|
||||
.backgroundColor($r('app.color.COLOR_FFFFFF'))
|
||||
}
|
||||
.width('15%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('60%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
|
||||
Column(){
|
||||
if (!this.isPlay){
|
||||
Image($r('app.media.app_icon'))
|
||||
.width(640)
|
||||
.height(64)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.opacity(0.6)
|
||||
}
|
||||
}
|
||||
.id('video_action')
|
||||
.width('60%')
|
||||
.height('70%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.onClick(e=>{
|
||||
if (this.isPlay) {
|
||||
this.avPlayerModel.paused();
|
||||
} else {
|
||||
this.avPlayerModel.play();
|
||||
}
|
||||
this.isPlay = !this.isPlay;
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.alignContent(Alignment.Center)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
|
||||
@Builder
|
||||
Item(img: Resource, num: Resource, callback) {
|
||||
Column() {
|
||||
Image(img)
|
||||
.width(35)
|
||||
.height(35)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(e => {
|
||||
callback();
|
||||
})
|
||||
Text(num)
|
||||
.width(60)
|
||||
.height(20)
|
||||
.fontColor($r('app.color.COLOR_E6FFFFFF'))
|
||||
.fontSize(14)
|
||||
.fontFamily($r('app.string.Font_family_regular'))
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(60)
|
||||
.height(60)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import http from '@ohos.net.http';
|
||||
import Logger from '../utils/Logger';
|
||||
import Constant from '../utils/Constant';
|
||||
import NetworkModel from '../model/NetworkModel';
|
||||
import R from '../appsampled/data/R';
|
||||
|
||||
const TAG: string = '[ChatController]';
|
||||
|
||||
export default class ChatController {
|
||||
private networkModel: NetworkModel = new NetworkModel();
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @param username
|
||||
* @param msg
|
||||
* @returns
|
||||
*/
|
||||
public async sendMessage(username: string, msg: string): Promise<R> {
|
||||
Logger.info(TAG, `sendMessage username->${username},msg->${msg}`);
|
||||
let extraData = {
|
||||
msgType: 'system',
|
||||
receiver: username,
|
||||
templateCode: 'sampled',
|
||||
templateName: 'appsampled',
|
||||
testData: `{ \"content\": \"${msg}\" }`
|
||||
};
|
||||
Logger.info(TAG, `sendMessage extraData->${JSON.stringify(extraData)}`);
|
||||
let response = await this.networkModel.request(Constant.ACTION_SEND_MESSAGE, http.RequestMethod.POST, extraData, globalThis.userInfo.token);
|
||||
// 拿到响应中服务端返回的数据
|
||||
Logger.info(TAG, `sendMessage response.result->${JSON.stringify(response.result)}`);
|
||||
let data = response.result.toString();
|
||||
// 将其转成Json数据
|
||||
let jsonData = JSON.parse(data);
|
||||
Logger.info(TAG, `sendMessage jsonData->${JSON.stringify(jsonData)}`);
|
||||
// 统一的返回类型
|
||||
let result = new R();
|
||||
result.setSuccess(jsonData.success);
|
||||
result.setCode(jsonData.code);
|
||||
result.setMessage(jsonData.message);
|
||||
Logger.info(TAG, `sendMessage result->${JSON.stringify(result)}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 接收消息
|
||||
* @param id
|
||||
* @param callback
|
||||
*/
|
||||
public onMessage(id: string, callback) {
|
||||
Logger.info(TAG, `onMessage begin id:${id}`);
|
||||
this.networkModel.onMessage(id, globalThis.userInfo.token, (value) => {
|
||||
Logger.info(TAG, `onMessage value: ${value}`);
|
||||
let result = JSON.parse(value);
|
||||
Logger.info(TAG, `onMessage result: ${result}`);
|
||||
Logger.info(TAG, `onMessage msgTxt: ${result.msgTxt}`);
|
||||
if (result.msgTxt) {
|
||||
let message = JSON.parse(result.msgTxt);
|
||||
Logger.info(TAG, `onMessage content: ${message.content}`);
|
||||
callback(message.content)
|
||||
}
|
||||
});
|
||||
Logger.info(TAG, 'onMessage end');
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import http from '@ohos.net.http';
|
||||
import Logger from '../utils/Logger';
|
||||
import Constant from '../utils/Constant';
|
||||
import NetworkModel from '../model/NetworkModel';
|
||||
import LoginResult from '../appsampled/data/LoginResult';
|
||||
import R from '../appsampled/data/R';
|
||||
|
||||
const TAG: string = '[LoginController]';
|
||||
|
||||
export default class LoginController {
|
||||
private networkModel: NetworkModel = new NetworkModel();
|
||||
|
||||
public async login(phoneNumber: string, password: string): Promise<R> {
|
||||
Logger.info(TAG, `login phoneNumber->${phoneNumber},password->${password}`);
|
||||
let extraData = {
|
||||
username: phoneNumber,
|
||||
password: password
|
||||
};
|
||||
Logger.info(TAG, `login extraData->${JSON.stringify(extraData)}`)
|
||||
let response = await this.networkModel.request(Constant.ACTION_LOGIN, http.RequestMethod.POST, extraData);
|
||||
// 拿到响应中服务端返回的数据
|
||||
let data = response.result.toString();
|
||||
// 将其转成Json数据
|
||||
let jsonData = JSON.parse(data);
|
||||
Logger.info(TAG, `login jsonData->${JSON.stringify(jsonData)}`)
|
||||
// 统一的返回类型
|
||||
let result = new R();
|
||||
let loginResult = null;
|
||||
// result不为空则赋值其中的数据
|
||||
if (jsonData.result) {
|
||||
loginResult = new LoginResult();
|
||||
loginResult.setToken(jsonData.result.token);
|
||||
loginResult.setUsername(jsonData.result.userInfo.username);
|
||||
loginResult.setRealName(jsonData.result.userInfo.realname);
|
||||
loginResult.setAvatar(jsonData.result.userInfo.avatar);
|
||||
loginResult.setId(jsonData.result.userInfo.id);
|
||||
}
|
||||
result.setSuccess(jsonData.success);
|
||||
result.setCode(jsonData.code);
|
||||
result.setMessage(jsonData.message);
|
||||
// 设置返回的数据
|
||||
result.setData(loginResult);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import http from '@ohos.net.http';
|
||||
import Logger from '../utils/Logger';
|
||||
import Constant from '../utils/Constant';
|
||||
import NetworkModel from '../model/NetworkModel';
|
||||
|
||||
const TAG: string = '[UploadController]';
|
||||
|
||||
export default class UploadController {
|
||||
private networkModel: NetworkModel = new NetworkModel();
|
||||
|
||||
public async uploadFile(fileName: string): Promise<void> {
|
||||
Logger.info(TAG, `uploadFile start`);
|
||||
let extraData = {
|
||||
name: fileName,
|
||||
url: `${Constant.UPLOAD_URL}/${fileName}`
|
||||
};
|
||||
Logger.info(TAG, `uploadFile extraData->${JSON.stringify(extraData)}`);
|
||||
this.networkModel.uploadFile(Constant.ACTION_UPLOAD, fileName, (res) => {
|
||||
if (res) {
|
||||
Logger.info(TAG, `uploadFile success`);
|
||||
// 上传成功后请求服务器添加文件
|
||||
this.networkModel.request(Constant.ACTION_ADD_FILE, http.RequestMethod.POST, extraData, globalThis.userInfo.token);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import hilog from '@ohos.hilog';
|
||||
import window from '@ohos.window';
|
||||
import Logger from '../utils/Logger'
|
||||
|
||||
const TAG: string = '[EntryAbility]'
|
||||
|
||||
export default class EntryAbility extends UIAbility {
|
||||
onCreate(want, launchParam) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||
globalThis.abilityContext = this.context
|
||||
Logger.info(TAG, `onCreate:${this.context.cacheDir}`)
|
||||
Logger.info(TAG, `onCreate:${this.context.filesDir}`)
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||
// Main window is created, set main page for this ability
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
// pages/Index
|
||||
windowStage.loadContent('pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
return;
|
||||
}
|
||||
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
// Main window is destroyed, release UI related resources
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
// Ability has brought to foreground
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
// Ability has back to background
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
|
||||
}
|
||||
}
|
167
sample/AppSampleD/entry/src/main/ets/mock/MockData.ts
Normal file
167
sample/AppSampleD/entry/src/main/ets/mock/MockData.ts
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import User from '../appsampled/data/User';
|
||||
import Tool from '../appsampled/data/Tool';
|
||||
import { SearchResult, AudioInfo, VideoDetailInfo, VideoInfo } from '../appsampled/data/SearchResult'
|
||||
|
||||
export class MockInput {
|
||||
public static readonly TEST_INPUT_CONTENT_1: string = '黑夜问白天';
|
||||
public static readonly TEST_INPUT_CONTENT_2: string = '哦想';
|
||||
public static readonly TEST_INPUT_CONTENT_3: string = '我不愿让你一个人';
|
||||
}
|
||||
|
||||
export function getMockUser(): Array<User> {
|
||||
let userArr: Array<User> = [];
|
||||
userArr.push(new User('opposite user', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user1', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user2', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user3', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user4', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user5', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user6', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user7', $r('app.media.app_icon')));
|
||||
userArr.push(new User('user8', $r('app.media.app_icon')));
|
||||
return userArr;
|
||||
}
|
||||
|
||||
export function getMockTool(): Array<Tool> {
|
||||
let userArr: Array<Tool> = [];
|
||||
userArr.push(new Tool('打招呼', $r('app.media.app_icon')));
|
||||
userArr.push(new Tool('比个心', $r('app.media.app_icon')));
|
||||
userArr.push(new Tool('相册随机', $r('app.media.app_icon')));
|
||||
userArr.push(new Tool('以图换图', $r('app.media.app_icon')));
|
||||
userArr.push(new Tool('视频通话', $r('app.media.app_icon')));
|
||||
return userArr;
|
||||
}
|
||||
|
||||
export function getMockSearch(): Array<string> {
|
||||
let arr: Array<string> = [];
|
||||
arr.push('黑夜问白天');
|
||||
arr.push('哦想');
|
||||
arr.push('我不愿让你一个人');
|
||||
arr.push('test data 4');
|
||||
arr.push('测试数据 5');
|
||||
arr.push('test data 6');
|
||||
arr.push('测试数据 7');
|
||||
arr.push('test data 8');
|
||||
arr.push('测试数据 9');
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function getMockSearchResult(): Array<SearchResult> {
|
||||
let labelList: Array<Array<string>> = getLabelList();
|
||||
let audioInfoList: Array<Array<AudioInfo>> = getAudioInfoList();
|
||||
let videoDetailInfoList: Array<Array<VideoDetailInfo>> = getVideoDetailInfoList();
|
||||
let videoInfoList: Array<Array<VideoInfo>> = getVideoInfoList();
|
||||
let searchResultList: Array<SearchResult> = [
|
||||
new SearchResult(labelList[0], audioInfoList[0], videoDetailInfoList[0], videoInfoList[0]),
|
||||
new SearchResult(labelList[1], audioInfoList[1], videoDetailInfoList[1], videoInfoList[1]),
|
||||
new SearchResult(labelList[2], audioInfoList[2], videoDetailInfoList[2], videoInfoList[2]),
|
||||
];
|
||||
return searchResultList;
|
||||
}
|
||||
|
||||
function getLabelList(): Array<Array<string>> {
|
||||
let labelList: Array<Array<string>> = [
|
||||
['翻唱', '林俊杰', '合拍', '吉他弹唱', '女生', '歌曲教学'],
|
||||
['手势舞', '翻唱', '舞蹈', '安与骑兵', '广场舞', '疯狂梗传'],
|
||||
['伴奏', '五月天', '合唱', '林俊杰', '吉他弹唱', '钢琴']
|
||||
];
|
||||
return labelList;
|
||||
}
|
||||
|
||||
function getAudioInfoList(): Array<Array<AudioInfo>> {
|
||||
let audioInfoList: Array<Array<AudioInfo>> = [
|
||||
[
|
||||
new AudioInfo(1, '黑夜问白天', $r('app.media.app_icon'), '林俊杰', '02:03', '42.7万人使用', 'demo_video.mp4'),
|
||||
new AudioInfo(2, '黑夜问白天(TV)', $r('app.media.app_icon'), '林俊杰', '00:32', '22.4万使用', 'demo_video.mp4'),
|
||||
new AudioInfo(3, '黑夜问白天(演唱会)', $r('app.media.app_icon'), '林俊杰', '01:31', '35.6万使用', 'demo_video.mp4')
|
||||
],
|
||||
[
|
||||
new AudioInfo(1, '哦想', $r('app.media.app_icon'), '安与骑兵', '01:04', '1.7万人使用', 'demo_video.mp4'),
|
||||
new AudioInfo(2, '哦想(剪辑版)', $r('app.media.app_icon'), '安与骑兵', '00:30', '1685人使用', 'demo_video.mp4'),
|
||||
new AudioInfo(3, '哦想(Cover安与骑兵)', $r('app.media.app_icon'), '听月@国酒香', '01:04', '3309人使用', 'demo_video.mp4')
|
||||
],
|
||||
[
|
||||
new AudioInfo(1, '我不愿让你一个人', $r('app.media.app_icon'), '五月天', '01:00', '3.3万人使用', 'demo_video.mp4'),
|
||||
new AudioInfo(2, '我不愿让你一个人(剪辑版)', $r('app.media.app_icon'), '年岁并进', '00:35', '1.3万人使用', 'demo_video.mp4'),
|
||||
new AudioInfo(3, '我不愿让你一个人', $r('app.media.app_icon'), '五月天', '01:00', '982人使用', 'demo_video.mp4')
|
||||
]
|
||||
];
|
||||
return audioInfoList;
|
||||
}
|
||||
|
||||
function getVideoDetailInfoList(): Array<Array<VideoDetailInfo>> {
|
||||
let videoDetailInfoList: Array<Array<VideoDetailInfo>> = [
|
||||
[
|
||||
new VideoDetailInfo(1, '重拾快乐~', $r('app.media.app_icon'), '2021.10.12', '《黑夜问白天》林俊杰', '#林俊杰', '2.8w', '2188', '8487', '8062', 'demo_video.mp4', '韦德', $r('app.media.app_icon'), '贫穷让我们相遇', '3711'),
|
||||
new VideoDetailInfo(2, '俊杰观察', $r('app.media.app_icon'), '2022.02.28', '林俊杰清唱功底有多强', '#林俊杰#黑夜问白天#清唱', '49.3w', '3.6w', '2.7w', '4.4w', 'demo_video.mp4', '小桃冰茶', $r('app.media.app_icon'), '可以没有伴奏,不能没有提词器', '7.5万'),
|
||||
new VideoDetailInfo(3, '王巨星', $r('app.media.app_icon'), '2021.11.30', '好喜欢的歌啊啊啊啊', '#林俊杰', '65.5w', '1.5w', '2.3w', '2.8w', 'demo_video.mp4', 'LCCL', $r('app.media.app_icon'), '如果王巨星回复了我,我就好好生活', '2.4万')
|
||||
],
|
||||
[
|
||||
new VideoDetailInfo(1, '青鸟艺术声乐培训', $r('app.media.app_icon'), '2022.06.10', '给高考准备的一首歌', '#青鸟艺术声乐培训#高考#小助手', '85.6w', '3.6w', '6.2w', '6.0w', 'demo_video.mp4', '小小的太阳', $r('app.media.app_icon'), '我的喉咙只适合做核酸', '4.5万'),
|
||||
new VideoDetailInfo(2, 'Old马声乐小课堂', $r('app.media.app_icon'), '2022.11.16', '艺考选取曲子不能盲目跟风 挑选合适自己的作品最重要', '#音乐艺考生#声乐教学#无声卡演唱', '1.5w', '640', '1190', '2228', 'demo_video.mp4', 'zhongchuYYDS', $r('app.media.app_icon'), '感觉她咬字太流行了', '1486'),
|
||||
new VideoDetailInfo(3, '女王', $r('app.media.app_icon'), '2022.06.12', '安于骑兵演唱的《哦想》', '#聆听天籁之音#音乐分享', '3042', '244', '1174', '1319', 'demo_video.mp4', '用户5295745367339', $r('app.media.app_icon'), '还是原唱好', '101')
|
||||
],
|
||||
[
|
||||
new VideoDetailInfo(1, '一只喵', $r('app.media.app_icon'), '2023.05.29', '如果相识不能相恋 是不是还不如擦肩', '#五月天 #林俊杰 #我不愿让你一个人 #突然好想你', '21.4w', '1.7w', '2.7w', '3.2w', 'demo_video.mp4', '1', $r('app.media.app_icon'), '这四首歌放一起', '1.6万'),
|
||||
new VideoDetailInfo(2, '碑海北', $r('app.media.app_icon'), '2021.11.23', '我不愿让你一个人', '#奔向浪漫', '45.5w', '4.0w', '1.8w', '9.0w', 'demo_video.mp4', 'veafew520', $r('app.media.app_icon'), '为什么看这样的视频会哭?', '1.3万'),
|
||||
new VideoDetailInfo(3, '诺', $r('app.media.app_icon'), '2023.01.02', '懂你疼你更好的人', '#我不愿让你一个人', '14.4w', '5469', '9736', '1.4w', 'demo_video.mp4', '橘澜', $r('app.media.app_icon'), '不出意外的话这辈子都见不到了', '5554')
|
||||
]
|
||||
];
|
||||
return videoDetailInfoList;
|
||||
}
|
||||
|
||||
function getVideoInfoList(): Array<Array<VideoInfo>> {
|
||||
let videoInfoList: Array<Array<VideoInfo>> = [
|
||||
[
|
||||
new VideoInfo('重拾快乐~', $r('app.media.app_icon'), '2.8w', '《黑夜问白天》林俊杰', $r('app.media.app_icon')),
|
||||
new VideoInfo('王巨星', $r('app.media.app_icon'), '65.5w', '好喜欢的歌啊啊啊啊', $r('app.media.app_icon')),
|
||||
new VideoInfo('林俊杰', $r('app.media.app_icon'), '108.2w', '今晚大家开心吗', $r('app.media.app_icon')),
|
||||
new VideoInfo('俊杰观察', $r('app.media.app_icon'), '49.3w', '林俊杰清唱功底有多强?', $r('app.media.app_icon')),
|
||||
new VideoInfo('心跳乱了节奏', $r('app.media.app_icon'), '8467', '大哥又是压轴!熬最深的夜,看年少青春', $r('app.media.app_icon')),
|
||||
new VideoInfo('俊杰观察', $r('app.media.app_icon'), '17.2w', '在半空中真好...不会吵...被忽略的好歌!', $r('app.media.app_icon')),
|
||||
new VideoInfo('音雨蓝', $r('app.media.app_icon'), '4.9w', '湖南女子学院校园操场上,小哥翻唱林俊杰《黑夜问白天》', $r('app.media.app_icon')),
|
||||
new VideoInfo('会火大明星', $r('app.media.app_icon'), '3.3w', '没人可以拒绝黑夜问白天全程跟唱!', $r('app.media.app_icon')),
|
||||
new VideoInfo('曹雨航', $r('app.media.app_icon'), '59.0w', '等再见不如说一次再见#林俊杰', $r('app.media.app_icon')),
|
||||
new VideoInfo('音雨蓝', $r('app.media.app_icon'), '17.5w', '#大学生活#黑夜问白天翻唱', $r('app.media.app_icon'))
|
||||
],
|
||||
[
|
||||
new VideoInfo('民谣小酒馆', $r('app.media.app_icon'), '1.6w', '清澈的嗓音,宛如天籁之音', $r('app.media.app_icon')),
|
||||
new VideoInfo('Old马声乐小课堂', $r('app.media.app_icon'), '1.5w', '艺考选取曲子不能盲目跟风 挑选合适自己的作品最重要', $r('app.media.app_icon')),
|
||||
new VideoInfo('女王', $r('app.media.app_icon'), '3043', '安于骑兵演唱的《哦想》', $r('app.media.app_icon')),
|
||||
new VideoInfo('故里音乐', $r('app.media.app_icon'), '123', '有粉丝说想听#完整版必须安排上', $r('app.media.app_icon')),
|
||||
new VideoInfo('倾听音乐', $r('app.media.app_icon'), '7543', '《哦,想》被小女孩和老师唱红了全网', $r('app.media.app_icon')),
|
||||
new VideoInfo('安与骑兵', $r('app.media.app_icon'), '1.6w', '#安与骑兵 清唱《哦!想》', $r('app.media.app_icon')),
|
||||
new VideoInfo('688音乐视频', $r('app.media.app_icon'), '1.0w', '第18集 女孩刚刚开口歌声已经是我醉了', $r('app.media.app_icon')),
|
||||
new VideoInfo('忆路音乐', $r('app.media.app_icon'), '2.8w', '来听听原唱,哦了半天发现我这嗓子还是只适合做核酸', $r('app.media.app_icon')),
|
||||
new VideoInfo('郭一橙', $r('app.media.app_icon'), '1870', '#真人真唱#广场舞', $r('app.media.app_icon')),
|
||||
new VideoInfo('歌吧音乐', $r('app.media.app_icon'), '5.3w', '干净的声音,犹如天籁,生活明朗,万物可爱', $r('app.media.app_icon'))
|
||||
],
|
||||
[
|
||||
new VideoInfo('五月天饭团', $r('app.media.app_icon'), '45.8w', '#五月天 五月天的歌里什么都有,唯独没有纠缠', $r('app.media.app_icon')),
|
||||
new VideoInfo('碑海北', $r('app.media.app_icon'), '45.5w', '我不愿让你一个人', $r('app.media.app_icon')),
|
||||
new VideoInfo('碑海北', $r('app.media.app_icon'), '33.7w', '一段健康的感情可以让你每晚平静入睡', $r('app.media.app_icon')),
|
||||
new VideoInfo('一只喵', $r('app.media.app_icon'), '21.4w', '如果相识不能相恋 是不是还不如擦肩', $r('app.media.app_icon')),
|
||||
new VideoInfo('良友音乐409', $r('app.media.app_icon'), '7788', '五月天的《我不愿让你一个人》', $r('app.media.app_icon')),
|
||||
new VideoInfo('五月天饭团', $r('app.media.app_icon'), '4.5w', '#五月天 life版《我不愿让你一个人》', $r('app.media.app_icon')),
|
||||
new VideoInfo('橘子调', $r('app.media.app_icon'), '2.1w', '五月天的歌#后来的我们', $r('app.media.app_icon')),
|
||||
new VideoInfo('俊杰观察', $r('app.media.app_icon'), '7.1w', '也许未来你会找到懂你疼你更好的人', $r('app.media.app_icon')),
|
||||
new VideoInfo('诺', $r('app.media.app_icon'), '14.4w', '#我不愿让你一个人 懂你疼你更好的人', $r('app.media.app_icon')),
|
||||
new VideoInfo('孤思路', $r('app.media.app_icon'), '11.0w', '和@音乐人青峰(合拍)一起', $r('app.media.app_icon'))
|
||||
]
|
||||
];
|
||||
return videoInfoList;
|
||||
}
|
139
sample/AppSampleD/entry/src/main/ets/model/AVPlayerModel.ts
Normal file
139
sample/AppSampleD/entry/src/main/ets/model/AVPlayerModel.ts
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import media from '@ohos.multimedia.media';
|
||||
import Logger from '../utils/Logger'
|
||||
|
||||
const TAG: string = '[AVPlayerModel]'
|
||||
|
||||
export default class AVPlayerModel {
|
||||
private avPlayer: media.AVPlayer;
|
||||
private count: number = 1;
|
||||
private surfaceID: string = ''; // surfaceID用于播放画面显示,具体的值需要通过Xcomponent接口获取,相关文档链接见上面Xcomponent创建方法
|
||||
private isSeek: boolean = true; // 用于区分模式是否支持seek操作
|
||||
|
||||
private context;
|
||||
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
// 注册avplayer回调函数
|
||||
setAVPlayerCallback() {
|
||||
// seek操作结果回调函数
|
||||
this.avPlayer.on('seekDone', (seekDoneTime) => {
|
||||
Logger.info(TAG, `AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
|
||||
})
|
||||
// error回调监听函数,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
|
||||
this.avPlayer.on('error', (err) => {
|
||||
Logger.info(TAG, `Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
|
||||
this.avPlayer.reset(); // 调用reset重置资源,触发idle状态
|
||||
})
|
||||
// 状态机变化回调函数
|
||||
this.avPlayer.on('stateChange', async (state, reason) => {
|
||||
switch (state) {
|
||||
case 'idle': // 成功调用reset接口后触发该状态机上报
|
||||
Logger.info(TAG, 'AVPlayer state idle called.');
|
||||
this.avPlayer.release(); // 调用release接口销毁实例对象
|
||||
break;
|
||||
case 'initialized': // avplayer 设置播放源后触发该状态上报
|
||||
Logger.info(TAG, 'AVPlayerstate initialized called.');
|
||||
if (this.surfaceID) {
|
||||
this.avPlayer.surfaceId = this.surfaceID; // 设置显示画面,当播放的资源为纯音频时无需设置
|
||||
}
|
||||
this.avPlayer.prepare().then(() => {
|
||||
Logger.info(TAG, 'AVPlayer prepare succeeded.');
|
||||
}, (err) => {
|
||||
Logger.info(TAG, `Invoke prepare failed, code is ${err.code}, message is ${err.message}`);
|
||||
});
|
||||
break;
|
||||
case 'prepared': // prepare调用成功后上报该状态机
|
||||
Logger.info(TAG, 'AVPlayer state prepared called.');
|
||||
this.avPlayer.play(); // 调用播放接口开始播放
|
||||
break;
|
||||
case 'playing': // play成功调用后触发该状态机上报
|
||||
Logger.info(TAG, 'AVPlayer state playing called.');
|
||||
if (this.count !== 0) {
|
||||
if (this.isSeek) {
|
||||
Logger.info(TAG, 'AVPlayer start to seek.');
|
||||
} else {
|
||||
// 当播放模式不支持seek操作时继续播放到结尾
|
||||
Logger.info(TAG, 'AVPlayer wait to play end.');
|
||||
}
|
||||
} else {
|
||||
this.avPlayer.pause(); // 调用暂停接口暂停播放
|
||||
}
|
||||
this.count++;
|
||||
break;
|
||||
case 'paused': // pause成功调用后触发该状态机上报
|
||||
Logger.info(TAG, 'AVPlayer state paused called.');
|
||||
this.avPlayer.loop = true;
|
||||
break;
|
||||
case 'completed': // 播放结束后触发该状态机上报
|
||||
Logger.info(TAG, 'AVPlayer state completed called.');
|
||||
this.avPlayer.play(); // 再次播放接口开始播放
|
||||
break;
|
||||
case 'stopped': // stop接口成功调用后触发该状态机上报
|
||||
Logger.info(TAG, 'AVPlayer state stopped called.');
|
||||
this.avPlayer.reset(); // 调用reset接口初始化avplayer状态
|
||||
break;
|
||||
case 'released':
|
||||
Logger.info(TAG, 'AVPlayer state released called.');
|
||||
break;
|
||||
default:
|
||||
Logger.info(TAG, 'AVPlayer state unknown called.');
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public play(){
|
||||
if (this.avPlayer) {
|
||||
this.avPlayer.play();
|
||||
}
|
||||
}
|
||||
public paused(){
|
||||
if (this.avPlayer) {
|
||||
this.avPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
// 以下demo为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
|
||||
async avPlayerFdSrcDemo(avName: string, surfaceID?: string) {
|
||||
if (surfaceID) {
|
||||
this.surfaceID = surfaceID;
|
||||
}
|
||||
// 创建avPlayer实例对象
|
||||
this.avPlayer = await media.createAVPlayer();
|
||||
// 创建状态机变化回调函数
|
||||
this.setAVPlayerCallback();
|
||||
// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址
|
||||
// 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度
|
||||
let context = this.context;
|
||||
let fileDescriptor = await context.resourceManager.getRawFd(avName);
|
||||
this.isSeek = false; // 支持seek操作
|
||||
// 为fdSrc赋值触发initialized状态机上报
|
||||
this.avPlayer.fdSrc = fileDescriptor;
|
||||
}
|
||||
|
||||
// 以下demo为通过url设置网络地址来实现播放直播码流的demo
|
||||
async avPlayerLiveDemo() {
|
||||
// 创建avPlayer实例对象
|
||||
this.avPlayer = await media.createAVPlayer();
|
||||
// 创建状态机变化回调函数
|
||||
this.setAVPlayerCallback();
|
||||
this.isSeek = false; // 不支持seek操作
|
||||
this.avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; // 播放hls网络直播码流
|
||||
}
|
||||
}
|
301
sample/AppSampleD/entry/src/main/ets/model/CameraModel.ts
Normal file
301
sample/AppSampleD/entry/src/main/ets/model/CameraModel.ts
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import camera from '@ohos.multimedia.camera'
|
||||
import image from '@ohos.multimedia.image'
|
||||
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
|
||||
import media from '@ohos.multimedia.media';
|
||||
import deviceInfo from '@ohos.deviceInfo';
|
||||
import type common from '@ohos.app.ability.common'
|
||||
import MediaModel from './MediaModel'
|
||||
import Logger from '../utils/Logger'
|
||||
|
||||
const TAG: string = '[CameraModel]'
|
||||
|
||||
const CAMERASIZE = {
|
||||
WIDTH: 1920,
|
||||
HEIGHT: 1080
|
||||
}
|
||||
|
||||
/**
|
||||
* 相机服务
|
||||
*/
|
||||
export default class CameraModel {
|
||||
private cameraInput: camera.CameraInput;
|
||||
private previewOutput: camera.PreviewOutput;
|
||||
private fileAsset: mediaLibrary.FileAsset;
|
||||
private photoUri: string = '';
|
||||
private mediaModel: MediaModel;
|
||||
private fd: number = -1;
|
||||
private receiver: image.ImageReceiver;
|
||||
private context: any;
|
||||
private cameraManager: camera.CameraManager;
|
||||
private cameras: Array<camera.CameraDevice>;
|
||||
private photoOutPut: camera.PhotoOutput;
|
||||
private captureSession: camera.CaptureSession;
|
||||
private cameraOutputCapability: camera.CameraOutputCapability;
|
||||
private videoOutput: camera.VideoOutput;
|
||||
private avRecorder: media.AVRecorder;
|
||||
|
||||
private avRecorderProfile: media.VideoRecorderProfile = {
|
||||
audioBitrate: 48000,
|
||||
audioChannels: 2,
|
||||
audioCodec: media.CodecMimeType.AUDIO_AAC,
|
||||
audioSampleRate: 48000,
|
||||
fileFormat: media.ContainerFormatType.CFT_MPEG_4,
|
||||
videoBitrate: 2000000,
|
||||
videoCodec: media.CodecMimeType.VIDEO_MPEG4,
|
||||
videoFrameWidth: 640,
|
||||
videoFrameHeight: 480,
|
||||
videoFrameRate: 30
|
||||
}
|
||||
|
||||
private videoSourceType = 0;
|
||||
|
||||
constructor(context: common.Context) {
|
||||
this.context = context
|
||||
this.mediaModel = MediaModel.getMediaInstance(context)
|
||||
// 服务端代码,创建ImageReceiver
|
||||
this.receiver = image.createImageReceiver(CAMERASIZE.WIDTH, CAMERASIZE.HEIGHT, 4, 8) // 4表示生成的图像格式,8表示用户希望同时访问的最大图像数
|
||||
Logger.info(TAG, `createImageReceiver`)
|
||||
// 获取Surface ID
|
||||
this.receiver.getReceivingSurfaceId((surfaceId) => {
|
||||
Logger.info(TAG, `getReceivingSurfaceId surfaceId is ${surfaceId}`)
|
||||
})
|
||||
// 注册Surface的监听,在surface的buffer准备好后触发
|
||||
this.receiver.on('imageArrival', () => {
|
||||
Logger.info(TAG, `imageArrival`)
|
||||
// 去获取Surface中最新的buffer
|
||||
this.receiver.readNextImage((err, image) => {
|
||||
Logger.info(TAG, `readNextImage`)
|
||||
if (err || image === undefined) {
|
||||
Logger.error(TAG, `failed to get valid image`)
|
||||
return
|
||||
}
|
||||
image.getComponent(4, (errMsg, img) => {
|
||||
// 4表示图像类型为JPEG
|
||||
// 消费component.byteBuffer,例如:将buffer内容保存成图片。
|
||||
Logger.info(TAG, `getComponent`)
|
||||
if (errMsg || img === undefined) {
|
||||
Logger.info(TAG, `failed to get valid buffer`)
|
||||
return
|
||||
}
|
||||
let buffer = new ArrayBuffer(4096)
|
||||
if (img.byteBuffer) {
|
||||
buffer = img.byteBuffer
|
||||
} else {
|
||||
Logger.error(TAG, `img.byteBuffer is undefined`)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建相机
|
||||
*/
|
||||
async createCamera(surfaceId: string): Promise<void> {
|
||||
Logger.info(TAG, `initCamera surfaceId:${surfaceId}`);
|
||||
// await this.releaseCamera();
|
||||
Logger.info(TAG, `deviceInfo.deviceType = ${deviceInfo.deviceType}`);
|
||||
if (deviceInfo.deviceType === 'default') {
|
||||
Logger.info(TAG, `deviceInfo.deviceType default 1 = ${deviceInfo.deviceType}`);
|
||||
this.videoSourceType = 1;
|
||||
Logger.info(TAG, `deviceInfo.deviceType default 2 = ${deviceInfo.deviceType}`);
|
||||
} else {
|
||||
Logger.info(TAG, `deviceInfo.deviceType other 1 = ${deviceInfo.deviceType}`);
|
||||
this.videoSourceType = 0;
|
||||
Logger.info(TAG, `deviceInfo.deviceType other 2 = ${deviceInfo.deviceType}`);
|
||||
}
|
||||
Logger.info(TAG, `getCameraManager begin`);
|
||||
try {
|
||||
Logger.info(TAG, `getCameraManager try begin`);
|
||||
this.cameraManager = camera.getCameraManager(this.context);
|
||||
Logger.info(TAG, `getCameraManager try end`);
|
||||
} catch (e) {
|
||||
Logger.info(TAG, `getCameraManager catch e:${JSON.stringify(e)}`);
|
||||
}
|
||||
Logger.info(TAG, `getCameraManager end`);
|
||||
Logger.info(TAG, `getCameraManager ${JSON.stringify(this.cameraManager)}`);
|
||||
this.cameras = this.cameraManager.getSupportedCameras();
|
||||
Logger.info(TAG, `createCamera get cameras ${this.cameras.length}`);
|
||||
if (this.cameras.length === 0) {
|
||||
Logger.info(TAG, 'cannot get cameras');
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info(TAG, `createCamera cameras=${this.cameras}`);
|
||||
let mCamera = this.cameras[0];
|
||||
Logger.info(TAG, `createCamera mCamera=${mCamera}`);
|
||||
this.cameraInput = this.cameraManager.createCameraInput(mCamera);
|
||||
Logger.info(TAG, `createCamera cameraInput=${this.cameraInput}`);
|
||||
this.cameraInput.open();
|
||||
Logger.info(TAG, 'createCameraInput');
|
||||
this.cameraOutputCapability = this.cameraManager.getSupportedOutputCapability(mCamera);
|
||||
let previewProfile = this.cameraOutputCapability.previewProfiles[0];
|
||||
this.previewOutput = this.cameraManager.createPreviewOutput(
|
||||
previewProfile,
|
||||
surfaceId
|
||||
);
|
||||
Logger.info(TAG, 'createPreviewOutput');
|
||||
let rSurfaceId = await this.receiver.getReceivingSurfaceId();
|
||||
let photoProfile = this.cameraOutputCapability.photoProfiles[0];
|
||||
this.photoOutPut = this.cameraManager.createPhotoOutput(
|
||||
photoProfile,
|
||||
rSurfaceId
|
||||
);
|
||||
this.captureSession = this.cameraManager.createCaptureSession();
|
||||
Logger.info(TAG, 'createCaptureSession');
|
||||
this.captureSession.beginConfig();
|
||||
Logger.info(TAG, 'beginConfig');
|
||||
this.captureSession.addInput(this.cameraInput);
|
||||
this.captureSession.addOutput(this.previewOutput);
|
||||
this.captureSession.addOutput(this.photoOutPut);
|
||||
await this.captureSession.commitConfig();
|
||||
await this.captureSession.start();
|
||||
Logger.info(TAG, 'captureSession start');
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始录像
|
||||
*/
|
||||
async startVideo(): Promise<void> {
|
||||
Logger.info(TAG, 'startVideo begin');
|
||||
Logger.info(TAG, 'startVideo 1');
|
||||
await this.captureSession.stop();
|
||||
Logger.info(TAG, 'startVideo 2');
|
||||
this.captureSession.beginConfig();
|
||||
Logger.info(TAG, 'startVideo 3');
|
||||
if (this.videoOutput) {
|
||||
try {
|
||||
Logger.info(TAG, 'startVideo 4');
|
||||
this.captureSession.removeOutput(this.videoOutput);
|
||||
} catch (e) {
|
||||
Logger.info(TAG, `startVideo catch e:${e}`);
|
||||
}
|
||||
}
|
||||
if (this.videoOutput) {
|
||||
try {
|
||||
Logger.info(TAG, 'startVideo 5');
|
||||
this.captureSession.removeOutput(this.videoOutput);
|
||||
Logger.info(TAG, 'startVideo 6');
|
||||
} catch (e) {
|
||||
Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
|
||||
}
|
||||
try {
|
||||
Logger.info(TAG, 'startVideo release');
|
||||
await this.videoOutput.release();
|
||||
} catch (e) {
|
||||
Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
|
||||
}
|
||||
}
|
||||
Logger.info(TAG, 'startVideo 7');
|
||||
this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.VIDEO);
|
||||
Logger.info(TAG, `startVideo fileAsset:${this.fileAsset}`);
|
||||
this.fd = await this.mediaModel.getFdPath(this.fileAsset);
|
||||
Logger.info(TAG, `startVideo fd:${this.fd}`);
|
||||
this.avRecorder = await media.createAVRecorder();
|
||||
|
||||
Logger.info(TAG, `startVideo into createAVRecorder:${this.avRecorder}`);
|
||||
if (this.avRecorder != null) {
|
||||
Logger.info(TAG, `startVideo createAVRecorder success:${this.avRecorder}`);
|
||||
|
||||
let videoConfig: media.VideoRecorderConfig = {
|
||||
audioSourceType: 1,
|
||||
videoSourceType: this.videoSourceType,
|
||||
profile: this.avRecorderProfile,
|
||||
url: `fd://${this.fd}`,
|
||||
rotation: 0
|
||||
}
|
||||
|
||||
Logger.info(TAG, `startVideo videoConfig:${JSON.stringify(videoConfig)}`);
|
||||
try {
|
||||
await this.avRecorder.prepare(videoConfig);
|
||||
} catch (err) {
|
||||
Logger.info(TAG, `startVideo err:${err}`);
|
||||
}
|
||||
|
||||
Logger.info(TAG, `startVideo prepare`);
|
||||
let videoId = await this.avRecorder.getInputSurface();
|
||||
let videoProfile = this.cameraOutputCapability.videoProfiles[0];
|
||||
Logger.info(TAG, `startVideo capability.videoProfiles[]=: ${JSON.stringify(this.cameraOutputCapability.videoProfiles)}`);
|
||||
Logger.info(TAG, `startVideo videoProfile:${JSON.stringify(videoProfile)}`);
|
||||
this.videoOutput = this.cameraManager.createVideoOutput(videoProfile, videoId);
|
||||
Logger.info(TAG, `startVideo videoOutput:${this.videoOutput}`);
|
||||
this.captureSession.addOutput(this.videoOutput);
|
||||
Logger.info(TAG, `startVideo addOutput`);
|
||||
await this.captureSession.commitConfig();
|
||||
Logger.info(TAG, `startVideo commitConfig`);
|
||||
await this.captureSession.start();
|
||||
Logger.info(TAG, `startVideo commitConfig captureSession`);
|
||||
await this.videoOutput.start();
|
||||
Logger.info(TAG, `startVideo commitConfig videoOutput`);
|
||||
await this.avRecorder.start();
|
||||
Logger.info(TAG, 'startVideo end');
|
||||
|
||||
} else {
|
||||
Logger.info(TAG, `startVideo createAVRecorder fail, error null`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止录像
|
||||
*/
|
||||
async stopVideo(): Promise<string> {
|
||||
Logger.info(TAG, 'stopVideo called');
|
||||
await this.avRecorder.stop();
|
||||
await this.avRecorder.release();
|
||||
await this.videoOutput.stop();
|
||||
// 停止结束时复制录制的视频至沙箱cache目录中
|
||||
let fileName = await this.copyVideo();
|
||||
await this.fileAsset.close(this.fd);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制视频至video
|
||||
*/
|
||||
async copyVideo(): Promise<string> {
|
||||
let url = this.fileAsset.uri;
|
||||
Logger.info(TAG, `stopVideo uri:${url}`);
|
||||
let fileName = await this.mediaModel.copyVideo(this.fd);
|
||||
Logger.info(TAG, `stopVideo fileName:${fileName}`);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭相机
|
||||
*/
|
||||
async releaseCamera(): Promise<void> {
|
||||
Logger.info(TAG, `releaseCamera start`);
|
||||
if (this.cameraInput) {
|
||||
await this.cameraInput.close();
|
||||
}
|
||||
if (this.previewOutput) {
|
||||
await this.previewOutput.release();
|
||||
}
|
||||
if (this.photoOutPut) {
|
||||
await this.photoOutPut.release();
|
||||
}
|
||||
if (this.videoOutput) {
|
||||
await this.videoOutput.release();
|
||||
}
|
||||
if (this.captureSession) {
|
||||
await this.captureSession.release();
|
||||
}
|
||||
Logger.info(TAG, `releaseCamera end`);
|
||||
}
|
||||
}
|
||||
|
89
sample/AppSampleD/entry/src/main/ets/model/MediaModel.ts
Normal file
89
sample/AppSampleD/entry/src/main/ets/model/MediaModel.ts
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type common from '@ohos.app.ability.common'
|
||||
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
|
||||
import fs from '@ohos.file.fs'
|
||||
import DateTimeUtil from '../utils/DateTimeUtil';
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG = '[MediaModel]';
|
||||
|
||||
export default class MediaModel {
|
||||
private mediaLibraryTest: mediaLibrary.MediaLibrary = undefined;
|
||||
private static mediaInstance: MediaModel = undefined;
|
||||
|
||||
constructor() {
|
||||
this.mediaLibraryTest = mediaLibrary.getMediaLibrary(globalThis.abilityContext);
|
||||
}
|
||||
|
||||
public static getMediaInstance(context: common.Context): MediaModel {
|
||||
if (this.mediaInstance === undefined) {
|
||||
this.mediaInstance = new MediaModel();
|
||||
}
|
||||
return this.mediaInstance;
|
||||
}
|
||||
|
||||
async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> {
|
||||
let result = {
|
||||
prefix: 'VID_', suffix: '.mp4', directory: mediaLibrary.DirectoryType.DIR_VIDEO
|
||||
}
|
||||
let info = result;
|
||||
Logger.info(TAG, `createAndGetUri info = ${info}`);
|
||||
let dateTimeUtil = new DateTimeUtil();
|
||||
let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`;
|
||||
let displayName = `${info.prefix}${name}${info.suffix}`;
|
||||
Logger.info(TAG, `createAndGetUri displayName = ${displayName},mediaType = ${mediaType}`);
|
||||
let publicPath = await this.mediaLibraryTest.getPublicDirectory(info.directory);
|
||||
Logger.info(TAG, `createAndGetUri publicPath = ${publicPath}/${displayName}`);
|
||||
let fileAsset = null;
|
||||
try {
|
||||
fileAsset = await this.mediaLibraryTest.createAsset(mediaType, displayName, publicPath);
|
||||
} catch (err) {
|
||||
Logger.info(TAG, `createAndGetUri err = ${err}`);
|
||||
}
|
||||
Logger.info(TAG, `createAndGetUri fileAsset = ${fileAsset}`);
|
||||
return fileAsset;
|
||||
}
|
||||
|
||||
async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> {
|
||||
let fd = await fileAsset.open('Rw');
|
||||
Logger.info(TAG, `fd = ${fd}`);
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制视频至沙箱
|
||||
* @param fd
|
||||
* @returns
|
||||
*/
|
||||
async copyVideo(fd: number): Promise<string> {
|
||||
// 将录制视频存入沙箱路径
|
||||
let mContext: common.Context = globalThis.abilityContext;
|
||||
Logger.info(TAG, `this.fd = ${JSON.stringify(fd)}`);
|
||||
// upload只可访问的沙箱路径:/data/app/el2/100/base/com.samples.appsampled/haps/entry/cache/
|
||||
Logger.info(TAG, `mContext.cacheDir = ${JSON.stringify(mContext.cacheDir)}`);
|
||||
let fileName = new Date().getTime().toString();
|
||||
let imagePath = `${mContext.cacheDir}/${fileName}.mp4`;
|
||||
Logger.info(TAG, `this.imagePath = ${JSON.stringify(imagePath)}`);
|
||||
try {
|
||||
fs.copyFileSync(fd, imagePath);
|
||||
return `${fileName}.mp4`;
|
||||
} catch (err) {
|
||||
Logger.info(TAG, `this.err = ${err}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
128
sample/AppSampleD/entry/src/main/ets/model/NetworkModel.ts
Normal file
128
sample/AppSampleD/entry/src/main/ets/model/NetworkModel.ts
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import http from '@ohos.net.http';
|
||||
import request from '@ohos.request';
|
||||
import webSocket from '@ohos.net.webSocket';
|
||||
import Logger from '../utils/Logger';
|
||||
import Constant from '../utils/Constant';
|
||||
|
||||
const TAG: string = '[NetworkModel]';
|
||||
|
||||
export default class NetworkModel {
|
||||
private httpRequest: http.HttpRequest = http.createHttp();
|
||||
private mWebSocket: webSocket.WebSocket = webSocket.createWebSocket();
|
||||
|
||||
public async request(action: string, method: http.RequestMethod, extraData: Object, token?: string): Promise<http.HttpResponse> {
|
||||
Logger.info(TAG, `request action->${JSON.stringify(action)}, method->${JSON.stringify(method)}, extraData->${JSON.stringify(extraData)},token->${JSON.stringify(token)}`)
|
||||
let header = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Access-Token': token
|
||||
}
|
||||
let response = await this.httpRequest.request(
|
||||
Constant.URL + action,
|
||||
{
|
||||
method: method,
|
||||
header: header,
|
||||
extraData: extraData,
|
||||
expectDataType: http.HttpDataType.STRING,
|
||||
usingCache: true,
|
||||
priority: 1,
|
||||
connectTimeout: 60000,
|
||||
readTimeout: 60000,
|
||||
usingProtocol: http.HttpProtocol.HTTP1_1,
|
||||
usingProxy: false,
|
||||
});
|
||||
Logger.info(TAG, `request response->${JSON.stringify(response)}`)
|
||||
return response;
|
||||
|
||||
}
|
||||
|
||||
public uploadFile(action: string, fileName: string, callback): void {
|
||||
Logger.info(TAG, `upload file create action = ${action}, fileName = ${fileName}`)
|
||||
Logger.info(TAG, `upload url = ${Constant.URL + action}`)
|
||||
Logger.info(TAG, `upload token = ${globalThis.userInfo.token}`)
|
||||
let uploadTask: request.UploadTask;
|
||||
let uploadConfig = {
|
||||
url: Constant.URL + action,
|
||||
header: {
|
||||
'X-Access-Token': globalThis.userInfo.token, 'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
method: "POST",
|
||||
files: [{
|
||||
filename: fileName, name: "file", uri: `internal://cache/${fileName}`, type: "mp4"
|
||||
}],
|
||||
data: [{
|
||||
name: 'biz', value: Constant.UPLOAD_URL
|
||||
}],
|
||||
};
|
||||
Logger.info(TAG, 'upload uploadConfig,' + JSON.stringify(uploadConfig))
|
||||
try {
|
||||
Logger.info(TAG, 'upload start')
|
||||
request.uploadFile(globalThis.abilityContext, uploadConfig).then((data) => {
|
||||
uploadTask = data;
|
||||
Logger.info(TAG, 'upload end 1')
|
||||
uploadTask.on('complete', (taskState: Array<request.TaskState>) => {
|
||||
Logger.info(TAG, 'upload complete ' + JSON.stringify(taskState))
|
||||
callback(true)
|
||||
});
|
||||
Logger.info(TAG, 'upload end 2')
|
||||
}).catch((err) => {
|
||||
Logger.error(TAG, `Failed to request the upload. ${err}`);
|
||||
});
|
||||
} catch (err) {
|
||||
Logger.error(TAG, `Failed to request the upload. Code: ${err.code}, message: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async onMessage(id: string, token: string, callback): Promise<void> {
|
||||
Logger.info(TAG, `onMessage on connect begin: URL= ${Constant.ACTION_ON_MESSAGE_URL + id}`);
|
||||
|
||||
// 连接websocket
|
||||
this.mWebSocket.connect(Constant.ACTION_ON_MESSAGE_URL + id, (err, value) => {
|
||||
if (!err) {
|
||||
Logger.info(TAG, 'onMessage Connected successfully');
|
||||
|
||||
// 连接成功订阅消息
|
||||
this.mWebSocket.on('message', (err, value) => {
|
||||
Logger.info(TAG, `onMessage on message, message:${value}`);
|
||||
if (!err) {
|
||||
Logger.info(TAG, 'onMessage receive successfully');
|
||||
callback(value);
|
||||
} else {
|
||||
Logger.info(TAG, `onMessage receive failed. Err: ${JSON.stringify(err)}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 连接成功订阅错误信息,出现错误则关闭webSocket
|
||||
this.mWebSocket.on('error', (err) => {
|
||||
Logger.info(TAG, `onMessage on error, error: ${JSON.stringify(err)}`);
|
||||
this.mWebSocket.close((err, value) => {
|
||||
if (!err) {
|
||||
Logger.info(TAG, 'onMessage Connection closed successfully');
|
||||
} else {
|
||||
Logger.info(TAG, `onMessage Failed to close the connection. Err: ${JSON.stringify(err)}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
Logger.info(TAG, `onMessage Connection failed. Err: ${JSON.stringify(err)}`);
|
||||
}
|
||||
});
|
||||
|
||||
Logger.info(TAG, `onMessage on connect end`);
|
||||
|
||||
}
|
||||
}
|
144
sample/AppSampleD/entry/src/main/ets/pages/Index.ets
Normal file
144
sample/AppSampleD/entry/src/main/ets/pages/Index.ets
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@ohos.router';
|
||||
import Logger from '../utils/Logger'
|
||||
import MessagePage from '../component/MessageComponent'
|
||||
import VideoComponent from '../component/VideoComponent'
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import Constant from '../utils/Constant';
|
||||
|
||||
const TAG: string = '[Index]'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State selectDownIndex: number = 0; // 底部选择索引
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
*/
|
||||
loginVerification(): boolean {
|
||||
// 验证是否登录
|
||||
if (globalThis.userInfo == null || globalThis.userInfo == undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pageTransition() {
|
||||
// 禁止首页页面转场效果
|
||||
PageTransitionEnter({ type: RouteType.None, duration: 0 })
|
||||
PageTransitionExit({ type: RouteType.None, duration: 0 })
|
||||
}
|
||||
|
||||
onPageShow() {
|
||||
router.clear();
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
||||
Column() {
|
||||
if (this.selectDownIndex === 0) {
|
||||
VideoComponent()
|
||||
} else if (this.selectDownIndex === 1) {
|
||||
|
||||
} else if (this.selectDownIndex === 2 && this.loginVerification()) {
|
||||
MessagePage()
|
||||
} else if (this.selectDownIndex === 3) {
|
||||
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('92%')
|
||||
|
||||
// 底部操作栏
|
||||
Row() {
|
||||
Text($r('app.string.Home_page'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectDownIndex === 0 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCF1F3F5'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ left: 10 })
|
||||
.onClick(e => {
|
||||
this.selectDownIndex = 0;
|
||||
Logger.info(TAG, `onClick this is ${this.selectDownIndex}`)
|
||||
})
|
||||
Text($r('app.string.Friend'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectDownIndex === 1 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCF1F3F5'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ left: 10 })
|
||||
.onClick(e => {
|
||||
this.selectDownIndex = 1;
|
||||
Logger.info(TAG, `onClick this is ${this.selectDownIndex}`)
|
||||
})
|
||||
Image($r('app.media.app_icon'))
|
||||
.id('index_main')
|
||||
.width(80)
|
||||
.height(40)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(e => {
|
||||
Logger.info(TAG, `onClick this is ${this.selectDownIndex}`)
|
||||
// 跳转页面前暂停本地视频
|
||||
emitter.emit({ eventId: Constant.EVENT_PAUSED_INDEX });
|
||||
// 验证是否登录
|
||||
if (!this.loginVerification()) {
|
||||
router.pushUrl({ url: 'appsampled/pages/Login' })
|
||||
return;
|
||||
}
|
||||
router.pushUrl({ url: 'appsampled/pages/CameraPage' })
|
||||
})
|
||||
Text($r('app.string.Message'))
|
||||
.id('index_message')
|
||||
.height('100%')
|
||||
.fontColor(this.selectDownIndex === 2 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCF1F3F5'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ right: 10 })
|
||||
.onClick(e => {
|
||||
this.selectDownIndex = 2;
|
||||
Logger.info(TAG, `onClick this is ${this.selectDownIndex}`)
|
||||
// 跳转页面前暂停本地视频
|
||||
emitter.emit({ eventId: Constant.EVENT_PAUSED_INDEX });
|
||||
// 验证是否登录
|
||||
if (!this.loginVerification()) {
|
||||
router.pushUrl({ url: 'appsampled/pages/Login' })
|
||||
}
|
||||
})
|
||||
Text($r('app.string.Me'))
|
||||
.height('100%')
|
||||
.fontColor(this.selectDownIndex === 3 ? $r('app.color.COLOR_FFFFFF') : $r('app.color.COLOR_CCF1F3F5'))
|
||||
.fontSize(22)
|
||||
.fontFamily($r('app.string.Font_family_medium'))
|
||||
.margin({ left: 10 })
|
||||
.onClick(e => {
|
||||
this.selectDownIndex = 3;
|
||||
Logger.info(TAG, `onClick this is ${this.selectDownIndex}`)
|
||||
})
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('8%')
|
||||
.justifyContent(FlexAlign.SpaceAround)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor($r('app.color.COLOR_000000'))
|
||||
}
|
||||
}
|
||||
|
||||
|
34
sample/AppSampleD/entry/src/main/ets/utils/Constant.ts
Normal file
34
sample/AppSampleD/entry/src/main/ets/utils/Constant.ts
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export default class Constant {
|
||||
|
||||
// URL
|
||||
public static readonly URL: string = 'http://192.168.18.165:8080/jeecg-boot';
|
||||
public static readonly UPLOAD_URL: string = 'appsampled';
|
||||
public static readonly ACTION_LOGIN: string = '/sys/login';
|
||||
public static readonly ACTION_UPLOAD: string = '/sys/common/upload';
|
||||
public static readonly ACTION_ADD_FILE: string = '/harmony/video/add';
|
||||
public static readonly ACTION_SEND_MESSAGE: string = '/sys/message/sysMessageTemplate/sendMsg';
|
||||
public static readonly ACTION_ON_MESSAGE_URL: string = 'ws://192.168.18.47:8080/jeecg-boot/websocket/';
|
||||
|
||||
// EVENT ID
|
||||
public static readonly EVENT_PAUSED_AUDIO: number = 1;
|
||||
public static readonly EVENT_PAUSED_VIDEO: number = 2;
|
||||
public static readonly EVENT_PAUSED_INDEX: number = 3;
|
||||
|
||||
public static readonly TEST_NAME_DEMO_VIDEO: string = 'demo_video.mp4';
|
||||
public static readonly TEST_NAME_DEMO_AUDIO: string = 'demo_audio.mp3';
|
||||
}
|
74
sample/AppSampleD/entry/src/main/ets/utils/DateTimeUtil.ts
Normal file
74
sample/AppSampleD/entry/src/main/ets/utils/DateTimeUtil.ts
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 日期工具
|
||||
*/
|
||||
|
||||
const NINE = 9; // 这是数字9
|
||||
|
||||
export default class DateTimeUtil {
|
||||
/**
|
||||
* 时分秒
|
||||
*/
|
||||
getTime(): string {
|
||||
const DATETIME = new Date();
|
||||
return this.concatTime(
|
||||
DATETIME.getHours(),
|
||||
DATETIME.getMinutes(),
|
||||
DATETIME.getSeconds()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 年月日
|
||||
*/
|
||||
getDate(): string {
|
||||
const DATETIME = new Date();
|
||||
return this.concatDate(
|
||||
DATETIME.getFullYear(),
|
||||
DATETIME.getMonth() + 1,
|
||||
DATETIME.getDate()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期不足两位补充0
|
||||
* @param value-数据值
|
||||
*/
|
||||
fill(value: number): string {
|
||||
return (value > NINE ? '' : '0') + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 年月日格式修饰
|
||||
* @param year
|
||||
* @param month
|
||||
* @param date
|
||||
*/
|
||||
concatDate(year: number, month: number, date: number): string {
|
||||
return `${year}${this.fill(month)}${this.fill(date)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时分秒格式修饰
|
||||
* @param hours
|
||||
* @param minutes
|
||||
* @param seconds
|
||||
*/
|
||||
concatTime(hours: number, minutes: number, seconds: number): string {
|
||||
return `${this.fill(hours)}${this.fill(minutes)}${this.fill(seconds)}`;
|
||||
}
|
||||
}
|
45
sample/AppSampleD/entry/src/main/ets/utils/Logger.ts
Normal file
45
sample/AppSampleD/entry/src/main/ets/utils/Logger.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import hilog from '@ohos.hilog'
|
||||
|
||||
class Logger {
|
||||
private domain: number
|
||||
private prefix: string
|
||||
private format: string = '%{public}s, %{public}s'
|
||||
|
||||
constructor(prefix: string) {
|
||||
this.prefix = prefix
|
||||
this.domain = 0xFF00
|
||||
}
|
||||
|
||||
debug(...args: string[]) {
|
||||
hilog.debug(this.domain, this.prefix, this.format, args)
|
||||
}
|
||||
|
||||
info(...args: string[]) {
|
||||
hilog.info(this.domain, this.prefix, this.format, args)
|
||||
}
|
||||
|
||||
warn(...args: string[]) {
|
||||
hilog.warn(this.domain, this.prefix, this.format, args)
|
||||
}
|
||||
|
||||
error(...args: string[]) {
|
||||
hilog.error(this.domain, this.prefix, this.format, args)
|
||||
}
|
||||
}
|
||||
|
||||
export default new Logger('[Sample_AppSampleD]')
|
70
sample/AppSampleD/entry/src/main/module.json5
Normal file
70
sample/AppSampleD/entry/src/main/module.json5
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"module": {
|
||||
"name": "entry",
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"default"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "EntryAbility",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ts",
|
||||
"description": "$string:EntryAbility_desc",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:EntryAbility_label",
|
||||
"startWindowIcon": "$media:app_icon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"exported": true,
|
||||
"skills": [
|
||||
{
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
],
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"requestPermissions": [
|
||||
{
|
||||
"name": "ohos.permission.CAMERA"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.MICROPHONE"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.MEDIA_LOCATION"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.WRITE_MEDIA"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.READ_MEDIA"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.INTERNET"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FFFFFF",
|
||||
"value": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_80FFFFFF",
|
||||
"value": "#80FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_CCFFFFFF",
|
||||
"value": "#CCFFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_E6FFFFFF",
|
||||
"value": "#E6FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_000000",
|
||||
"value": "#000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_33000000",
|
||||
"value": "#33000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_5BA854",
|
||||
"value": "#5BA854"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_E6000000",
|
||||
"value": "#e6000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_99000000",
|
||||
"value": "#99000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_007DFF",
|
||||
"value": "#007DFF"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_66000000",
|
||||
"value": "#66000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_0D000000",
|
||||
"value": "#0d000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FF000000",
|
||||
"value": "#ff000000"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_CCF1F3F5",
|
||||
"value": "#CCF1F3F5"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_99F1F3F5",
|
||||
"value": "#99F1F3F5"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FF785F",
|
||||
"value": "#ff758f"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FC2B55",
|
||||
"value": "#fc2b55"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_57A9FE",
|
||||
"value": "#58a9fe"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FF689F",
|
||||
"value": "#ff689f"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_393939",
|
||||
"value": "#393939"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_3DA0F1",
|
||||
"value": "#3DA0F1"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_1E1E1E",
|
||||
"value": "#1e1e1e"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_AE4EF7",
|
||||
"value": "#ae4ef7"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_168CF6",
|
||||
"value": "#168cf6"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_FE2B54",
|
||||
"value": "#fe2b54"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_E3163D",
|
||||
"value": "#E3163D"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_5A5B63",
|
||||
"value": "#5a5b63"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_D7B837",
|
||||
"value": "#d7b837"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_99393939",
|
||||
"value": "#99393939"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_151724",
|
||||
"value": "#151724"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_EEC934",
|
||||
"value": "#EEC934"
|
||||
},
|
||||
{
|
||||
"name": "COLOR_669F9B9B",
|
||||
"value": "#669F9B9B"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,240 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "appsampled"
|
||||
},
|
||||
{
|
||||
"name": "Recommend",
|
||||
"value": "recommend"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_medium",
|
||||
"value": "HarmonyOS Sans SC-Medium"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_regular",
|
||||
"value": "HarmonyOS Sans SC-Regular"
|
||||
},
|
||||
{
|
||||
"name": "Home_page",
|
||||
"value": "home page"
|
||||
},
|
||||
{
|
||||
"name": "Message",
|
||||
"value": "message"
|
||||
},
|
||||
{
|
||||
"name": "LoginByPhone",
|
||||
"value": "login by phone"
|
||||
},
|
||||
{
|
||||
"name": "Input_phone",
|
||||
"value": "please input phone"
|
||||
},
|
||||
{
|
||||
"name": "Input_password",
|
||||
"value": "please input password"
|
||||
},
|
||||
{
|
||||
"name": "Login",
|
||||
"value": "login"
|
||||
},
|
||||
{
|
||||
"name": "Video",
|
||||
"value": "video"
|
||||
},
|
||||
{
|
||||
"name": "Next",
|
||||
"value": "Next"
|
||||
},
|
||||
{
|
||||
"name": "Stroll",
|
||||
"value": "stroll"
|
||||
},
|
||||
{
|
||||
"name": "Experience",
|
||||
"value": "experience"
|
||||
},
|
||||
{
|
||||
"name": "Attention",
|
||||
"value": "attention"
|
||||
},
|
||||
{
|
||||
"name": "Store",
|
||||
"value": "store"
|
||||
},
|
||||
{
|
||||
"name": "Friend",
|
||||
"value": "friend"
|
||||
},
|
||||
{
|
||||
"name": "Me",
|
||||
"value": "me"
|
||||
},
|
||||
{
|
||||
"name": "UserNick",
|
||||
"value": "@xiaoming"
|
||||
},
|
||||
{
|
||||
"name": "TikContent",
|
||||
"value": "It's a Lovely Day Today#sunny day#clouds"
|
||||
},
|
||||
{
|
||||
"name": "Num",
|
||||
"value": "%sW"
|
||||
},
|
||||
{
|
||||
"name": "NewFriend",
|
||||
"value": "New Friend"
|
||||
},
|
||||
{
|
||||
"name": "No_new_notice",
|
||||
"value": "No new notice"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message",
|
||||
"value": "Interactive message"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message_content",
|
||||
"value": "Ming liked your video"
|
||||
},
|
||||
{
|
||||
"name": "Greet",
|
||||
"value": "greet"
|
||||
},
|
||||
{
|
||||
"name": "Send_Message",
|
||||
"value": "Send Message"
|
||||
},
|
||||
{
|
||||
"name": "Search",
|
||||
"value": "search"
|
||||
},
|
||||
{
|
||||
"name": "Clear_all_search_record",
|
||||
"value": "Clear all search record"
|
||||
},
|
||||
{
|
||||
"name": "Synthesize",
|
||||
"value": "synthesize"
|
||||
},
|
||||
{
|
||||
"name": "Music",
|
||||
"value": "music"
|
||||
},
|
||||
{
|
||||
"name": "User",
|
||||
"value": "user"
|
||||
},
|
||||
{
|
||||
"name": "Commodity",
|
||||
"value": "commodity"
|
||||
},
|
||||
{
|
||||
"name": "Live_streaming",
|
||||
"value": "live streaming"
|
||||
},
|
||||
{
|
||||
"name": "All",
|
||||
"value": "all"
|
||||
},
|
||||
{
|
||||
"name": "Special",
|
||||
"value": "special"
|
||||
},
|
||||
{
|
||||
"name": "Album",
|
||||
"value": "album"
|
||||
},
|
||||
{
|
||||
"name": "Word",
|
||||
"value": "word"
|
||||
},
|
||||
{
|
||||
"name": "Subsection",
|
||||
"value": "subsection"
|
||||
},
|
||||
{
|
||||
"name": "Photo",
|
||||
"value": "photo"
|
||||
},
|
||||
{
|
||||
"name": "Everyday",
|
||||
"value": "everyday"
|
||||
},
|
||||
{
|
||||
"name": "Wen",
|
||||
"value": "wen"
|
||||
},
|
||||
{
|
||||
"name": "Send_everyday",
|
||||
"value": "send everyday"
|
||||
},
|
||||
{
|
||||
"name": "Select_music",
|
||||
"value": "select music"
|
||||
},
|
||||
{
|
||||
"name": "Return_edit",
|
||||
"value": "Return Edit"
|
||||
},
|
||||
{
|
||||
"name": "Topic",
|
||||
"value": "topic"
|
||||
},
|
||||
{
|
||||
"name": "Where_are_you",
|
||||
"value": "where are you"
|
||||
},
|
||||
{
|
||||
"name": "Add_applet",
|
||||
"value": "Add applet"
|
||||
},
|
||||
{
|
||||
"name": "Publicly_visible",
|
||||
"value": "Publicly visible"
|
||||
},
|
||||
{
|
||||
"name": "Advanced_setup",
|
||||
"value": "advanced setup"
|
||||
},
|
||||
{
|
||||
"name": "Well_Number_Friend",
|
||||
"value": "# Friend"
|
||||
},
|
||||
{
|
||||
"name": "Add_work_description",
|
||||
"value": "Add work description"
|
||||
},
|
||||
{
|
||||
"name": "Select_cover",
|
||||
"value": "select cover"
|
||||
},
|
||||
{
|
||||
"name": "Save_Draft",
|
||||
"value": "Save Draft"
|
||||
},
|
||||
{
|
||||
"name": "Publish",
|
||||
"value": "publish"
|
||||
},
|
||||
{
|
||||
"name": "Publish_Success",
|
||||
"value": "Publish Success"
|
||||
},
|
||||
{
|
||||
"name": "Connection_timesout",
|
||||
"value": "The connection times out. Please check the network status"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,10 @@
|
||||
{
|
||||
"src": [
|
||||
"pages/Index",
|
||||
"appsampled/pages/Login",
|
||||
"appsampled/pages/ChatPage",
|
||||
"appsampled/pages/SearchPage",
|
||||
"appsampled/pages/CameraPage",
|
||||
"appsampled/pages/PublishPage"
|
||||
]
|
||||
}
|
@ -0,0 +1,240 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "AppSampleD"
|
||||
},
|
||||
{
|
||||
"name": "Recommend",
|
||||
"value": "recommend"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_medium",
|
||||
"value": "HarmonyOS Sans SC-Medium"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_regular",
|
||||
"value": "HarmonyOS Sans SC-Regular"
|
||||
},
|
||||
{
|
||||
"name": "Home_page",
|
||||
"value": "home page"
|
||||
},
|
||||
{
|
||||
"name": "Message",
|
||||
"value": "message"
|
||||
},
|
||||
{
|
||||
"name": "LoginByPhone",
|
||||
"value": "login by phone"
|
||||
},
|
||||
{
|
||||
"name": "Input_phone",
|
||||
"value": "please input phone"
|
||||
},
|
||||
{
|
||||
"name": "Input_password",
|
||||
"value": "please input password"
|
||||
},
|
||||
{
|
||||
"name": "Login",
|
||||
"value": "login"
|
||||
},
|
||||
{
|
||||
"name": "Video",
|
||||
"value": "video"
|
||||
},
|
||||
{
|
||||
"name": "Next",
|
||||
"value": "Next"
|
||||
},
|
||||
{
|
||||
"name": "Stroll",
|
||||
"value": "stroll"
|
||||
},
|
||||
{
|
||||
"name": "Experience",
|
||||
"value": "experience"
|
||||
},
|
||||
{
|
||||
"name": "Attention",
|
||||
"value": "attention"
|
||||
},
|
||||
{
|
||||
"name": "Store",
|
||||
"value": "store"
|
||||
},
|
||||
{
|
||||
"name": "Friend",
|
||||
"value": "friend"
|
||||
},
|
||||
{
|
||||
"name": "Me",
|
||||
"value": "me"
|
||||
},
|
||||
{
|
||||
"name": "UserNick",
|
||||
"value": "@xiaoming"
|
||||
},
|
||||
{
|
||||
"name": "TikContent",
|
||||
"value": "It's a Lovely Day Today#sunny day#clouds"
|
||||
},
|
||||
{
|
||||
"name": "Num",
|
||||
"value": "%sW"
|
||||
},
|
||||
{
|
||||
"name": "NewFriend",
|
||||
"value": "New Friend"
|
||||
},
|
||||
{
|
||||
"name": "No_new_notice",
|
||||
"value": "No new notice"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message",
|
||||
"value": "Interactive message"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message_content",
|
||||
"value": "Ming liked your video"
|
||||
},
|
||||
{
|
||||
"name": "Greet",
|
||||
"value": "greet"
|
||||
},
|
||||
{
|
||||
"name": "Send_Message",
|
||||
"value": "Send Message"
|
||||
},
|
||||
{
|
||||
"name": "Search",
|
||||
"value": "search"
|
||||
},
|
||||
{
|
||||
"name": "Clear_all_search_record",
|
||||
"value": "Clear all search record"
|
||||
},
|
||||
{
|
||||
"name": "Synthesize",
|
||||
"value": "synthesize"
|
||||
},
|
||||
{
|
||||
"name": "Music",
|
||||
"value": "music"
|
||||
},
|
||||
{
|
||||
"name": "User",
|
||||
"value": "user"
|
||||
},
|
||||
{
|
||||
"name": "Commodity",
|
||||
"value": "commodity"
|
||||
},
|
||||
{
|
||||
"name": "Live_streaming",
|
||||
"value": "live streaming"
|
||||
},
|
||||
{
|
||||
"name": "All",
|
||||
"value": "all"
|
||||
},
|
||||
{
|
||||
"name": "Special",
|
||||
"value": "special"
|
||||
},
|
||||
{
|
||||
"name": "Album",
|
||||
"value": "album"
|
||||
},
|
||||
{
|
||||
"name": "Word",
|
||||
"value": "word"
|
||||
},
|
||||
{
|
||||
"name": "Subsection",
|
||||
"value": "subsection"
|
||||
},
|
||||
{
|
||||
"name": "Photo",
|
||||
"value": "photo"
|
||||
},
|
||||
{
|
||||
"name": "Everyday",
|
||||
"value": "everyday"
|
||||
},
|
||||
{
|
||||
"name": "Wen",
|
||||
"value": "wen"
|
||||
},
|
||||
{
|
||||
"name": "Send_everyday",
|
||||
"value": "send everyday"
|
||||
},
|
||||
{
|
||||
"name": "Select_music",
|
||||
"value": "select music"
|
||||
},
|
||||
{
|
||||
"name": "Return_edit",
|
||||
"value": "Return Edit"
|
||||
},
|
||||
{
|
||||
"name": "Topic",
|
||||
"value": "topic"
|
||||
},
|
||||
{
|
||||
"name": "Where_are_you",
|
||||
"value": "where are you"
|
||||
},
|
||||
{
|
||||
"name": "Add_applet",
|
||||
"value": "Add applet"
|
||||
},
|
||||
{
|
||||
"name": "Publicly_visible",
|
||||
"value": "Publicly visible"
|
||||
},
|
||||
{
|
||||
"name": "Advanced_setup",
|
||||
"value": "advanced setup"
|
||||
},
|
||||
{
|
||||
"name": "Well_Number_Friend",
|
||||
"value": "# Friend"
|
||||
},
|
||||
{
|
||||
"name": "Add_work_description",
|
||||
"value": "Add work description"
|
||||
},
|
||||
{
|
||||
"name": "Select_cover",
|
||||
"value": "select cover"
|
||||
},
|
||||
{
|
||||
"name": "Save_Draft",
|
||||
"value": "Save as Draft"
|
||||
},
|
||||
{
|
||||
"name": "Publish",
|
||||
"value": "publish"
|
||||
},
|
||||
{
|
||||
"name": "Publish_Success",
|
||||
"value": "Publish Success"
|
||||
},
|
||||
{
|
||||
"name": "Connection_timesout",
|
||||
"value": "The connection times out. Please check the network status"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
@ -0,0 +1,240 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "模块描述"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "仿应用"
|
||||
},
|
||||
{
|
||||
"name": "Recommend",
|
||||
"value": "推荐"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_medium",
|
||||
"value": "HarmonyOS Sans SC-Medium"
|
||||
},
|
||||
{
|
||||
"name": "Font_family_regular",
|
||||
"value": "HarmonyOS Sans SC-Regular"
|
||||
},
|
||||
{
|
||||
"name": "Home_page",
|
||||
"value": "首页"
|
||||
},
|
||||
{
|
||||
"name": "Message",
|
||||
"value": "消息"
|
||||
},
|
||||
{
|
||||
"name": "LoginByPhone",
|
||||
"value": "手机号密码登录"
|
||||
},
|
||||
{
|
||||
"name": "Input_phone",
|
||||
"value": "请输入手机号"
|
||||
},
|
||||
{
|
||||
"name": "Input_password",
|
||||
"value": "请输入密码"
|
||||
},
|
||||
{
|
||||
"name": "Login",
|
||||
"value": "登录"
|
||||
},
|
||||
{
|
||||
"name": "Video",
|
||||
"value": "视频"
|
||||
},
|
||||
{
|
||||
"name": "Next",
|
||||
"value": "下一步"
|
||||
},
|
||||
{
|
||||
"name": "Stroll",
|
||||
"value": "逛逛"
|
||||
},
|
||||
{
|
||||
"name": "Experience",
|
||||
"value": "经验"
|
||||
},
|
||||
{
|
||||
"name": "Attention",
|
||||
"value": "关注"
|
||||
},
|
||||
{
|
||||
"name": "Store",
|
||||
"value": "商城"
|
||||
},
|
||||
{
|
||||
"name": "Friend",
|
||||
"value": "朋友"
|
||||
},
|
||||
{
|
||||
"name": "Me",
|
||||
"value": "我"
|
||||
},
|
||||
{
|
||||
"name": "UserNick",
|
||||
"value": "@小明"
|
||||
},
|
||||
{
|
||||
"name": "TikContent",
|
||||
"value": "今天天气真好#晴天#白云"
|
||||
},
|
||||
{
|
||||
"name": "Num",
|
||||
"value": "%s万"
|
||||
},
|
||||
{
|
||||
"name": "NewFriend",
|
||||
"value": "新朋友"
|
||||
},
|
||||
{
|
||||
"name": "No_new_notice",
|
||||
"value": "没有新通知"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message",
|
||||
"value": "互动消息"
|
||||
},
|
||||
{
|
||||
"name": "Interactive_message_content",
|
||||
"value": "xiaoming点赞了你的视频"
|
||||
},
|
||||
{
|
||||
"name": "Greet",
|
||||
"value": "跟 Ta 打个招呼"
|
||||
},
|
||||
{
|
||||
"name": "Send_Message",
|
||||
"value": "发送消息"
|
||||
},
|
||||
{
|
||||
"name": "Search",
|
||||
"value": "搜索"
|
||||
},
|
||||
{
|
||||
"name": "Clear_all_search_record",
|
||||
"value": "清楚全部搜索记录"
|
||||
},
|
||||
{
|
||||
"name": "Synthesize",
|
||||
"value": "综合"
|
||||
},
|
||||
{
|
||||
"name": "Music",
|
||||
"value": "音乐"
|
||||
},
|
||||
{
|
||||
"name": "User",
|
||||
"value": "用户"
|
||||
},
|
||||
{
|
||||
"name": "Commodity",
|
||||
"value": "商品"
|
||||
},
|
||||
{
|
||||
"name": "Live_streaming",
|
||||
"value": "直播"
|
||||
},
|
||||
{
|
||||
"name": "All",
|
||||
"value": "全部"
|
||||
},
|
||||
{
|
||||
"name": "Special",
|
||||
"value": "特效"
|
||||
},
|
||||
{
|
||||
"name": "Album",
|
||||
"value": "相册"
|
||||
},
|
||||
{
|
||||
"name": "Word",
|
||||
"value": "文字"
|
||||
},
|
||||
{
|
||||
"name": "Subsection",
|
||||
"value": "分段"
|
||||
},
|
||||
{
|
||||
"name": "Photo",
|
||||
"value": "照片"
|
||||
},
|
||||
{
|
||||
"name": "Everyday",
|
||||
"value": "日常"
|
||||
},
|
||||
{
|
||||
"name": "Wen",
|
||||
"value": "文"
|
||||
},
|
||||
{
|
||||
"name": "Send_everyday",
|
||||
"value": "发日常"
|
||||
},
|
||||
{
|
||||
"name": "Select_music",
|
||||
"value": "选择音乐"
|
||||
},
|
||||
{
|
||||
"name": "Return_edit",
|
||||
"value": "返回编辑"
|
||||
},
|
||||
{
|
||||
"name": "Topic",
|
||||
"value": "# 话题"
|
||||
},
|
||||
{
|
||||
"name": "Where_are_you",
|
||||
"value": "你在哪里"
|
||||
},
|
||||
{
|
||||
"name": "Add_applet",
|
||||
"value": "添加小程序"
|
||||
},
|
||||
{
|
||||
"name": "Publicly_visible",
|
||||
"value": "公开可见"
|
||||
},
|
||||
{
|
||||
"name": "Advanced_setup",
|
||||
"value": "高级设置"
|
||||
},
|
||||
{
|
||||
"name": "Well_Number_Friend",
|
||||
"value": "# 朋友"
|
||||
},
|
||||
{
|
||||
"name": "Add_work_description",
|
||||
"value": "添加作品描述"
|
||||
},
|
||||
{
|
||||
"name": "Select_cover",
|
||||
"value": "选封面"
|
||||
},
|
||||
{
|
||||
"name": "Save_Draft",
|
||||
"value": "存草稿"
|
||||
},
|
||||
{
|
||||
"name": "Publish",
|
||||
"value": "发布"
|
||||
},
|
||||
{
|
||||
"name": "Publish_Success",
|
||||
"value": "发布成功"
|
||||
},
|
||||
{
|
||||
"name": "Connection_timesout",
|
||||
"value": "连接超时,请检查网络状态"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import hilog from '@ohos.hilog';
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
|
||||
|
||||
export default function abilityTest() {
|
||||
describe('ActsAbilityTest', function () {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(function () {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(function () {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(function () {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(function () {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('assertContain',0, function () {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
|
||||
let a = 'abc'
|
||||
let b = 'b'
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b)
|
||||
expect(a).assertEqual(a)
|
||||
})
|
||||
})
|
||||
}
|
221
sample/AppSampleD/entry/src/ohosTest/ets/test/Index.test.ets
Normal file
221
sample/AppSampleD/entry/src/ohosTest/ets/test/Index.test.ets
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
import hilog from '@ohos.hilog';
|
||||
import { Driver, ON, MatchPattern } from '@ohos.UiTest';
|
||||
import abilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
import { getString } from '../util/ResourceUtil';
|
||||
|
||||
const TAG = '[Sample_AppSampleD]';
|
||||
const DOMAIN = 0xF811;
|
||||
const BUNDLE = 'AppSampleD';
|
||||
const delegator = abilityDelegatorRegistry.getAbilityDelegator();
|
||||
|
||||
let driver = Driver.create();
|
||||
|
||||
export default function IndexTest() {
|
||||
describe('IndexTest', function () {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(async function (done) {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
|
||||
// 启动Ability
|
||||
delegator.executeShellCommand('aa start -a EntryAbility -b com.samples.appsamppled');
|
||||
|
||||
await driver.delayMs(2000);
|
||||
done()
|
||||
})
|
||||
beforeEach(function () {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(function () {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(function () {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
|
||||
it('Video', 0, async function (done) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Video begin');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('video_action','Video');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('video_action','Video');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('search','Video');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await driver.delayMs(1000);
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Video end');
|
||||
done()
|
||||
})
|
||||
|
||||
it('Search', 0, async function (done) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Search begin');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('searchItem_1','Search');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('musicID_1','Search');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndClickById('musicID_2','Search');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndClickById('musicID_2','Search');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndClickById('titleID_2','Search');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('searchBack','Search');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('searchBack','Search');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await driver.delayMs(1000);
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Search end');
|
||||
done()
|
||||
})
|
||||
|
||||
it('Message', 0, async function (done) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Message begin');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('index_message','Message');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('login','Message');
|
||||
|
||||
await driver.delayMs(5000);
|
||||
|
||||
await checkAndClickById('index_message','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('userID_1','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndInputById('chatInput','Hello!','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('msgSend','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndInputById('chatInput','How are you?','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('msgSend','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await checkAndClickById('chatBack','Message');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await driver.delayMs(1000);
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Message end');
|
||||
done()
|
||||
})
|
||||
|
||||
it('Post_videos', 0, async function (done) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Post_videos begin');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('index_main','Post_videos');
|
||||
await driver.delayMs(1000);
|
||||
|
||||
// 授权
|
||||
await checkAndClickPermission(getString($r('app.string.allow')), "Post_videos");
|
||||
await checkAndClickPermission(getString($r('app.string.allow')), "Post_videos");
|
||||
await checkAndClickPermission(getString($r('app.string.allow')), "Post_videos");
|
||||
await driver.delayMs(1000);
|
||||
|
||||
await checkAndClickById('startVideo','Post_videos');
|
||||
await driver.delayMs(5000);
|
||||
await checkAndClickById('stopVideo','Post_videos');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndClickById('next','Post_videos');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndInputById('textArea','This is my video','Post_videos');
|
||||
await driver.delayMs(2000);
|
||||
|
||||
await checkAndClickById('upload','Post_videos');
|
||||
await driver.delayMs(500);
|
||||
|
||||
await driver.delayMs(1000);
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + 'Post_videos end');
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据id拿到组件并点击
|
||||
* @param id
|
||||
*/
|
||||
async function checkAndClickById(id: string, log: string) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + `${log} id:${id}`);
|
||||
await driver.assertComponentExist(ON.id(id));
|
||||
let res = await driver.findComponent(ON.id(id));
|
||||
await res.click();
|
||||
}
|
||||
/**
|
||||
* 根据text拿到组件并点击
|
||||
* @param text
|
||||
*/
|
||||
async function checkAndClickByText(text: string, log: string) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + `${log} text:${text}`);
|
||||
await driver.assertComponentExist(ON.text(text));
|
||||
let res = await driver.findComponent(ON.text(text));
|
||||
await res.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id拿到组件并输入消息
|
||||
* @param id
|
||||
* @param msg
|
||||
*/
|
||||
async function checkAndInputById(id:string,msg:string,log:string){
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + `${log} id:${id}`);
|
||||
await driver.assertComponentExist(ON.id(id));
|
||||
let res = await driver.findComponent(ON.id(id));
|
||||
await res.inputText(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Text验证对应权限
|
||||
* @param text
|
||||
* @param log
|
||||
*/
|
||||
async function checkAndClickPermission(text: string, log: string) {
|
||||
hilog.info(DOMAIN, TAG, BUNDLE + `${log} text:${text}`);
|
||||
await driver.assertComponentExist(ON.text(getString($r('app.string.whether')) + text, MatchPattern.CONTAINS));
|
||||
let res = await driver.findComponent(ON.text(text, MatchPattern.EQUALS));
|
||||
await res.click();
|
||||
}
|
||||
}
|
21
sample/AppSampleD/entry/src/ohosTest/ets/test/List.test.ets
Normal file
21
sample/AppSampleD/entry/src/ohosTest/ets/test/List.test.ets
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import IndexTest from './Index.test'
|
||||
import abilityTest from './Ability.test'
|
||||
|
||||
export default function testsuite() {
|
||||
abilityTest()
|
||||
IndexTest()
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
import hilog from '@ohos.hilog';
|
||||
import { Hypium } from '@ohos/hypium';
|
||||
import testsuite from '../test/List.test';
|
||||
import window from '@ohos.window';
|
||||
|
||||
export default class TestAbility extends UIAbility {
|
||||
onCreate(want, launchParam) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? '');
|
||||
var abilityDelegator: any
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||
var abilityDelegatorArguments: any
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
|
||||
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
|
||||
windowStage.loadContent('testability/pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
return;
|
||||
}
|
||||
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
|
||||
JSON.stringify(data) ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
aboutToAppear() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear');
|
||||
}
|
||||
@State message: string = 'Hello World'
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize(50)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
Button() {
|
||||
Text('next page')
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}.type(ButtonType.Capsule)
|
||||
.margin({
|
||||
top: 20
|
||||
})
|
||||
.backgroundColor('#0D9FFB')
|
||||
.width('35%')
|
||||
.height('5%')
|
||||
.onClick(()=>{
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import hilog from '@ohos.hilog';
|
||||
import TestRunner from '@ohos.application.testRunner';
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
|
||||
var abilityDelegator = undefined
|
||||
var abilityDelegatorArguments = undefined
|
||||
|
||||
async function onAbilityCreateCallback() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
|
||||
}
|
||||
|
||||
async function addAbilityMonitorCallback(err: any) {
|
||||
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
|
||||
}
|
||||
|
||||
export default class OpenHarmonyTestRunner implements TestRunner {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
onPrepare() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
|
||||
}
|
||||
|
||||
async onRun() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||
var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
|
||||
let lMonitor = {
|
||||
abilityName: testAbilityName,
|
||||
onAbilityCreate: onAbilityCreateCallback,
|
||||
};
|
||||
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
|
||||
var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
|
||||
var debug = abilityDelegatorArguments.parameters['-D']
|
||||
if (debug == 'true')
|
||||
{
|
||||
cmd += ' -D'
|
||||
}
|
||||
hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd);
|
||||
abilityDelegator.executeShellCommand(cmd,
|
||||
(err: any, d: any) => {
|
||||
hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? '');
|
||||
hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? '');
|
||||
hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? '');
|
||||
})
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
|
||||
const delegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||
|
||||
export function getString(resource: Resource): string {
|
||||
let manage = delegator.getAppContext().resourceManager
|
||||
return manage.getStringSync(resource)
|
||||
}
|
||||
|
||||
|
||||
export async function getStringArray(resource: Resource): Promise<Array<string>> {
|
||||
let manage = delegator.getAppContext().resourceManager
|
||||
let menuList: Array<string> = await manage.getStringArrayValue(resource);
|
||||
return menuList;
|
||||
}
|
50
sample/AppSampleD/entry/src/ohosTest/module.json5
Normal file
50
sample/AppSampleD/entry/src/ohosTest/module.json5
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"module": {
|
||||
"name": "entry_test",
|
||||
"type": "feature",
|
||||
"description": "$string:module_test_desc",
|
||||
"mainElement": "TestAbility",
|
||||
"deviceTypes": [
|
||||
"default"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:test_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "TestAbility",
|
||||
"srcEntry": "./ets/testability/TestAbility.ets",
|
||||
"description": "$string:TestAbility_desc",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:TestAbility_label",
|
||||
"exported": true,
|
||||
"startWindowIcon": "$media:app_icon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"skills": [
|
||||
{
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
],
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_test_desc",
|
||||
"value": "test ability description"
|
||||
},
|
||||
{
|
||||
"name": "TestAbility_desc",
|
||||
"value": "the test ability"
|
||||
},
|
||||
{
|
||||
"name": "TestAbility_label",
|
||||
"value": "test label"
|
||||
},
|
||||
{
|
||||
"name": "allow",
|
||||
"value": "允许"
|
||||
},
|
||||
{
|
||||
"name": "whether",
|
||||
"value": "是否"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"testability/pages/Index"
|
||||
]
|
||||
}
|
20
sample/AppSampleD/hvigor/hvigor-config.json5
Normal file
20
sample/AppSampleD/hvigor/hvigor-config.json5
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"hvigorVersion": "2.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "2.0.0"
|
||||
}
|
||||
}
|
2
sample/AppSampleD/hvigor/hvigor-wrapper.js
Normal file
2
sample/AppSampleD/hvigor/hvigor-wrapper.js
Normal file
File diff suppressed because one or more lines are too long
2
sample/AppSampleD/hvigorfile.ts
Normal file
2
sample/AppSampleD/hvigorfile.ts
Normal file
@ -0,0 +1,2 @@
|
||||
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
|
||||
export { appTasks } from '@ohos/hvigor-ohos-plugin';
|
61
sample/AppSampleD/hvigorw
Normal file
61
sample/AppSampleD/hvigorw
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Hvigor startup script, version 1.0.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# NODE_HOME - location of a Node home dir
|
||||
# or
|
||||
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
HVIGOR_APP_HOME=$(dirname $(readlink -f $0))
|
||||
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||
warn() {
|
||||
echo ""
|
||||
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo ""
|
||||
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
fail() {
|
||||
error "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Determine node to start hvigor wrapper script
|
||||
if [ -n "${NODE_HOME}" ];then
|
||||
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||
if [ ! -x "$EXECUTABLE_NODE" ];then
|
||||
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||
fi
|
||||
else
|
||||
EXECUTABLE_NODE="node"
|
||||
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
|
||||
fi
|
||||
|
||||
# Check hvigor wrapper script
|
||||
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
|
||||
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||
fi
|
||||
|
||||
# start hvigor-wrapper script
|
||||
exec "${EXECUTABLE_NODE}" \
|
||||
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
70
sample/AppSampleD/hvigorw.bat
Normal file
70
sample/AppSampleD/hvigorw.bat
Normal file
@ -0,0 +1,70 @@
|
||||
:: Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
:: Licensed under the Apache License, Version 2.0 (the "License");
|
||||
:: you may not use this file except in compliance with the License.
|
||||
:: You may obtain a copy of the License at
|
||||
::
|
||||
:: http://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing, software
|
||||
:: distributed under the License is distributed on an "AS IS" BASIS,
|
||||
:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
:: See the License for the specific language governing permissions and
|
||||
:: limitations under the License.
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Hvigor startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||
set NODE_EXE=node.exe
|
||||
|
||||
goto start
|
||||
|
||||
:start
|
||||
@rem Find node.exe
|
||||
if defined NODE_HOME goto findNodeFromNodeHome
|
||||
|
||||
%NODE_EXE% --version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findNodeFromNodeHome
|
||||
set NODE_HOME=%NODE_HOME:"=%
|
||||
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||
|
||||
if exist "%NODE_EXE_PATH%" goto execute
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Execute hvigor
|
||||
"%NODE_EXE%" %WRAPPER_MODULE_PATH% %*
|
||||
|
||||
:fail
|
||||
exit /b 1
|
26
sample/AppSampleD/oh-package.json5
Normal file
26
sample/AppSampleD/oh-package.json5
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
{
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"@ohos/hypium": "1.0.6"
|
||||
},
|
||||
"author": "",
|
||||
"name": "appsampled",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user