Toggle navigation
Toggle navigation
This project
Loading...
Sign in
developOne
/
harmonyPool
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
王士厅
2024-05-14 18:20:22 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
5408ea6bb94323c27a1f558311f74260f0d58bbf
5408ea6b
1 parent
e1928b87
音频悬浮窗
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
196 additions
and
33 deletions
sight_harmony/commons/wdKit/src/main/ets/utils/EmitterEventId.ts
sight_harmony/commons/wdKit/src/main/ets/utils/EmitterUtils.ets
sight_harmony/features/wdComponent/src/main/ets/components/MorningEveningPaper/MorningEveningPaperComponent.ets
sight_harmony/features/wdComponent/src/main/ets/components/view/OperRowListView.ets
sight_harmony/features/wdComponent/src/main/ets/viewmodel/AudioSuspensionModel.ets
sight_harmony/features/wdPlayer/src/main/ets/utils/DateFormatUtil.ets
sight_harmony/products/phone/src/main/ets/entryability/EntryAbility.ets
sight_harmony/products/phone/src/main/ets/pages/view/AudioComponent.ets
sight_harmony/products/phone/src/main/module.json5
sight_harmony/commons/wdKit/src/main/ets/utils/EmitterEventId.ts
View file @
5408ea6
...
...
@@ -31,6 +31,14 @@ export enum EmitterEventId {
// App进入后台
APP_ENTER_BACKGROUD
=
101
,
// 更换音频名称
AUDIO_CHANGE_TITLe
=
10
,
// 更换音频状态
AUDIO_CHANGE_STATUS
=
11
,
// 获取音频悬浮窗焦点状态
AUDIO_WINDOW_TYPE
=
12
,
}
...
...
sight_harmony/commons/wdKit/src/main/ets/utils/EmitterUtils.ets
View file @
5408ea6
...
...
@@ -23,7 +23,7 @@ export class EmitterUtils {
* @param eventId 事件id
* @param str 字符串数据
*/
static sendEvent(eventId: number, str?: string) {
static sendEvent(eventId: number, str?: string
| number
) {
let event: emitter.InnerEvent = {
eventId: eventId,
priority: emitter.EventPriority.LOW
...
...
sight_harmony/features/wdComponent/src/main/ets/components/MorningEveningPaper/MorningEveningPaperComponent.ets
View file @
5408ea6
...
...
@@ -142,6 +142,7 @@ export struct MorningEveningPaperComponent {
if (this.compListItem.operDataList && this.compListItem.operDataList.length > 0) {
this.getAllContentInteractData(this.compListItem.operDataList)
}
Logger.debug('compInfoBean?.compList[0].audioDataList', JSON.stringify(compInfoBean?.compList[0].audioDataList))
if (compInfoBean?.compList[0].audioDataList) {
this.audioPlayUrl = compInfoBean?.compList[0].audioDataList[0].audioUrl
this.audioTitle = compInfoBean?.compList[0].audioDataList[0].title
...
...
@@ -301,8 +302,9 @@ export struct MorningEveningPaperComponent {
.onClick(() => {
Logger.info("TAG", "cj compInfoBean onClick1 = " + this.isAudioPlaying)
// dialog.open()
this.AudioSuspension.showWindow()
// this.playerController.firstPlay(this.audioPlayUrl)
// this.playerController.firstPlay(this.audioPlayUrl, this.audioTitle)
this.AudioSuspension.setPlayerUrl(this.audioPlayUrl, this.audioTitle)
Logger.info(TAG, "this.audioPlayUrl = " + this.audioPlayUrl)
Logger.info("TAG", "cj compInfoBean onClick2 = " + this.isAudioPlaying)
})
}
...
...
sight_harmony/features/wdComponent/src/main/ets/components/view/OperRowListView.ets
View file @
5408ea6
...
...
@@ -23,6 +23,9 @@ import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
import { PageRepository } from '../../repository/PageRepository';
import { SpConstants } from 'wdConstant/Index';
import { WDShare } from 'wdShare/Index';
import { AudioSuspensionModel } from '../../viewmodel/AudioSuspensionModel'
import { EmitterEventId, EmitterUtils } from 'wdKit/Index'
import { PlayerConstants } from 'wdPlayer'
const TAG = 'OperRowListView';
...
...
@@ -55,15 +58,23 @@ export struct OperRowListView {
@State newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
@State likeBean: Record<string, string> = {}
@State audioUrl: string = ''
@State audioTitle: string = ''
@State bgColor: ResourceColor = Color.White
@State showCommentIcon: boolean = true
@State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
needLike: boolean = true
private AudioSuspension = new AudioSuspensionModel()
@State currentStatus: number | string | undefined = 0;
async aboutToAppear() {
console.info(TAG, '22222----', this.styleType)
console.info(TAG, '3333----', this.needLike)
this.handleStyle()
EmitterUtils.receiveEvent(EmitterEventId.AUDIO_CHANGE_STATUS, (val: number | string | undefined) => {
console.log(TAG,'this.currentStatus', val)
this.currentStatus = val
})
}
async onDetailUpdated() {
...
...
@@ -97,7 +108,9 @@ export struct OperRowListView {
// 音频需要数据
if (this.operationButtonList?.includes('listen')) {
this.audioUrl = this.contentDetailData.audioList[0]?.audioUrl || ''
this.audioTitle = this.contentDetailData.newsTitle || ''
console.log(TAG, 'this.audioUrl+++', this.audioUrl)
console.log(TAG, 'this.audioTitle+++', this.audioTitle)
}
}
...
...
@@ -231,13 +244,14 @@ export struct OperRowListView {
@Builder
builderListen() {
Column() {
Image(
$r('app.media.icon_listen'
))
Image(
this.currentStatus === PlayerConstants.STATUS_START ? $r("app.media.icon_audio_pause") : $r("app.media.icon_listen"
))
.width(24)
.height(24)
.aspectRatio(1)
.interpolation(ImageInterpolation.High)
.onClick((event: ClickEvent) => {
ToastUtils.showToast('音频为公共方法,待开发', 1000);
this.AudioSuspension.setPlayerUrl(this.audioUrl, this.audioTitle)
// ToastUtils.showToast('音频为公共方法,待开发', 1000);
})
}
.width(42)
...
...
sight_harmony/features/wdComponent/src/main/ets/viewmodel/AudioSuspensionModel.ets
View file @
5408ea6
...
...
@@ -2,6 +2,7 @@ import window from '@ohos.window';
import { Logger } from 'wdKit';
import { WDPlayerController } from 'wdPlayer';
import { BusinessError } from '@ohos.base';
import { EmitterEventId, EmitterUtils } from 'wdKit/Index'
const TAG = 'AudioSuspensionModel'
...
...
@@ -11,6 +12,10 @@ const TAG = 'AudioSuspensionModel'
export class AudioSuspensionModel {
public playerController: SubscribedAbstractProperty<WDPlayerController> = AppStorage.link<WDPlayerController>('playerController')
public floatWindowClass: SubscribedAbstractProperty<window.Window> = AppStorage.link<window.Window>('floatWindowClass')
public srcTitle: string = ''
private url: string = ''
private expandWidth: number = 800
private expandHeight: number = 200
constructor() {
this.initPlayerController()
}
...
...
@@ -23,6 +28,10 @@ export class AudioSuspensionModel {
AppStorage.setOrCreate('playerController', new WDPlayerController());
this.playerController = AppStorage.link<WDPlayerController>('playerController')
Logger.info(TAG, 'playerController create success')
this.playerController.get().onStatusChange = (status: number) => {
console.info(TAG, 'this.currentStatus', status)
EmitterUtils.sendEvent(EmitterEventId.AUDIO_CHANGE_STATUS, status)
}
} else {
Logger.info(TAG, 'playerController already exit')
}
...
...
@@ -30,32 +39,70 @@ export class AudioSuspensionModel {
/**
* 配置音频地址
*/
public setPlayerUrl() {
// this.playerController.switchPlayOrPause()
Logger.info(TAG, 'handlePlayer')
public setPlayerUrl(url: string, srcTitle: string) {
// console.log(TAG,'this.url', this.url)
// console.log(TAG,'url', url)
if (this.url === url) {
this.playerController.get().switchPlayOrPause()
} else {
this.url = url
this.playerController.get().firstPlay(url)
this.playerController.get().onCanplay = () => {
this.playerController.get().play()
}
this.srcTitle = srcTitle
EmitterUtils.sendEvent(EmitterEventId.AUDIO_CHANGE_TITLe, this.srcTitle)
console.log(TAG, 'handlePlayer')
this.resizeWindow(this.expandWidth, this.expandHeight)
}
this.showWindow()
}
// 显示悬浮窗。
public showWindow() {
// 判断当前窗口是否已显示,使用callback异步回调。
this.floatWindowClass.get().isShowing((err: BusinessError, data) => {
const errCode: number = err.code;
if (errCode) {
console.error(TAG, 'Failed window is showing Cause:' + JSON.stringify(err));
return;
}
console.info(TAG, 'window is showing: ' + JSON.stringify(data));
if(data === false) {
// 显示当前窗口,使用callback异步回调。
this.floatWindowClass.get().showWindow((err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error(
'floatWindowClass Failed to show the window. Cause: ' + JSON.stringify(err));
console.error(TAG,
'floatWindowClass Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('floatWindowClass Succeeded in showing the window.');
console.info(TAG, 'floatWindowClass Succeeded in showing the window.');
});
}
});
}
// 设置悬浮窗尺寸
public resizeWindow(width: number, height: number) {
this.floatWindowClass.get().resize(width, height, (err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error(TAG, 'floatWindowClass Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info(TAG, 'floatWindowClass Succeeded in changing the window size.');
});
}
// 销毁悬浮窗 使用destroy对其进行销毁。
public destroyWindow() {
this.floatWindowClass.get().destroyWindow((err: BusinessError) => {
/*
this.floatWindowClass.get().destroyWindow((err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error('floatWindowClass Failed to destroy the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('floatWindowClass Succeeded in destroying the window.');
});
});
*/
}
...
...
sight_harmony/features/wdPlayer/src/main/ets/utils/DateFormatUtil.ets
View file @
5408ea6
...
...
@@ -17,6 +17,22 @@ export class DateFormatUtil {
return `${'00'}${':'}${DateFormatUtil.padding(second.toString())}`;
}
}
/**
* ms数转成00:00格式
* @param milliseconds
* @returns
*/
static convertMillisecondsToMinutesSeconds(milliseconds: number): string {
const totalSeconds = Math.floor(milliseconds / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
// 添加前导零,确保格式为两位数
const formattedMinutes = String(minutes).padStart(2, '0');
const formattedSeconds = String(seconds).padStart(2, '0');
return `${formattedMinutes}:${formattedSeconds}`;
}
static padding(num: string) {
let length = 2;
...
...
sight_harmony/products/phone/src/main/ets/entryability/EntryAbility.ets
View file @
5408ea6
...
...
@@ -23,6 +23,8 @@ import { ConfigurationConstant } from '@kit.AbilityKit';
import { WDPushNotificationManager } from 'wdHwAbility/Index';
import { StartupManager } from '../startupmanager/StartupManager';
let floatWindowClass: window.Window | null = null;
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
StartupManager.sharedInstance().appOnCreate(want, launchParam, this.context)
...
...
@@ -82,7 +84,6 @@ export default class EntryAbility extends UIAbility {
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
// 1.创建悬浮窗
let floatWindowClass: window.Window | null = null;
const config: window.Configuration = {
name: "floatWindow", windowType: window.WindowType.TYPE_FLOAT, ctx: this.context
};
...
...
@@ -104,14 +105,6 @@ export default class EntryAbility extends UIAbility {
}
console.info('floatWindowClass Succeeded in moving the window.');
});
floatWindowClass.resize(800, 200, (err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error('floatWindowClass Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info('floatWindowClass Succeeded in changing the window size.');
});
// 3.为悬浮窗加载对应的目标页面。
floatWindowClass.setUIContent("pages/view/AudioComponent", (err: BusinessError) => {
let errCode: number = err.code;
...
...
@@ -122,11 +115,27 @@ export default class EntryAbility extends UIAbility {
console.info('floatWindowClass Succeeded in loading the content.');
});
floatWindowClass.on('windowEvent', (data) => {
EmitterUtils.sendEvent(EmitterEventId.AUDIO_WINDOW_TYPE, data)
});
});
}
destroyFloatWindow() {
(floatWindowClass as window.Window).destroyWindow((err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error('floatWindowClass Failed to destroy the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('floatWindowClass Succeeded in destroying the window.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
this.destroyFloatWindow()
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
...
...
sight_harmony/products/phone/src/main/ets/pages/view/AudioComponent.ets
View file @
5408ea6
import { AudioSuspensionModel } from 'wdComponent'
import { PlayerConstants } from 'wdPlayer'
import { PlayerConstants, DateFormatUtil } from 'wdPlayer'
import { EmitterEventId, EmitterUtils } from 'wdKit/Index'
import window from '@ohos.window';
const TAG = 'AudioSuspensionModel'
@Entry
@Component
struct Index {
private AudioSuspension = new AudioSuspensionModel()
@State audioTitle: string = '来了!新闻早班车5月9日';
@State currentTime: string = '00:03';
@State totalTime: string = '06:16';
@State progressVal: number = 20;
@State currentStatus: number = 0;
@State audioTitle: string | undefined = '';
@State currentTime: string = '00:00';
@State totalTime: string = '00:00';
@State progressVal: number = 0;
@State currentStatus: number | string |undefined = 0;
@State isExpand: boolean = true;
private expandWidth: number = 800
private expandHeight: number = 200
private foldWidth: number = 200
private foldHeight: number = 200
aboutToAppear() {
this.AudioSuspension.playerController.get().onTimeUpdate = (position, duration) => {
this.currentTime = DateFormatUtil.convertMillisecondsToMinutesSeconds(position);
this.totalTime = DateFormatUtil.convertMillisecondsToMinutesSeconds(duration);
this.progressVal = Math.floor(position * 100 / duration);
}
EmitterUtils.receiveEvent(EmitterEventId.AUDIO_CHANGE_TITLe, (val:string | undefined) => {
console.log(TAG,'this.audioTitle', val)
this.audioTitle = val
})
EmitterUtils.receiveEvent(EmitterEventId.AUDIO_CHANGE_STATUS, (val: number | string | undefined) => {
console.log(TAG,'this.currentStatus', val)
this.currentStatus = val
})
EmitterUtils.receiveEvent(EmitterEventId.AUDIO_WINDOW_TYPE, (val: number | string | undefined) => {
if (val == window.WindowEventType.WINDOW_ACTIVE) {
console.info(TAG, 'current window stage event is WINDOW_ACTIVE', val);
this.isExpand = true
this.AudioSuspension.resizeWindow(this.expandWidth, this.expandHeight)
} else if (val == window.WindowEventType.WINDOW_INACTIVE) {
console.info(TAG, 'current window stage event is WINDOW_INACTIVE', val);
this.isExpand = false
this.AudioSuspension.resizeWindow(this.foldWidth, this.foldHeight)
}
})
}
onPageHide() {
// this.status = PlayerConstants.STATUS_PAUSE;
this.AudioSuspension.playerController.get()?.pause();
}
build() {
Stack({ alignContent: Alignment.End }) {
if(this.isExpand) {
Column() { //标题 时间 进度条
Marquee({
start: true,
...
...
@@ -66,7 +112,7 @@ struct Index {
.justifyContent(FlexAlign.Start)
Row() {
Image(this.currentStatus !
= PlayerConstants.STATUS_START ? $r("app.media.icon_audio_pause") : $r("app.media.icon_audio_playing"))
Image(this.currentStatus ==
= PlayerConstants.STATUS_START ? $r("app.media.icon_audio_pause") : $r("app.media.icon_audio_playing"))
.objectFit(ImageFit.Contain)
.width(24)
.height(24)
...
...
@@ -74,7 +120,6 @@ struct Index {
.onClick(() => {
if (this.AudioSuspension.playerController) {
this.AudioSuspension.playerController.get().switchPlayOrPause()
this.currentStatus = this.AudioSuspension.playerController.get().getStatus()
}
})
...
...
@@ -90,7 +135,22 @@ struct Index {
})
}.width(80)
.height(60)
} else {
Row() {
Image(this.currentStatus === PlayerConstants.STATUS_START ? $r("app.media.icon_audio_pause") : $r("app.media.icon_audio_playing"))
.objectFit(ImageFit.Contain)
.width(24)
.height(24)
.onClick(() => {
if (this.AudioSuspension.playerController) {
this.AudioSuspension.playerController.get().switchPlayOrPause()
}
})
}
.justifyContent(FlexAlign.Center)
.width(60)
.height(60)
}
}
.width('100%')
.height('100%')
...
...
sight_harmony/products/phone/src/main/module.json5
View file @
5408ea6
...
...
@@ -92,9 +92,16 @@
{
"name"
:
"ohos.permission.INTERNET"
},
//
{
//
"name"
:
"ohos.permission.SYSTEM_FLOAT_WINDOW"
,
//
}
{
"name"
:
"ohos.permission.SYSTEM_FLOAT_WINDOW"
,
"reason"
:
"$string:EntryAbility_desc"
,
"usedScene"
:
{
"abilities"
:
[
"FormAbility"
],
"when"
:
"inuse"
}
}
]
}
}
\ No newline at end of file
...
...
Please
register
or
login
to post a comment