8
OAT.xml
@ -57,10 +57,18 @@
|
||||
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
|
||||
<filteritem type="filepath" name="demos/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="demos/.*.jpg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="common/.*/src/main/resources/base/media/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="common/.*/src/main/js/default/common/image/icon/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="common/.*/src/main/js/default/common/image/icon/.*.jpg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="common/.*/src/main/js/default/common/image/svg/.*.svg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="entry/src/main/resources/base/media/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="entry/src/main/js/default/common/image/icon/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="entry/src/main/js/default/common/image/icon/.*.jpg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="entry/src/main/js/default/common/image/svg/.*.svg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="features/.*/src/main/resources/base/media/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="features/.*/src/main/js/default/common/image/icon/.*.png" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="features/.*/src/main/js/default/common/image/icon/.*.jpg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="features/.*/src/main/js/default/common/image/svg/.*.svg" desc="self developed image"/>
|
||||
<filteritem type="filepath" name="figures/.*.png" desc="self developed image"/>
|
||||
</filefilter>
|
||||
|
||||
|
@ -1,17 +1,3 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
{
|
||||
"app": {
|
||||
"signingConfigs": [],
|
||||
@ -37,5 +23,45 @@
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"srcPath": "./common/base"
|
||||
},
|
||||
{
|
||||
"name": "timeline",
|
||||
"srcPath": "./features/timeline"
|
||||
},
|
||||
{
|
||||
"name": "browser",
|
||||
"srcPath": "./features/browser"
|
||||
},
|
||||
{
|
||||
"name": "grid",
|
||||
"srcPath": "./features/grid"
|
||||
},
|
||||
{
|
||||
"name": "album",
|
||||
"srcPath": "./features/album"
|
||||
},
|
||||
{
|
||||
"name": "selectAlbum",
|
||||
"srcPath": "./features/selectAlbum"
|
||||
},
|
||||
{
|
||||
"name": "third",
|
||||
"srcPath": "./features/third"
|
||||
},
|
||||
{
|
||||
"name": "mediaOperation",
|
||||
"srcPath": "./features/mediaOperation"
|
||||
},
|
||||
{
|
||||
"name": "distributed",
|
||||
"srcPath": "./features/distributed"
|
||||
},
|
||||
{
|
||||
"name": "formEditor",
|
||||
"srcPath": "./features/formEditor"
|
||||
}
|
||||
],
|
||||
}
|
3
common/base/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
/.preview
|
||||
/build
|
5
common/base/build-profile.json5
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
}
|
||||
}
|
3
common/base/hvigorfile.js
Normal file
@ -0,0 +1,3 @@
|
||||
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
|
||||
module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
|
||||
|
@ -12,9 +12,4 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export enum SelectionState {
|
||||
NONE,
|
||||
SELECTED,
|
||||
NOT_SELECTED,
|
||||
}
|
||||
export { MainPage } from './src/main/ets/components/MainPage/MainPage'
|
5
common/base/package-lock.json
generated
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "@ohos/base",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1
|
||||
}
|
14
common/base/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"license": "ISC",
|
||||
"types": "",
|
||||
"devDependencies": {},
|
||||
"name": "@ohos/base",
|
||||
"description": "a npm package which contains arkUI2.0 page",
|
||||
"ohos": {
|
||||
"org": ""
|
||||
},
|
||||
"main": "src/main/ets/components/MainPage/MainPage.ets",
|
||||
"repository": {},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Constants } from '../model/common/Constants'
|
||||
import { WindowConstants } from '../constants/WindowConstants'
|
||||
|
||||
// New style
|
||||
@Component
|
||||
@ -20,12 +20,12 @@ export struct EmptyAlbumComponent {
|
||||
@Consume gridHeight: number;
|
||||
@Consume isBigCard: boolean;
|
||||
@State icHeight: number = 0;
|
||||
gridAspectRatio = Constants.CARD_ASPECT_RATIO;
|
||||
gridAspectRatio = WindowConstants.CARD_ASPECT_RATIO;
|
||||
|
||||
aboutToAppear(): void {
|
||||
let numberHeight = px2vp(fp2px(Constants.TEXT_SIZE_BODY2));
|
||||
let nameHeight = px2vp(fp2px(Constants.TEXT_SIZE_SUB_TITLE1));
|
||||
this.icHeight = this.gridHeight - Constants.ALBUM_SET_NEW_ICON_MARGIN - numberHeight - nameHeight;
|
||||
let numberHeight = px2vp(fp2px(WindowConstants.TEXT_SIZE_BODY2));
|
||||
let nameHeight = px2vp(fp2px(WindowConstants.TEXT_SIZE_SUB_TITLE1));
|
||||
this.icHeight = this.gridHeight - WindowConstants.ALBUM_SET_NEW_ICON_MARGIN - numberHeight - nameHeight;
|
||||
}
|
||||
|
||||
build() {
|
244
common/base/src/main/ets/components/ImageGridItemComponent.ets
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug, logInfo, logError } from '../utils/LoggerUtils'
|
||||
import { AnimationConstants } from '../constants/AnimationConstants'
|
||||
import { MediaDataItem } from '../data/MediaDataItem'
|
||||
import { DateUtil } from '../utils/DateUtil'
|
||||
import { Broadcast } from '../utils/Broadcast'
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants'
|
||||
import { startTrace } from '../utils/TraceControllerUtils'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils'
|
||||
|
||||
const TAG = "ImageGridItemComponent"
|
||||
// General grid picture control
|
||||
@Component
|
||||
export struct ImageGridItemComponent {
|
||||
@Consume broadCast: Broadcast;
|
||||
@Consume isSelectedMode: boolean;
|
||||
@Consume @Watch('onShow') isShow: boolean;
|
||||
@State thumbnail: string = ""
|
||||
@State isFavourite: boolean = false
|
||||
@State pressAnimScale: number = 1.0;
|
||||
@State isError: boolean = false
|
||||
pageName = '';
|
||||
mediaItem: MediaDataItem;
|
||||
isThird = false;
|
||||
private isEnteringPhoto = false;
|
||||
|
||||
private resetPressAnim(): void {
|
||||
this.pressAnimScale = 1;
|
||||
this.isEnteringPhoto = false;
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
logDebug(TAG, 'aboutToAppear');
|
||||
this.resetShow();
|
||||
}
|
||||
|
||||
private resetShow() {
|
||||
startTraceWithTaskId("load MediaItem", this.mediaItem.index)
|
||||
this.mediaItem.load(false).then(() => {
|
||||
finishTraceWithTaskId("load MediaItem", this.mediaItem.index)
|
||||
this.thumbnail = this.mediaItem.getThumbnail(MediaConstants.DEFAULT_SIZE, MediaConstants.DEFAULT_SIZE)
|
||||
this.isError = false
|
||||
logDebug(TAG, `getThumbnail ${this.thumbnail}`)
|
||||
this.mediaItem.isFavor().then((status: boolean) => {
|
||||
this.isFavourite = status
|
||||
})
|
||||
})
|
||||
this.resetPressAnim();
|
||||
}
|
||||
|
||||
aboutToDisappear(): void {
|
||||
logDebug(TAG, `aboutToDisappear`);
|
||||
this.resetPressAnim();
|
||||
}
|
||||
|
||||
private onShow(): void {
|
||||
this.resetShow();
|
||||
}
|
||||
|
||||
async routePage(isError: boolean) {
|
||||
logInfo(TAG, `routePage ${isError}`);
|
||||
try {
|
||||
startTrace('enterPhotoBrowser');
|
||||
if (this.isThird) {
|
||||
this.broadCast.emit(BroadcastConstants.JUMP_THIRD_PHOTO_BROWSER, [this.pageName, this.mediaItem]);
|
||||
} else {
|
||||
this.broadCast.emit(BroadcastConstants.JUMP_PHOTO_BROWSER, [this.pageName, this.mediaItem]);
|
||||
}
|
||||
} catch (err) {
|
||||
logError(TAG, `fail callback, code: ${err.code}, msg: ${err.msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
async routeToPreviewPage() {
|
||||
try {
|
||||
logInfo(TAG, 'routeToPreviewPage');
|
||||
this.broadCast.emit(BroadcastConstants.JUMP_THIRD_PHOTO_BROWSER, [this.pageName, this.mediaItem]);
|
||||
} catch (err) {
|
||||
logError(TAG, `fail callback, code: ${err.code}, msg: ${err.msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
private onSelected() {
|
||||
logInfo(TAG, 'onSelected');
|
||||
this.mediaItem.setSelect(!this.mediaItem.isSelect)
|
||||
this.broadCast.emit(BroadcastConstants.SELECT, [this.mediaItem.index])
|
||||
}
|
||||
|
||||
private selectStateChange() {
|
||||
logInfo(TAG, `change selected ${this.isSelectedMode}`);
|
||||
if (this.isSelectedMode) {
|
||||
this.onSelected()
|
||||
} else {
|
||||
this.isSelectedMode = true
|
||||
this.pressAnimScale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack({ alignContent: Alignment.Start }) {
|
||||
Image(this.isError ? this.mediaItem.getAlt() : this.thumbnail)
|
||||
.aspectRatio(1)
|
||||
.rotate({ x: 0, y: 0, z: 1, angle: this.isError ? 0 : this.mediaItem.orientation })
|
||||
.objectFit(ImageFit.Cover)
|
||||
.autoResize(false)
|
||||
.onComplete(() => {
|
||||
logDebug(TAG, `Draw the image! ${this.thumbnail}`);
|
||||
})
|
||||
|
||||
.onError(() => {
|
||||
logError(TAG, `alt Image ${this.mediaItem.index} error :${this.thumbnail}`);
|
||||
if (this.thumbnail.length == 0 || this.mediaItem.width == 0 || this.mediaItem.height == 0) {
|
||||
this.resetShow()
|
||||
} else {
|
||||
this.isError = true
|
||||
}
|
||||
})
|
||||
.sharedTransition(this.pageName + this.mediaItem.getHashCode(), {
|
||||
duration: AnimationConstants.SHARE_TRANSITION_DURATION
|
||||
})
|
||||
|
||||
if (this.mediaItem.mediaType == MediaLib.MediaType.VIDEO) {
|
||||
Column()
|
||||
.position({ x: '0%', y: '50%' })
|
||||
.height('50%')
|
||||
.width('100%')
|
||||
.linearGradient({
|
||||
angle: 0,
|
||||
colors: [[$r('app.color.album_cover_gradient_start_color'), 0], [$r('app.color.transparent'), 1.0]]
|
||||
})
|
||||
Text(DateUtil.getFormattedDuration(this.mediaItem.duration))
|
||||
.fontSize($r('sys.float.ohos_id_text_size_caption'))
|
||||
.fontFamily($r('app.string.id_text_font_family_regular'))
|
||||
.fontColor($r('app.color.text_color_above_picture'))
|
||||
.lineHeight($r('app.float.grid_item_text_line_height'))
|
||||
.position({ x: '0%', y: '100%' })
|
||||
.markAnchor({
|
||||
x: $r('app.float.grid_item_duration_markAnchor_x'),
|
||||
y: $r('app.float.grid_item_duration_markAnchor_y')
|
||||
})
|
||||
.margin({ right: $r('app.float.grid_item_duration_margin_right') })
|
||||
}
|
||||
if (this.isFavourite) {
|
||||
Image($r('app.media.ic_favorite_overlay'))
|
||||
.height($r('app.float.icon_size'))
|
||||
.width($r('app.float.icon_size'))
|
||||
.objectFit(ImageFit.Contain)
|
||||
.position({ x: '100%', y: '0%' })
|
||||
.markAnchor({
|
||||
x: $r('app.float.grid_item_favor_markAnchor_x'),
|
||||
y: $r('app.float.grid_item_favor_markAnchor_y')
|
||||
})
|
||||
}
|
||||
|
||||
Column()
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
.backgroundColor(this.isSelectedMode && this.mediaItem.isSelect ?
|
||||
$r('app.color.item_selection_bg_color') : $r('app.color.transparent'))
|
||||
.onClick(() => {
|
||||
if (this.isSelectedMode) {
|
||||
this.onSelected();
|
||||
} else {
|
||||
logInfo(TAG, 'item onClick loadBmp');
|
||||
if (this.isThird) {
|
||||
this.broadCast.emit(BroadcastConstants.JUMP_THIRD_PHOTO_BROWSER, [this.pageName, this.mediaItem]);
|
||||
} else {
|
||||
this.broadCast.emit(BroadcastConstants.JUMP_PHOTO_BROWSER, [this.pageName, this.mediaItem]);
|
||||
}
|
||||
this.isEnteringPhoto = true;
|
||||
}
|
||||
})
|
||||
if (this.isSelectedMode) {
|
||||
Image($r('app.media.ic_photo_preview'))
|
||||
.onClick(() => {
|
||||
this.routeToPreviewPage();
|
||||
logInfo(TAG, 'expand.');
|
||||
})
|
||||
.height($r('app.float.icon_size_hot'))
|
||||
.width($r('app.float.icon_size_hot'))
|
||||
.position({ x: '0%', y: '0%' })
|
||||
.markAnchor({ x: 0, y: 0 })
|
||||
.padding($r('app.float.grid_item_preview_padding'))
|
||||
Image(this.mediaItem.isSelect
|
||||
? $r('app.media.ic_gallery_public_checkbox_filled') : $r('app.media.ic_checkbox_off_overlay'))
|
||||
.height($r('app.float.icon_size'))
|
||||
.width($r('app.float.icon_size'))
|
||||
.position({ x: '100%', y: '100%' })
|
||||
.markAnchor({
|
||||
x: $r('app.float.grid_item_checkbox_markAnchor'),
|
||||
y: $r('app.float.grid_item_checkbox_markAnchor')
|
||||
})
|
||||
.onClick(() => {
|
||||
this.onSelected();
|
||||
})
|
||||
}
|
||||
}
|
||||
.scale({
|
||||
x: this.pressAnimScale,
|
||||
y: this.pressAnimScale
|
||||
})
|
||||
.animation({
|
||||
duration: AnimationConstants.PRESS_ANIM_DURATION,
|
||||
curve: Curve.Ease
|
||||
})
|
||||
.onTouch(event => {
|
||||
logInfo(TAG, `onTouch trigger: isSelectedMode: ${this.isSelectedMode},
|
||||
isEnteringPhoto: ${this.isEnteringPhoto}, ${JSON.stringify(event)}`);
|
||||
if (this.isSelectedMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Press animation
|
||||
if (event.type == TouchType.Down) {
|
||||
this.pressAnimScale = AnimationConstants.PRESS_ANIM_SCALE;
|
||||
}
|
||||
|
||||
if (event.type == TouchType.Up && !this.isEnteringPhoto && this.pressAnimScale != 1) {
|
||||
this.pressAnimScale = 1;
|
||||
}
|
||||
})
|
||||
.gesture(LongPressGesture().onAction((event: GestureEvent) => {
|
||||
if (!this.isThird) {
|
||||
logInfo(TAG, `LongPressGesture ${this.isSelectedMode}`);
|
||||
this.selectStateChange();
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
@ -12,17 +12,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@Entry
|
||||
@Component
|
||||
export struct MainPage {
|
||||
@State message: string = 'Hello World'
|
||||
|
||||
export class PeerInfo {
|
||||
coverUri: any;
|
||||
deviceName: string;
|
||||
count: number; // the count of photos
|
||||
networkId: string;
|
||||
|
||||
constructor(uri, name, count, networkId) {
|
||||
this.coverUri = uri;
|
||||
this.deviceName = name;
|
||||
this.count = count;
|
||||
this.networkId = networkId;
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize(50)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
}
|
22
common/base/src/main/ets/constants/AnimationConstants.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
export class AnimationConstants {
|
||||
static readonly SHARE_TRANSITION_DURATION = 200;
|
||||
static readonly DELETE_ANIMATE_DURATION: number = 150;
|
||||
// Press animation duration
|
||||
static readonly PRESS_ANIM_DURATION = 100;
|
||||
// Press to scale the value at the end of the animation
|
||||
static readonly PRESS_ANIM_SCALE = 0.9;
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class BroadCastConstants {
|
||||
export class BroadcastConstants {
|
||||
static readonly SELECT = 'select';
|
||||
static readonly GROUP_SELECT = 'groupSelect';
|
||||
static readonly JUMP_PHOTO_BROWSER = 'JumpPhotoPage';
|
||||
@ -24,7 +24,6 @@ export class BroadCastConstants {
|
||||
static readonly BACK_PRESS_EVENT = 'back';
|
||||
static readonly RESET_STATE_EVENT = 'resetState';
|
||||
static readonly ON_TAB_CHANGED = 'onTabChanged';
|
||||
static readonly PHOTO_BROWSER_ACTIVE = 'photoBrowserActive';
|
||||
static readonly RESET_ZERO = 'resetZero';
|
||||
static readonly SHOW_DETAIL_DIALOG = 'showDetailDialog';
|
||||
static readonly SHOW_MULTI_SELECT_DIALOG = 'showMultiSelectDialog';
|
||||
@ -51,7 +50,8 @@ export class BroadCastConstants {
|
||||
static readonly INIT_DATE_TEXT = 'init_date_text';
|
||||
static readonly THIRD_ROUTE_PAGE = 'third_route_page';
|
||||
static readonly ON_DATA_RELOADED_WITH_EDIT = 'on_data_reloaded_with_edit';
|
||||
static readonly PHOTO_EDIT_SAVE_ID: string = 'photo_edit_save_id';
|
||||
static readonly PHOTO_EDIT_SAVE_COMPLETE: string = 'photo_edit_save_complete';
|
||||
static readonly CHANGE_SWIPER_DURATION = 'change_swiper_duration';
|
||||
// USED for AppStorage
|
||||
static readonly LEFT_BLANK: string = 'leftBlank';
|
||||
}
|
89
common/base/src/main/ets/constants/MediaConstants.ts
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
export class MediaConstants {
|
||||
// Media item status
|
||||
static readonly UNDEFINED = 0;
|
||||
static readonly PART_LOADED = 1
|
||||
static readonly LOADED = 2;
|
||||
static readonly TRASHED = 3;
|
||||
// Media type
|
||||
static readonly MEDIA_TYPE_IMAGE: string = 'image';
|
||||
static readonly MEDIA_TYPE_VIDEO: string = 'video';
|
||||
static readonly MEDIA_TYPE_ALBUM: string = 'album';
|
||||
static readonly MEDIA_TYPE_DEVICE: string = 'device';
|
||||
static readonly MEDIA_TYPE_REMOTE: string = 'remote';
|
||||
|
||||
static readonly DEVICE_STATE_ONLINE: string = 'online';
|
||||
static readonly DEVICE_STATE_OFFLINE: string = 'offline';
|
||||
static readonly DEVICE_STATE_CHANGE: string = 'change';
|
||||
static readonly ROTATE_NONE = 0;
|
||||
static readonly ROTATE_ONCE = 90;
|
||||
static readonly ROTATE_TWICE = 180;
|
||||
static readonly ROTATE_THIRD = 270;
|
||||
static readonly ROTATE_AROUND = 360;
|
||||
static readonly DEFAULT_SIZE = 256;
|
||||
// select type
|
||||
static readonly SELECT_TYPE_ALL = 0;
|
||||
static readonly SELECT_TYPE_VIDEO = 1;
|
||||
static readonly SELECT_TYPE_IMAGE = 2;
|
||||
// album id
|
||||
static readonly ALBUM_ID_ALL = 'default_all';
|
||||
static readonly ALBUM_ID_CAMERA = 'default_camera';
|
||||
static readonly ALBUM_ID_VIDEO = 'default_video';
|
||||
static readonly ALBUM_ID_RECYCLE = 'default_recycle';
|
||||
static readonly ALBUM_ID_FAVOR = 'default_favor';
|
||||
static readonly ALBUM_ID_SNAPSHOT = 'default_snapshot';
|
||||
static readonly ALBUM_ID_REMOTE = 'default_remote';
|
||||
static readonly ALBUM_DISABLE_COPY_LIST = new Set([
|
||||
MediaConstants.ALBUM_ID_ALL,
|
||||
MediaConstants.ALBUM_ID_VIDEO,
|
||||
MediaConstants.ALBUM_ID_RECYCLE,
|
||||
MediaConstants.ALBUM_ID_FAVOR
|
||||
]);
|
||||
static readonly ALBUM_DISABLE_DELETE_LIST = new Set([
|
||||
MediaConstants.ALBUM_ID_ALL,
|
||||
MediaConstants.ALBUM_ID_CAMERA,
|
||||
MediaConstants.ALBUM_ID_VIDEO,
|
||||
MediaConstants.ALBUM_ID_RECYCLE,
|
||||
MediaConstants.ALBUM_ID_FAVOR
|
||||
]);
|
||||
static readonly ALBUM_DISABLE_NEW_LIST = new Set([
|
||||
MediaConstants.ALBUM_ID_ALL,
|
||||
MediaConstants.ALBUM_ID_CAMERA,
|
||||
MediaConstants.ALBUM_ID_VIDEO,
|
||||
MediaConstants.ALBUM_ID_RECYCLE,
|
||||
MediaConstants.ALBUM_ID_FAVOR,
|
||||
MediaConstants.ALBUM_ID_SNAPSHOT
|
||||
]);
|
||||
static readonly ALBUM_DISABLE_RENAME_LIST = new Set([
|
||||
MediaConstants.ALBUM_ID_ALL,
|
||||
MediaConstants.ALBUM_ID_CAMERA,
|
||||
MediaConstants.ALBUM_ID_VIDEO,
|
||||
MediaConstants.ALBUM_ID_RECYCLE,
|
||||
MediaConstants.ALBUM_ID_FAVOR,
|
||||
MediaConstants.ALBUM_ID_SNAPSHOT
|
||||
]);
|
||||
static readonly ALBUM_DEFAULT_SORT_LIST = [
|
||||
MediaConstants.ALBUM_ID_CAMERA,
|
||||
MediaConstants.ALBUM_ID_ALL,
|
||||
MediaConstants.ALBUM_ID_VIDEO,
|
||||
MediaConstants.ALBUM_ID_SNAPSHOT,
|
||||
MediaConstants.ALBUM_ID_FAVOR
|
||||
];
|
||||
static readonly CAMERA_ALBUM_PATH = 'Camera'
|
||||
static readonly REMOTE_ALBUM_PATH = 'FromOtherDevices'
|
||||
static readonly SNAPSHOT_ALBUM_PATH = 'Screenshots'
|
||||
}
|
37
common/base/src/main/ets/constants/RouterConstants.ts
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
export class RouterConstants {
|
||||
static readonly ENTRY_FROM_NONE = 0;
|
||||
static readonly ENTRY_FROM_CAMERA = 1;
|
||||
static readonly ENTRY_FROM_SINGLE_SELECT = 2;
|
||||
static readonly ENTRY_FROM_MULTIPLE_SELECT = 3;
|
||||
static readonly ENTRY_FROM_RECYCLE = 4;
|
||||
static readonly ENTRY_FROM_DISTRIBUTED = 5;
|
||||
static readonly ENTRY_FROM_NORMAL = 6;
|
||||
static readonly ENTRY_FROM_FORM_ABILITY = 7;
|
||||
static readonly ENTRY_FROM_FORM_FORM_EDITOR = 8;
|
||||
static readonly ENTRY_FROM_VIEW_DATA = 9;
|
||||
static readonly ENTRY_FROM_FORM_ABILITY_NONE = 12;
|
||||
static readonly ENTRY_FROM = {
|
||||
NORMAL: 0,
|
||||
CAMERA: 1,
|
||||
SINGLE_SELECT: 2,
|
||||
MULTIPLE_SELECT: 3,
|
||||
RECYCLE: 4,
|
||||
DISTRIBUTED: 5,
|
||||
CARD: 6,
|
||||
VIEW_DATA: 7
|
||||
}
|
||||
}
|
42
common/base/src/main/ets/constants/WindowConstants.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
export class WindowConstants {
|
||||
static readonly MAIN_WINDOW: string = 'mainWindow';
|
||||
static readonly TOP_BAR_SIZE: number = 56;
|
||||
static readonly TOOL_BAR_SIZE: number = 72;
|
||||
static readonly BOTTOM_TOOL_BAR_SIZE: number = 196;
|
||||
static readonly FILTER_BOTTOM_TOOL_BAR_SIZE: number = 232;
|
||||
// Grid Constants
|
||||
static readonly ACTION_BAR_HEIGHT: number = 56;
|
||||
static readonly TAB_BAR_WIDTH: number = 96;
|
||||
static readonly GRID_GUTTER: number = 2;
|
||||
static readonly GRID_IMAGE_SIZE: number = 256;
|
||||
static readonly GRID_MAX_SIZE_RATIO: number = 1.2;
|
||||
static readonly GRID_MIN_COUNT: number = 4;
|
||||
static readonly SCROLL_BAR_SIDE_MIN_GAP: number = 12;
|
||||
static readonly SCROLL_MARGIN: number = 24;
|
||||
static readonly SCROLL_BAR_VISIBLE_THRESHOLD: number = 50;
|
||||
static readonly CARD_ASPECT_RATIO: number = 0.75;
|
||||
static readonly TEXT_SIZE_SUB_TITLE1: number = 18; // ohos_id_text_size_sub_title1
|
||||
static readonly TEXT_SIZE_BODY2: number = 14; // ohos_id_text_size_body2
|
||||
static readonly TEXT_SIZE_SUB_TITLE2: number = 16; // ohos_id_text_size_sub_title2
|
||||
|
||||
static readonly ALBUM_SET_NEW_ICON_SIZE: number = 22;
|
||||
static readonly ALBUM_SET_NEW_ICON_MARGIN: number = 8;
|
||||
static readonly ALBUM_SET_MARGIN: number = 24;
|
||||
static readonly ALBUM_SET_GUTTER: number = 12;
|
||||
static readonly ALBUM_SET_COVER_SIZE: number = 150;
|
||||
}
|
110
common/base/src/main/ets/data/AlbumDataItem.ts
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { logDebug, logError } from '../utils/LoggerUtils'
|
||||
import selectManager from '../manager/SelectManager'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { getFetchOptions } from '../helper/MediaDataHelper';
|
||||
|
||||
const TAG = "AlbumDataItem"
|
||||
|
||||
export class AlbumDataItem {
|
||||
index: number;
|
||||
id: string;
|
||||
uri: string;
|
||||
orientation: number;
|
||||
displayName: string;
|
||||
count: number;
|
||||
isDisableRename: boolean;
|
||||
isDisableDelete: boolean;
|
||||
relativePath: string;
|
||||
innerId: number;
|
||||
selectType: number = MediaConstants.SELECT_TYPE_ALL
|
||||
deviceId: string = ""
|
||||
isSelect: boolean = false
|
||||
status: number = MediaConstants.UNDEFINED
|
||||
|
||||
constructor(id: string, count: number, displayName: string, selectType: number, deviceId: string) {
|
||||
this.id = id
|
||||
this.displayName = displayName
|
||||
this.count = count
|
||||
this.isDisableRename = MediaConstants.ALBUM_DISABLE_RENAME_LIST.has(id)
|
||||
this.isDisableDelete = MediaConstants.ALBUM_DISABLE_DELETE_LIST.has(id)
|
||||
this.selectType = selectType
|
||||
this.deviceId = deviceId
|
||||
}
|
||||
|
||||
getHashCode(): string {
|
||||
return `${this.id} ${this.orientation}`
|
||||
}
|
||||
|
||||
async load(): Promise<void> {
|
||||
if (this.status >= MediaConstants.LOADED) {
|
||||
return
|
||||
}
|
||||
let fetchOption: MediaLib.MediaFetchOptions = await getFetchOptions(this.selectType, this.id, this.deviceId)
|
||||
let fileAsset = (await mediaModel.getAllMediaItem(this.id, fetchOption, false)).fileAsset
|
||||
this.update(fileAsset)
|
||||
}
|
||||
|
||||
update(fileAsset: MediaLib.FileAsset) {
|
||||
this.uri = fileAsset.uri
|
||||
this.orientation = fileAsset.orientation
|
||||
this.relativePath = fileAsset.relativePath
|
||||
|
||||
this.status = MediaConstants.LOADED
|
||||
}
|
||||
|
||||
async getRelativePath(): Promise<string> {
|
||||
await this.load()
|
||||
return this.relativePath
|
||||
}
|
||||
|
||||
getThumbnail(): string{
|
||||
logDebug(TAG, `this.uri ${this.uri}`)
|
||||
return this.uri + `/thumbnail/256/256`
|
||||
}
|
||||
|
||||
async getVideoCount(): Promise<number> {
|
||||
if (this.selectType == MediaConstants.SELECT_TYPE_IMAGE) {
|
||||
return 0
|
||||
}
|
||||
let videoFetchOption: MediaLib.MediaFetchOptions = await getFetchOptions(MediaConstants.SELECT_TYPE_VIDEO, this.id, this.deviceId)
|
||||
return (await mediaModel.getAllMediaItem(this.id, videoFetchOption, true)).counts
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.isSelect = isSelect
|
||||
selectManager.setSelect(this.uri, this.isSelect)
|
||||
}
|
||||
|
||||
async onDelete(): Promise<boolean> {
|
||||
try {
|
||||
let fetchOption: MediaLib.MediaFetchOptions = await getFetchOptions(this.selectType, this.id, "")
|
||||
await mediaModel.deleteAll(fetchOption)
|
||||
selectManager.deleteSelect(this.uri)
|
||||
this.status = MediaConstants.TRASHED
|
||||
return true
|
||||
} catch (err) {
|
||||
logError(TAG, `onDelete error: ${JSON.stringify(err)}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
isDeleted(): boolean {
|
||||
return this.status == MediaConstants.TRASHED
|
||||
}
|
||||
}
|
41
common/base/src/main/ets/data/FavorMediaDataItem.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { MediaDataItem } from './MediaDataItem'
|
||||
|
||||
export class FavorMediaDataItem extends MediaDataItem {
|
||||
constructor(selections: string, selectionArgs: Array<string>, index: number) {
|
||||
super(selections, selectionArgs, "", index)
|
||||
}
|
||||
|
||||
async loadFileAsset(): Promise<MediaLib.FileAsset> {
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: this.selections,
|
||||
selectionArgs: this.selectionArgs,
|
||||
order: `date_added DESC LIMIT ${this.index},1`
|
||||
};
|
||||
return (await mediaModel.getAllFavorMediaItem(fetchOption, false)).fileAsset
|
||||
}
|
||||
|
||||
async setFavor(): Promise<boolean> {
|
||||
let isSuccess: boolean = await super.setFavor()
|
||||
let isFavor: boolean = await super.isFavor()
|
||||
this.status = isFavor ? this.status : MediaConstants.TRASHED
|
||||
return isSuccess
|
||||
}
|
||||
}
|
211
common/base/src/main/ets/data/MediaDataItem.ts
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug, logInfo, logWarn, logError } from '../utils/LoggerUtils'
|
||||
import { ViewType } from '../data/ViewType'
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { setOrientation } from '../helper/MediaDataHelper'
|
||||
import selectManager from '../manager/SelectManager'
|
||||
|
||||
const TAG = "MediaDataItem"
|
||||
|
||||
const STATUS_UNDEFINED = -1
|
||||
const STATUS_FALSE = 0
|
||||
const STATUS_TRUE = 1
|
||||
|
||||
export class MediaDataItem {
|
||||
readonly viewType = ViewType.ITEM
|
||||
readonly hashIndex: number
|
||||
index: number
|
||||
dateAdded: number
|
||||
dateModified: number
|
||||
dateTaken: number
|
||||
status: number = MediaConstants.UNDEFINED
|
||||
isSelect: boolean = false
|
||||
id: number
|
||||
uri: string
|
||||
orientation: number
|
||||
duration: number
|
||||
size: number
|
||||
width: number; // width changed by orientation
|
||||
height: number; // height changed by orientation
|
||||
imgWidth: number; // may be smaller than width, as width is too large
|
||||
imgHeight: number; // may be smaller than height, as height is too large
|
||||
path: string
|
||||
title: string
|
||||
displayName: string
|
||||
mediaType: MediaLib.MediaType
|
||||
favouriteStatus: number = STATUS_UNDEFINED
|
||||
canRotate: number = STATUS_UNDEFINED
|
||||
selections: string = ""
|
||||
selectionArgs: Array<string> = new Array()
|
||||
deviceId: string = ''
|
||||
|
||||
constructor(selections: string, selectionArgs: Array<string>, deviceId: string, index: number) {
|
||||
this.selections = selections
|
||||
this.selectionArgs = selectionArgs
|
||||
this.deviceId = deviceId
|
||||
this.hashIndex = index
|
||||
this.index = index
|
||||
}
|
||||
|
||||
getHashCode(): string {
|
||||
return this.status == MediaConstants.UNDEFINED ? `${this.hashIndex}` : `${this.uri} ${this.orientation}`
|
||||
}
|
||||
|
||||
async loadFileAsset(): Promise<MediaLib.FileAsset> {
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: this.selections,
|
||||
selectionArgs: this.selectionArgs,
|
||||
order: `date_added DESC LIMIT ${this.index},1`
|
||||
};
|
||||
if (this.deviceId.length > 0) {
|
||||
fetchOption['networkId'] = this.deviceId
|
||||
}
|
||||
return (await mediaModel.getAllCommonMediaItem(fetchOption, false)).fileAsset
|
||||
}
|
||||
|
||||
async load(isForce: boolean): Promise<void> {
|
||||
logInfo(TAG, `load ${this.status}`)
|
||||
if (this.status > (isForce ? MediaConstants.PART_LOADED : MediaConstants.UNDEFINED)) {
|
||||
return
|
||||
}
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
if (fileAsset) {
|
||||
this.update(fileAsset)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
update(fileAsset: MediaLib.FileAsset) {
|
||||
this.id = fileAsset.id
|
||||
this.uri = fileAsset.uri
|
||||
this.orientation = fileAsset.orientation
|
||||
this.mediaType = fileAsset.mediaType
|
||||
this.duration = fileAsset.duration
|
||||
this.size = fileAsset.size;
|
||||
if (this.orientation == MediaConstants.ROTATE_ONCE || this.orientation == MediaConstants.ROTATE_THIRD) {
|
||||
this.width = fileAsset.height;
|
||||
this.height = fileAsset.width;
|
||||
} else {
|
||||
this.width = fileAsset.width;
|
||||
this.height = fileAsset.height;
|
||||
}
|
||||
this.imgWidth = this.width;
|
||||
this.imgHeight = this.height;
|
||||
this.path = fileAsset.relativePath
|
||||
this.title = fileAsset.title;
|
||||
this.displayName = fileAsset.displayName
|
||||
this.dateAdded = fileAsset.dateAdded * 1000
|
||||
this.dateModified = fileAsset.dateModified * 1000
|
||||
this.dateTaken = fileAsset.dateTaken * 1000
|
||||
this.isSelect = selectManager.isSelect(this.uri, this.isSelect)
|
||||
|
||||
// may change
|
||||
fileAsset.isFavorite().then((isFavor: boolean) => this.favouriteStatus = (isFavor) ? STATUS_TRUE : STATUS_FALSE)
|
||||
|
||||
if (this.width > 0 && this.height > 0) {
|
||||
this.status = MediaConstants.LOADED
|
||||
} else {
|
||||
this.status = MediaConstants.PART_LOADED
|
||||
}
|
||||
}
|
||||
|
||||
getThumbnail(width: number, height: number): string{
|
||||
logDebug(TAG, `getThumbnail ${this.status}`)
|
||||
if (this.status != MediaConstants.LOADED) {
|
||||
logWarn(TAG, `getThumbnail fail as status: ${this.status}`)
|
||||
return ""
|
||||
}
|
||||
logDebug(TAG, `this.uri ${this.uri}`)
|
||||
return this.uri + `/thumbnail/${width}/${height}`
|
||||
}
|
||||
|
||||
getAlt(): Resource{
|
||||
if (this.mediaType == MediaLib.MediaType.VIDEO) {
|
||||
return $r('app.media.alt_video_placeholder')
|
||||
} else {
|
||||
return $r('app.media.alt_placeholder')
|
||||
}
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.isSelect = isSelect
|
||||
selectManager.setSelect(this.uri, this.isSelect)
|
||||
}
|
||||
|
||||
async onDelete(): Promise<boolean> {
|
||||
try {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
await fileAsset.trash(true)
|
||||
selectManager.deleteSelect(this.uri)
|
||||
this.status = MediaConstants.TRASHED
|
||||
return true
|
||||
} catch (err) {
|
||||
logError(TAG, `onDelete error: ${JSON.stringify(err)}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
isDeleted(): boolean {
|
||||
return this.status == MediaConstants.TRASHED
|
||||
}
|
||||
|
||||
async isFavor(): Promise<boolean> {
|
||||
if (this.favouriteStatus == STATUS_UNDEFINED) {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
this.favouriteStatus = (await fileAsset.isFavorite()) ? STATUS_TRUE : STATUS_FALSE
|
||||
}
|
||||
return this.favouriteStatus == STATUS_TRUE
|
||||
}
|
||||
|
||||
async setFavor(): Promise<boolean> {
|
||||
let status = !(await this.isFavor())
|
||||
try {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
await fileAsset.favorite(status)
|
||||
await fileAsset.commitModify()
|
||||
this.favouriteStatus = status ? STATUS_TRUE : STATUS_FALSE
|
||||
return true
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async setOrientation(): Promise<void> {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
this.orientation = (this.orientation + MediaConstants.ROTATE_ONCE) % MediaConstants.ROTATE_AROUND
|
||||
await setOrientation(fileAsset, this.orientation)
|
||||
let tmp = this.width
|
||||
this.width = this.height
|
||||
this.height = tmp
|
||||
}
|
||||
|
||||
async setName(name: string): Promise<void> {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
let displayName = fileAsset.displayName;
|
||||
let index = displayName.lastIndexOf('.');
|
||||
displayName = name + displayName.slice(index);
|
||||
|
||||
this.displayName = displayName
|
||||
fileAsset.displayName = displayName;
|
||||
|
||||
this.title = name
|
||||
fileAsset.title = name;
|
||||
await fileAsset.commitModify()
|
||||
}
|
||||
}
|
51
common/base/src/main/ets/data/PeerDataItem.ts
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug } from '../utils/LoggerUtils'
|
||||
import selectManager from '../manager/SelectManager'
|
||||
|
||||
const TAG = "PeerDataItem"
|
||||
|
||||
export class PeerDataItem {
|
||||
index: number;
|
||||
uri: string;
|
||||
orientation: number;
|
||||
deviceName: string;
|
||||
count: number;
|
||||
networkId: string;
|
||||
isSelect: boolean;
|
||||
|
||||
constructor(count: number, peer: MediaLib.PeerInfo, fileAsset: MediaLib.FileAsset) {
|
||||
this.uri = fileAsset.uri
|
||||
this.orientation = fileAsset.orientation
|
||||
this.deviceName = peer.deviceName
|
||||
this.count = count
|
||||
this.networkId = peer.networkId
|
||||
}
|
||||
|
||||
getHashCode() {
|
||||
return `${this.networkId} ${this.orientation}`
|
||||
}
|
||||
|
||||
getThumbnail(): string{
|
||||
logDebug(TAG, `this.uri ${this.uri}`)
|
||||
return this.uri + `/thumbnail/256/256`
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.isSelect = isSelect
|
||||
selectManager.setSelect(this.uri, this.isSelect)
|
||||
}
|
||||
}
|
@ -13,19 +13,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import i18n from '@ohos.i18n';
|
||||
import { Logger } from './Logger'
|
||||
export class SimpleAlbumDataItem {
|
||||
readonly id: string
|
||||
readonly displayName: string
|
||||
readonly relativePath: string
|
||||
readonly deviceId: string
|
||||
readonly deviceName: string
|
||||
|
||||
export class SystemUtil {
|
||||
static logger: Logger = new Logger('SystemUtil');
|
||||
|
||||
public static getSystemLanguage(): string {
|
||||
let systemLocale = i18n.getSystemLanguage();
|
||||
let localInfo = systemLocale.split('-')[0];
|
||||
return localInfo;
|
||||
}
|
||||
|
||||
public static is24HourClock(): boolean {
|
||||
return i18n.is24HourClock();
|
||||
constructor(id: string, displayName: string, relativePath: string, deviceId: string, deviceName: string) {
|
||||
this.id = id
|
||||
this.displayName = displayName
|
||||
this.relativePath = relativePath
|
||||
this.deviceId = deviceId
|
||||
this.deviceName = deviceName
|
||||
}
|
||||
}
|
65
common/base/src/main/ets/data/TrashMediaDataItem.ts
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logError } from '../utils/LoggerUtils';
|
||||
import selectManager from '../manager/SelectManager'
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { MediaDataItem } from './MediaDataItem'
|
||||
|
||||
const TAG = "TrashMediaDataItem"
|
||||
|
||||
export class TrashMediaDataItem extends MediaDataItem {
|
||||
constructor(selections: string, selectionArgs: Array<string>, index: number) {
|
||||
super(selections, selectionArgs, "", index)
|
||||
this.setSelect(true)
|
||||
}
|
||||
|
||||
async loadFileAsset(): Promise<MediaLib.FileAsset> {
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: this.selections,
|
||||
selectionArgs: this.selectionArgs,
|
||||
order: `date_added DESC LIMIT ${this.index},1`
|
||||
};
|
||||
return (await mediaModel.getAllTrashMediaItem(fetchOption, false)).fileAsset
|
||||
}
|
||||
|
||||
async onRecover(): Promise<boolean> {
|
||||
try {
|
||||
let fileAsset = await this.loadFileAsset()
|
||||
|
||||
await fileAsset.trash(false)
|
||||
selectManager.deleteSelect(this.uri)
|
||||
this.status = MediaConstants.TRASHED
|
||||
return true
|
||||
} catch (err) {
|
||||
logError(TAG, `onRecover error: ${JSON.stringify(err)}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async onDelete(): Promise<boolean> {
|
||||
try {
|
||||
await mediaModel.deleteOne(this.uri)
|
||||
selectManager.deleteSelect(this.uri)
|
||||
this.status = MediaConstants.TRASHED
|
||||
return true
|
||||
} catch (err) {
|
||||
logError(TAG, `onDelete error: ${JSON.stringify(err)}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
144
common/base/src/main/ets/helper/MediaDataHelper.ts
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 image from '@ohos.multimedia.image'
|
||||
import MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logInfo, logError } from '../utils/LoggerUtils'
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import { getResourceString } from '../utils/ResourceUtils'
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
|
||||
const TAG = "MediaDataHelper"
|
||||
|
||||
export class Rotatable {
|
||||
rotatable: boolean
|
||||
orientation: number
|
||||
}
|
||||
|
||||
export async function setOrientation(fileAsset: MediaLib.FileAsset, orientation: number): Promise<void> {
|
||||
logInfo(TAG, `setOrientation`)
|
||||
try {
|
||||
let fd: number = await mediaModel.openAsset('RW', fileAsset);
|
||||
let imageSourceApi: image.ImageSource = image.createImageSource(fd);
|
||||
await imageSourceApi.modifyImageProperty("Orientation", getPropertyValidOrientation(orientation))
|
||||
imageSourceApi.release()
|
||||
mediaModel.closeAsset(fd, fileAsset)
|
||||
} catch (err) {
|
||||
logError(TAG, `setOrientation err ${JSON.stringify(err)}`)
|
||||
fileAsset.orientation = orientation
|
||||
await fileAsset.commitModify()
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyValidOrientation(orientation: number): string {
|
||||
logInfo(TAG, `getPropertyValidOrientation ${orientation}`)
|
||||
switch (orientation) {
|
||||
case MediaConstants.ROTATE_NONE:
|
||||
return "1";
|
||||
case MediaConstants.ROTATE_THIRD:
|
||||
return "8";
|
||||
case MediaConstants.ROTATE_TWICE:
|
||||
return "3";
|
||||
case MediaConstants.ROTATE_ONCE:
|
||||
return "6";
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAlbumDisplayName(name: string): Promise<string> {
|
||||
switch (name) {
|
||||
case MediaConstants.ALBUM_ID_ALL:
|
||||
return await getResourceString($r('app.string.album_all'));
|
||||
case MediaConstants.ALBUM_ID_VIDEO:
|
||||
return await getResourceString($r('app.string.album_video'));
|
||||
case MediaConstants.ALBUM_ID_RECYCLE:
|
||||
return await getResourceString($r('app.string.album_recycle'));
|
||||
case MediaConstants.ALBUM_ID_CAMERA:
|
||||
return await getResourceString($r('app.string.album_camera'));
|
||||
case MediaConstants.ALBUM_ID_FAVOR:
|
||||
return await getResourceString($r('app.string.album_favor'));
|
||||
case MediaConstants.ALBUM_ID_REMOTE:
|
||||
return await getResourceString($r('app.string.album_remote_device'));
|
||||
case MediaConstants.ALBUM_ID_SNAPSHOT:
|
||||
return await getResourceString($r('app.string.album_screen_shot'));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function getFetchOptions(selectType: number, albumId: string, deviceId: string): Promise<MediaLib.MediaFetchOptions> {
|
||||
let selections: string = ""
|
||||
let selectionArgs: Array<string> = []
|
||||
let order: string = `date_added DESC`
|
||||
if (selectType == MediaConstants.SELECT_TYPE_VIDEO || albumId == MediaConstants.ALBUM_ID_VIDEO) {
|
||||
selections = MediaLib.FileKey.MEDIA_TYPE + ' = ?'
|
||||
selectionArgs = [MediaLib.MediaType.VIDEO.toString()]
|
||||
} else if (selectType == MediaConstants.SELECT_TYPE_IMAGE && albumId != MediaConstants.ALBUM_ID_VIDEO) {
|
||||
selections = MediaLib.FileKey.MEDIA_TYPE + ' = ?'
|
||||
selectionArgs = [MediaLib.MediaType.IMAGE.toString()]
|
||||
} else if (selectType == MediaConstants.SELECT_TYPE_IMAGE && albumId == MediaConstants.ALBUM_ID_VIDEO) {
|
||||
return undefined
|
||||
} else {
|
||||
selections = MediaLib.FileKey.MEDIA_TYPE + ' = ? or ' + MediaLib.FileKey.MEDIA_TYPE + ' = ?'
|
||||
selectionArgs = [MediaLib.MediaType.IMAGE.toString(), MediaLib.MediaType.VIDEO.toString()]
|
||||
}
|
||||
if (albumId == MediaConstants.ALBUM_ID_CAMERA) {
|
||||
let path = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_CAMERA)
|
||||
selections = `(${selections}) and ${MediaLib.FileKey.ALBUM_NAME} = ?`
|
||||
selectionArgs.push(path.substr(0, path.length - 1))
|
||||
} else if (albumId == MediaConstants.ALBUM_ID_SNAPSHOT) {
|
||||
let path = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_IMAGE) + "Screenshots/"
|
||||
selections = `(${selections}) and ${MediaLib.FileKey.RELATIVE_PATH} = ?`
|
||||
selectionArgs.push(path)
|
||||
} else if ((new Number(albumId).valueOf() || 0) > 0) {
|
||||
selections = `(${selections}) and ${MediaLib.FileKey.ALBUM_ID} = ?`
|
||||
selectionArgs.push(albumId)
|
||||
}
|
||||
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: selections,
|
||||
selectionArgs: selectionArgs,
|
||||
order: order
|
||||
};
|
||||
|
||||
if (deviceId.length > 0) {
|
||||
fetchOption['networkId'] = deviceId
|
||||
}
|
||||
return fetchOption
|
||||
}
|
||||
|
||||
export async function getFetchOptionsByItem(item: SimpleAlbumDataItem): Promise<MediaLib.MediaFetchOptions> {
|
||||
let selections: string = `${MediaLib.FileKey.MEDIA_TYPE} = ? or ${MediaLib.FileKey.MEDIA_TYPE} = ?`
|
||||
let selectionArgs: string[] = [MediaLib.MediaType.IMAGE.toString(), MediaLib.MediaType.VIDEO.toString()]
|
||||
|
||||
if (item.displayName.length > 0) {
|
||||
selections = `(${selections}) and ${MediaLib.FileKey.DISPLAY_NAME} = ?`
|
||||
selectionArgs.push(item.displayName)
|
||||
}
|
||||
|
||||
if (item.relativePath.length > 0) {
|
||||
selections = `(${selections}) and ${MediaLib.FileKey.RELATIVE_PATH} = ?`
|
||||
selectionArgs.push(item.relativePath)
|
||||
}
|
||||
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: selections,
|
||||
selectionArgs: selectionArgs,
|
||||
order: `date_added DESC`
|
||||
};
|
||||
return fetchOption
|
||||
}
|
38
common/base/src/main/ets/manager/BroadcastManager.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logInfo } from '../utils/LoggerUtils'
|
||||
import { Broadcast } from '../utils/Broadcast'
|
||||
import createOrGet from '../utils/SingleInstanceUtils';
|
||||
|
||||
const TAG = "BroadcastManager"
|
||||
|
||||
export class BroadcastManager {
|
||||
// The global Broadcast of the application process. Event registration and destruction should be paired
|
||||
private appBroadcast: Broadcast;
|
||||
|
||||
constructor() {
|
||||
logInfo(TAG, 'constructor');
|
||||
this.appBroadcast = new Broadcast();
|
||||
}
|
||||
|
||||
public getBroadcast(): Broadcast {
|
||||
return this.appBroadcast;
|
||||
}
|
||||
}
|
||||
|
||||
let broadcastManager = createOrGet(BroadcastManager, TAG);
|
||||
|
||||
export default broadcastManager as BroadcastManager;
|
@ -13,10 +13,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import inputConsumer from '@ohos.multimodalInput.inputConsumer';
|
||||
import { Logger } from '../../utils/Logger';
|
||||
import { logDebug } from '../utils/LoggerUtils';
|
||||
|
||||
const TAG = "MultimodalInputManager"
|
||||
|
||||
export class MultimodalInputManager {
|
||||
logger: Logger = new Logger('MultimodalInputManager');
|
||||
|
||||
//win + N
|
||||
leftKeyOptions: any = {
|
||||
@ -41,34 +42,34 @@ export class MultimodalInputManager {
|
||||
};
|
||||
|
||||
async registerListener(callback) {
|
||||
this.logger.debug(`registerListener start`);
|
||||
logDebug(TAG, `registerListener start`);
|
||||
inputConsumer.on('key', this.leftKeyOptions, (data) => {
|
||||
this.logger.debug(`notificationRegister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `notificationRegister data: ${JSON.stringify(data)}`);
|
||||
callback(0);
|
||||
});
|
||||
inputConsumer.on('key', this.rightKeyOptions, (data) => {
|
||||
this.logger.debug(`controlRegister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `controlRegister data: ${JSON.stringify(data)}`);
|
||||
callback(1);
|
||||
});
|
||||
inputConsumer.on('key', this.escKeyOptions, (data) => {
|
||||
this.logger.debug(`escRegister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `escRegister data: ${JSON.stringify(data)}`);
|
||||
callback(2);
|
||||
});
|
||||
this.logger.debug(`registerListener end`);
|
||||
logDebug(TAG, `registerListener end`);
|
||||
}
|
||||
|
||||
async unregisterListener() {
|
||||
this.logger.debug(`unregisterListener start`);
|
||||
logDebug(TAG, `unregisterListener start`);
|
||||
inputConsumer.off('key', this.leftKeyOptions, (data) => {
|
||||
this.logger.debug(`notificationUnregister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `notificationUnregister data: ${JSON.stringify(data)}`);
|
||||
});
|
||||
inputConsumer.off('key', this.rightKeyOptions, (data) => {
|
||||
this.logger.debug(`controlUnregister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `controlUnregister data: ${JSON.stringify(data)}`);
|
||||
});
|
||||
inputConsumer.off('key', this.escKeyOptions, (data) => {
|
||||
this.logger.debug(`escUnregister data: ${JSON.stringify(data)}`);
|
||||
logDebug(TAG, `escUnregister data: ${JSON.stringify(data)}`);
|
||||
});
|
||||
this.logger.debug(`unregisterListener end`);
|
||||
logDebug(TAG, `unregisterListener end`);
|
||||
}
|
||||
}
|
||||
|
404
common/base/src/main/ets/manager/ScreenManager.ts
Normal file
@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 deviceInfo from '@ohos.deviceInfo';
|
||||
import window from '@ohos.window';
|
||||
import createOrGet from '../utils/SingleInstanceUtils';
|
||||
import { logDebug, logInfo, logError } from '../utils/LoggerUtils'
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import { WindowConstants } from '../constants/WindowConstants'
|
||||
import { getResourceString } from '../utils/ResourceUtils'
|
||||
|
||||
export enum ColumnSize {
|
||||
COLUMN_TWO = 2,
|
||||
COLUMN_FOUR = 4,
|
||||
COLUMN_SIX = 6,
|
||||
COLUMN_EIGHT = 8,
|
||||
COLUMN_TWELVE = 12
|
||||
}
|
||||
|
||||
enum ScreenWidth {
|
||||
WIDTH_MEDIUM = 520,
|
||||
WIDTH_LARGE = 840
|
||||
}
|
||||
|
||||
enum WindowMode {
|
||||
UNDEFINED = 1,
|
||||
FULL_SCREEN,
|
||||
PRIMARY,
|
||||
SECONDARY,
|
||||
FLOATING
|
||||
}
|
||||
|
||||
const TAG = "ScreenManager"
|
||||
|
||||
const APP_KEY_SCREEN_MANAGER = 'app_key_screen_manager';
|
||||
|
||||
const SCREEN_ORIENTATION_HORIZONTAL: string = 'isHorizontal';
|
||||
const SCREEN_SIDEBAR: string = 'isSidebar';
|
||||
|
||||
const COLUMN_MARGIN: number = 12;
|
||||
const COLUMN_GUTTER: number = 12;
|
||||
|
||||
class ScreenManager {
|
||||
readonly ON_WIN_SIZE_CHANGED = 'on_win_size_changed';
|
||||
readonly ON_LEFT_BLANK_CHANGED = 'on_left_blank_changed';
|
||||
readonly DEFAULT_WIDTH: number = 1920;
|
||||
readonly DEFAULT_HEIGHT: number = 1080;
|
||||
readonly SPLIT_THRESHOLD = 1.7;
|
||||
private winWidth = 0.0;
|
||||
private winHeight = 0.0;
|
||||
private statusBarHeight = 0;
|
||||
private naviBarHeight = 0;
|
||||
private leftBlank: [number, number, number, number] = [0, 0, 0, 0];
|
||||
private events = [];
|
||||
private mainWindow: window.Window = undefined;
|
||||
|
||||
// Default orientation
|
||||
private horizontal = deviceInfo.deviceType != ('phone' || 'default')
|
||||
|
||||
// Default sidebar
|
||||
private sidebar = deviceInfo.deviceType != ('phone' || 'default')
|
||||
private windowMode = WindowMode.UNDEFINED;
|
||||
|
||||
constructor() {
|
||||
logInfo(TAG, 'constructor');
|
||||
}
|
||||
|
||||
async initializationSize(win): Promise<void> {
|
||||
this.mainWindow = win;
|
||||
this.setMainWindow(win)
|
||||
await this.checkWindowMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Listeners
|
||||
*
|
||||
* @param event
|
||||
* @param fn
|
||||
*/
|
||||
on(event, fn) {
|
||||
if (Array.isArray(event)) {
|
||||
for (let i = 0, l = event.length; i < l; i++) {
|
||||
this.on(event[i], fn);
|
||||
}
|
||||
} else {
|
||||
(this.events[event] || (this.events[event] = [])).push(fn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Listeners
|
||||
*
|
||||
* @param event
|
||||
* @param fn
|
||||
*/
|
||||
off(event, fn) {
|
||||
if (event == null || event == undefined) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(event)) {
|
||||
for (let i = 0, l = event.length; i < l; i++) {
|
||||
this.off(event[i], fn);
|
||||
}
|
||||
}
|
||||
const cbs = this.events[event];
|
||||
if (!cbs) {
|
||||
return;
|
||||
}
|
||||
if (fn == null || fn == undefined) {
|
||||
return;
|
||||
}
|
||||
let cb;
|
||||
let i = cbs.length;
|
||||
while (i--) {
|
||||
cb = cbs[i];
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
cbs.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private emit(event, argument: any[]) {
|
||||
let _self = this;
|
||||
if (!this.events[event]) {
|
||||
return;
|
||||
}
|
||||
let cbs = [...this.events[event]];
|
||||
if (cbs) {
|
||||
for (let i = 0, l = cbs.length; i < l; i++) {
|
||||
let ref = cbs[i];
|
||||
if (ref) {
|
||||
try {
|
||||
ref.apply(_self, argument);
|
||||
} catch (e) {
|
||||
new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isLeftBlankInitialized(): boolean {
|
||||
return this.leftBlank[0] != 0 || this.leftBlank[1] != 0 || this.leftBlank[2] != 0 || this.leftBlank[3] != 0;
|
||||
}
|
||||
|
||||
// Unit:vp
|
||||
getWinWidth(): number {
|
||||
return px2vp(this.winWidth);
|
||||
}
|
||||
|
||||
// Unit:vp
|
||||
getWinHeight(): number {
|
||||
return px2vp(this.winHeight);
|
||||
}
|
||||
|
||||
getStatusBarHeight(): number {
|
||||
return px2vp(this.statusBarHeight);
|
||||
}
|
||||
|
||||
getNaviBarHeight(): number {
|
||||
return px2vp(this.naviBarHeight);
|
||||
}
|
||||
|
||||
async initWindowMode() {
|
||||
logDebug(TAG, `start to initialize photos application window mode: ${this.windowMode}`);
|
||||
}
|
||||
|
||||
isSplitMode(): boolean {
|
||||
return (WindowMode.PRIMARY == this.windowMode || WindowMode.SECONDARY == this.windowMode)
|
||||
}
|
||||
|
||||
async checkWindowMode() {
|
||||
let before = this.windowMode;
|
||||
let mode = await globalThis.photosWindowStage.getWindowMode();
|
||||
logInfo(TAG, `photos application before/current window mode: ${before}/${mode}`);
|
||||
|
||||
if (before == mode) {
|
||||
return;
|
||||
}
|
||||
this.windowMode = mode;
|
||||
if (WindowMode.FULL_SCREEN == this.windowMode) {
|
||||
await this.setFullScreen();
|
||||
} else {
|
||||
this.setSplitScreen();
|
||||
}
|
||||
}
|
||||
|
||||
private setMainWindow(win: window.Window) {
|
||||
logDebug(TAG, 'setMainWindow');
|
||||
win.on('windowSizeChange', (data) => {
|
||||
logDebug(TAG, `windowSizeChange ${JSON.stringify(data)}`);
|
||||
this.checkWindowMode()
|
||||
this.onWinSizeChanged(data);
|
||||
})
|
||||
}
|
||||
|
||||
private async setFullScreen() {
|
||||
let topWindow: any = AppStorage.Get(WindowConstants.MAIN_WINDOW);
|
||||
logDebug(TAG, 'getTopWindow start');
|
||||
try {
|
||||
await topWindow.setLayoutFullScreen(true)
|
||||
logDebug(TAG, 'setFullScreen true Succeeded');
|
||||
await this.hideStatusBar(topWindow);
|
||||
} catch (err) {
|
||||
logError(TAG, `setFullScreen err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
setSplitScreen() {
|
||||
try {
|
||||
this.statusBarHeight = 0;
|
||||
this.naviBarHeight = 0;
|
||||
this.leftBlank = [0, 0, 0, 0];
|
||||
AppStorage.SetOrCreate(BroadcastConstants.LEFT_BLANK, this.leftBlank);
|
||||
} catch (err) {
|
||||
logError(TAG, `setSplitScreen err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async hideStatusBar(topWindow: any) {
|
||||
logDebug(TAG, 'hideStatusBar start');
|
||||
let names = ['navigation'];
|
||||
logDebug(TAG, `getTopWindow names: ${names} end`);
|
||||
try {
|
||||
await topWindow.setSystemBarEnable(names)
|
||||
logDebug(TAG, 'hideStatusBar Succeeded');
|
||||
let data = await topWindow.getAvoidArea(0)
|
||||
logDebug(TAG, `Succeeded in obtaining the area. Data: ${JSON.stringify(data)}`);
|
||||
this.onLeftBlankChanged(data);
|
||||
let barColor = await getResourceString($r('app.color.default_background_color'));
|
||||
let barContentColor = await getResourceString($r('app.color.default_bar_content_color'));
|
||||
if (!barColor) {
|
||||
barColor = '#00FFFFFF';
|
||||
}
|
||||
if (!barContentColor) {
|
||||
barContentColor = '#FF000000';
|
||||
}
|
||||
await topWindow.setSystemBarProperties({
|
||||
navigationBarColor: barColor,
|
||||
navigationBarContentColor: barContentColor
|
||||
});
|
||||
logInfo(TAG, 'setStatusBarColor done');
|
||||
} catch (err) {
|
||||
logError(TAG, `hideStatusBar err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
async setNavigationBarColor(barColor: string, barContentColor: string) {
|
||||
logDebug(TAG, 'setNavigationBarColor start');
|
||||
let topWindow: any = AppStorage.Get(WindowConstants.MAIN_WINDOW);
|
||||
try {
|
||||
topWindow.setSystemBarProperties(
|
||||
{
|
||||
navigationBarColor: barColor,
|
||||
navigationBarContentColor: barContentColor
|
||||
},
|
||||
() => logInfo(TAG, 'setStatusBarColor done')
|
||||
);
|
||||
} catch (err) {
|
||||
logError(TAG, `setNavigationBarColor err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
setSystemUi(isShowBar: boolean): void {
|
||||
logDebug(TAG, 'setSystemUi start');
|
||||
let topWindow: any = AppStorage.Get(WindowConstants.MAIN_WINDOW);
|
||||
logDebug(TAG, 'getTopWindow start');
|
||||
let names = ["navigation"];
|
||||
if (!isShowBar) {
|
||||
names = [];
|
||||
}
|
||||
logDebug(TAG, `getTopWindow names: ${names} end`);
|
||||
try {
|
||||
topWindow.setSystemBarEnable(names, () => {
|
||||
logDebug(TAG, 'setFullScreen Succeeded');
|
||||
if (isShowBar) {
|
||||
topWindow.getAvoidArea(0, (err, data) => {
|
||||
logInfo(TAG, 'Succeeded in obtaining the area. Data:' + JSON.stringify(data));
|
||||
this.onLeftBlankChanged(data);
|
||||
});
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
logError(TAG, `setSystemUi err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
private onLeftBlankChanged(area) {
|
||||
if (area == null || area == undefined || area.bottomRect.height == 0) {
|
||||
return;
|
||||
}
|
||||
let leftBlankBefore = {
|
||||
status: this.statusBarHeight,
|
||||
navi: this.naviBarHeight
|
||||
};
|
||||
this.statusBarHeight = 0;
|
||||
this.naviBarHeight = area.bottomRect.height;
|
||||
this.leftBlank = [this.leftBlank[0], this.leftBlank[1], this.leftBlank[2], area.bottomRect.height];
|
||||
if (leftBlankBefore.status != this.statusBarHeight || leftBlankBefore.navi != this.naviBarHeight) {
|
||||
logInfo(TAG, `leftBlank changed: ${JSON.stringify(leftBlankBefore)}-${JSON.stringify(this.leftBlank)}`)
|
||||
AppStorage.SetOrCreate(BroadcastConstants.LEFT_BLANK, this.leftBlank);
|
||||
}
|
||||
}
|
||||
|
||||
private onWinSizeChanged(size) {
|
||||
logInfo(TAG, `onWinSizeChanged ${JSON.stringify(size)}`);
|
||||
if (size == null || size == undefined) {
|
||||
return;
|
||||
}
|
||||
let sizeBefore = {
|
||||
width: this.winWidth,
|
||||
height: this.winHeight
|
||||
};
|
||||
this.winWidth = size.width;
|
||||
this.winHeight = size.height;
|
||||
|
||||
|
||||
if (sizeBefore.width != this.winWidth || sizeBefore.height != this.winHeight) {
|
||||
logInfo(TAG, `winSize changed: ${JSON.stringify(sizeBefore)} -> ${JSON.stringify(size)}`);
|
||||
this.emit(screenManager.ON_WIN_SIZE_CHANGED, [size]);
|
||||
}
|
||||
}
|
||||
|
||||
private onRotationAngleChanged(angle) {
|
||||
if (angle == null || angle == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (angle == 0) {
|
||||
this.horizontal = false;
|
||||
} else {
|
||||
this.horizontal = true;
|
||||
}
|
||||
AppStorage.SetOrCreate(SCREEN_ORIENTATION_HORIZONTAL, this.horizontal);
|
||||
}
|
||||
|
||||
isHorizontal(): boolean {
|
||||
if (AppStorage.Get(SCREEN_ORIENTATION_HORIZONTAL) == null) {
|
||||
AppStorage.SetOrCreate(SCREEN_ORIENTATION_HORIZONTAL, this.horizontal);
|
||||
}
|
||||
return AppStorage.Get(SCREEN_ORIENTATION_HORIZONTAL);
|
||||
}
|
||||
|
||||
isSidebar(): boolean {
|
||||
if (AppStorage.Get(SCREEN_SIDEBAR) == null) {
|
||||
AppStorage.SetOrCreate(SCREEN_SIDEBAR, this.sidebar);
|
||||
}
|
||||
return AppStorage.Get(SCREEN_SIDEBAR);
|
||||
}
|
||||
|
||||
getColumnsWidth(count: number): number {
|
||||
let columns = this.getScreenColumns()
|
||||
logInfo(TAG, `getColumnsWidth count is ${count} colunms is ${columns}`);
|
||||
let columnWidth = (px2vp(this.winWidth) - COLUMN_MARGIN) / columns;
|
||||
return columnWidth * count - COLUMN_GUTTER;
|
||||
}
|
||||
|
||||
getScreenColumns(): number {
|
||||
let width = px2vp(this.winWidth)
|
||||
if (width < ScreenWidth.WIDTH_MEDIUM) {
|
||||
return ColumnSize.COLUMN_FOUR;
|
||||
} else if (width >= ScreenWidth.WIDTH_MEDIUM && width < ScreenWidth.WIDTH_LARGE) {
|
||||
return ColumnSize.COLUMN_EIGHT;
|
||||
} else {
|
||||
return ColumnSize.COLUMN_TWELVE;
|
||||
}
|
||||
}
|
||||
|
||||
setKeepScreenOn() {
|
||||
logInfo(TAG, 'setKeepScreenOn start');
|
||||
let topWindow: any = AppStorage.Get('mainWindow');
|
||||
try {
|
||||
topWindow.setKeepScreenOn(true, () => logInfo(TAG, 'setKeepScreenOn Succeeded'))
|
||||
} catch (err) {
|
||||
logError(TAG, `setKeepScreenOn err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
setKeepScreenOff() {
|
||||
logInfo(TAG, 'setKeepScreenOff start');
|
||||
let topWindow: any = AppStorage.Get('mainWindow');
|
||||
try {
|
||||
topWindow.setKeepScreenOn(false, () => logInfo(TAG, 'setKeepScreenOff Succeeded'))
|
||||
} catch (err) {
|
||||
logError(TAG, `setKeepScreenOff err: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let screenManager = createOrGet(ScreenManager, TAG);
|
||||
|
||||
export default screenManager as ScreenManager;
|
41
common/base/src/main/ets/manager/SelectManager.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 createOrGet from '../utils/SingleInstanceUtils';
|
||||
|
||||
const TAG = ""
|
||||
|
||||
class SelectManager {
|
||||
private status: Map<string, boolean> = new Map()
|
||||
|
||||
isSelect(key: string, defaultValue: boolean): boolean{
|
||||
if (this.status.has(key)) {
|
||||
return this.status.get(key)
|
||||
} else {
|
||||
return defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
setSelect(key: string, value: boolean) {
|
||||
this.status.set(key, value)
|
||||
}
|
||||
|
||||
deleteSelect(key: string) {
|
||||
this.status.delete(key)
|
||||
}
|
||||
}
|
||||
|
||||
let selectManager = createOrGet(SelectManager, TAG);
|
||||
|
||||
export default selectManager as SelectManager;
|
107
common/base/src/main/ets/model/AlbumDataImpl.ts
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug, logWarn, logError } from '../utils/LoggerUtils';
|
||||
import { AlbumDataItem } from '../data/AlbumDataItem'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { getAlbumDisplayName, getFetchOptions } from '../helper/MediaDataHelper'
|
||||
|
||||
const TAG = "AlbumDataImpl"
|
||||
|
||||
export class AlbumDataImpl {
|
||||
private blackList: string[] = []
|
||||
private selectType: number = MediaConstants.SELECT_TYPE_ALL
|
||||
private deviceId: string = ''
|
||||
|
||||
setBlackList(blackList: string[]) {
|
||||
this.blackList = blackList
|
||||
}
|
||||
|
||||
setSelectType(selectType: number) {
|
||||
this.selectType = selectType
|
||||
}
|
||||
|
||||
setDeviceId(deviceId: string) {
|
||||
this.deviceId = deviceId
|
||||
}
|
||||
|
||||
async reloadAlbumItemData(): Promise<AlbumDataItem[]> {
|
||||
let albumDataItems = []
|
||||
for (let i = 0;i < MediaConstants.ALBUM_DEFAULT_SORT_LIST.length; i++) {
|
||||
await this.getAlbumItem(MediaConstants.ALBUM_DEFAULT_SORT_LIST[i], albumDataItems)
|
||||
}
|
||||
await this.getCommonAlbumItem(albumDataItems)
|
||||
await this.getAlbumItem(MediaConstants.ALBUM_ID_RECYCLE, albumDataItems)
|
||||
return albumDataItems
|
||||
}
|
||||
|
||||
private async getCommonAlbumItem(albumDataItems: AlbumDataItem[]): Promise<void> {
|
||||
let fetchOption: MediaLib.MediaFetchOptions = await getFetchOptions(this.selectType, "", this.deviceId)
|
||||
if (fetchOption == undefined) {
|
||||
return
|
||||
}
|
||||
fetchOption.selections = `(${fetchOption.selections}) and (${MediaLib.FileKey.ALBUM_NAME} <> ? and ${MediaLib.FileKey.ALBUM_NAME} <> ?)`
|
||||
fetchOption.selectionArgs.push('Camera', 'Screenshots')
|
||||
let albums: MediaLib.Album[] = await mediaModel.getAlbums(fetchOption)
|
||||
for (let i = 0;i < albums.length; i++) {
|
||||
let album: MediaLib.Album = albums[i]
|
||||
if (this.blackList.indexOf(album.albumId.toString()) >= 0) {
|
||||
continue
|
||||
}
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await album.getFileAssets()
|
||||
try {
|
||||
let count = fetchFileResult.getCount()
|
||||
if (count == 0) {
|
||||
continue
|
||||
}
|
||||
let item = new AlbumDataItem(album.albumId.toString(), count, album.albumName, this.selectType, this.deviceId)
|
||||
item.update(await fetchFileResult.getFirstObject())
|
||||
albumDataItems.push(item)
|
||||
} catch (err) {
|
||||
logError(TAG, `on err: ${JSON.stringify(err)}`)
|
||||
} finally {
|
||||
fetchFileResult.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async getAlbumItem(id: string, albumDataItems: AlbumDataItem[]): Promise<void> {
|
||||
if (this.blackList.indexOf(id) >= 0) {
|
||||
logDebug(TAG, `no need as in black list`)
|
||||
return
|
||||
}
|
||||
if (this.deviceId.length > 0 && (id != MediaConstants.ALBUM_ID_SNAPSHOT && id != MediaConstants.ALBUM_ID_CAMERA)) {
|
||||
logDebug(TAG, `no need`)
|
||||
return
|
||||
}
|
||||
let fetchOption: MediaLib.MediaFetchOptions = await getFetchOptions(this.selectType, id, this.deviceId)
|
||||
if (fetchOption == undefined) {
|
||||
logWarn(TAG, `${id} fetchOption is undefined`)
|
||||
return
|
||||
}
|
||||
let item = await mediaModel.getAllMediaItem(id, fetchOption, false)
|
||||
if (item.counts == 0) {
|
||||
logWarn(TAG, `${id} is empty`)
|
||||
return
|
||||
}
|
||||
|
||||
let displayName = await getAlbumDisplayName(id)
|
||||
let albumItem: AlbumDataItem = new AlbumDataItem(id, item.counts, displayName, this.selectType, this.deviceId)
|
||||
albumItem.update(item.fileAsset)
|
||||
albumDataItems.push(albumItem)
|
||||
return
|
||||
}
|
||||
}
|
47
common/base/src/main/ets/model/DistributedDataImpl.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logInfo } from '../utils/LoggerUtils';
|
||||
import { MediaConstants } from '../constants/MediaConstants';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { PeerDataItem } from '../data/PeerDataItem'
|
||||
|
||||
const TAG = "DistributedDataImpl"
|
||||
|
||||
export class DistributedDataImpl {
|
||||
async reloadAlbumItemData(): Promise<PeerDataItem[]> {
|
||||
let peerDataItems = []
|
||||
let peers: MediaLib.PeerInfo[] = await mediaModel.getActivePeers()
|
||||
logInfo(TAG, `peers: ${JSON.stringify(peers)}`)
|
||||
for (let i = 0;i < peers.length; i++) {
|
||||
let selections: string = `${MediaLib.FileKey.MEDIA_TYPE} = ? or ${MediaLib.FileKey.MEDIA_TYPE} = ?`
|
||||
let selectionArgs: string[] = [MediaLib.MediaType.IMAGE.toString(), MediaLib.MediaType.VIDEO.toString()]
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: selections,
|
||||
selectionArgs: selectionArgs,
|
||||
networkId: peers[i].networkId,
|
||||
order: `date_added DESC`
|
||||
}
|
||||
let item = await mediaModel.getAllCommonMediaItem(fetchOption, false)
|
||||
if (item.counts == 0) {
|
||||
continue
|
||||
}
|
||||
peerDataItems.push(new PeerDataItem(item.counts, peers[i], item.fileAsset))
|
||||
}
|
||||
|
||||
return peerDataItems
|
||||
}
|
||||
}
|
167
common/base/src/main/ets/model/GroupDataImpl.ts
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug, logInfo } from '../utils/LoggerUtils';
|
||||
import { WindowConstants } from '../constants/WindowConstants';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import screenManager from '../manager/ScreenManager'
|
||||
import { MediaConstants } from '../constants/MediaConstants';
|
||||
import { getFetchOptions } from '../helper/MediaDataHelper';
|
||||
import { MediaDataItem } from '../data/MediaDataItem';
|
||||
import { FavorMediaDataItem } from '../data/FavorMediaDataItem'
|
||||
import { TrashMediaDataItem } from '../data/TrashMediaDataItem'
|
||||
|
||||
const TAG = "GroupDataImpl"
|
||||
|
||||
export class GroupDataImpl {
|
||||
private selectType: number = MediaConstants.SELECT_TYPE_ALL
|
||||
private albumId: string = ""
|
||||
private deviceId: string = ""
|
||||
|
||||
setSelectType(selectType: number) {
|
||||
this.selectType = selectType
|
||||
}
|
||||
|
||||
setAlbumId(id: string) {
|
||||
logInfo(TAG, `setAlbumId: ${id}`)
|
||||
this.albumId = id
|
||||
}
|
||||
|
||||
setDeviceId(id: string) {
|
||||
logInfo(TAG, `setDeviceId: ${id}`)
|
||||
this.deviceId = id
|
||||
}
|
||||
|
||||
async reloadGroupItemData(isGrid: boolean): Promise<MediaDataItem[]> {
|
||||
if (isGrid) {
|
||||
return this.reloadGridGroupItemData()
|
||||
} else {
|
||||
return this.reloadBrowserGroupItemData()
|
||||
}
|
||||
}
|
||||
|
||||
async reloadBrowserGroupItemData(): Promise<MediaDataItem[]> {
|
||||
logDebug(TAG, `reloadGroupItemData`)
|
||||
let groupDataItem = []
|
||||
let fetchOption = await getFetchOptions(this.selectType, this.albumId, this.deviceId)
|
||||
if (fetchOption == undefined) {
|
||||
return []
|
||||
}
|
||||
let count: number = 0
|
||||
if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) {
|
||||
count = (await mediaModel.getAllFavorMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
groupDataItem.push(new FavorMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i))
|
||||
}
|
||||
} else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) {
|
||||
count = (await mediaModel.getAllTrashMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
groupDataItem.push(new TrashMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i))
|
||||
}
|
||||
} else {
|
||||
count = (await mediaModel.getAllCommonMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
groupDataItem.push(new MediaDataItem(fetchOption.selections, fetchOption.selectionArgs, this.deviceId, i))
|
||||
}
|
||||
}
|
||||
|
||||
logDebug(TAG, `reload finish count:${count}`)
|
||||
return groupDataItem
|
||||
}
|
||||
|
||||
async reloadGridGroupItemData(): Promise<MediaDataItem[]> {
|
||||
logDebug(TAG, `reloadGroupItemData`)
|
||||
let groupDataItem = []
|
||||
let fetchOption = await getFetchOptions(this.selectType, this.albumId, this.deviceId)
|
||||
if (fetchOption == undefined) {
|
||||
return []
|
||||
}
|
||||
let groupCount: number = this.getCount()
|
||||
let mediaFileAssets = await this.getMediaItemFileAssets(0, groupCount)
|
||||
if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) {
|
||||
let count: number = (await mediaModel.getAllFavorMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
let item = new FavorMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i)
|
||||
if (i < mediaFileAssets.length) {
|
||||
item.update(mediaFileAssets[i])
|
||||
}
|
||||
groupDataItem.push(item)
|
||||
}
|
||||
} else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) {
|
||||
let count: number = (await mediaModel.getAllTrashMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
let item = new TrashMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i)
|
||||
if (i < mediaFileAssets.length) {
|
||||
item.update(mediaFileAssets[i])
|
||||
}
|
||||
groupDataItem.push(item)
|
||||
}
|
||||
} else {
|
||||
let count: number = (await mediaModel.getAllCommonMediaItem(fetchOption, true)).counts
|
||||
for (let i = 0;i < count; i++) {
|
||||
let item = new MediaDataItem(fetchOption.selections, fetchOption.selectionArgs, this.deviceId, i)
|
||||
if (i < mediaFileAssets.length) {
|
||||
item.update(mediaFileAssets[i])
|
||||
}
|
||||
groupDataItem.push(item)
|
||||
}
|
||||
}
|
||||
// do not use await to avoid load cost too much time
|
||||
this.loadReset(groupDataItem, groupCount)
|
||||
|
||||
logDebug(TAG, `reload finish`)
|
||||
return groupDataItem
|
||||
}
|
||||
|
||||
private async getMediaItemFileAssets(start: number, count: number): Promise<MediaLib.FileAsset[]> {
|
||||
let selections: string = MediaLib.FileKey.MEDIA_TYPE + ' = ? or ' + MediaLib.FileKey.MEDIA_TYPE + ' = ?'
|
||||
let selectionArgs: Array<string> = [MediaLib.MediaType.IMAGE.toString(), MediaLib.MediaType.VIDEO.toString()]
|
||||
let fetchOption: MediaLib.MediaFetchOptions = {
|
||||
selections: selections,
|
||||
selectionArgs: selectionArgs,
|
||||
order: `date_added DESC LIMIT ${start},${count}`
|
||||
};
|
||||
if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) {
|
||||
return await mediaModel.getAllFavorMediaItems(fetchOption)
|
||||
} else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) {
|
||||
return await mediaModel.getAllTrashMediaItems(fetchOption)
|
||||
} else {
|
||||
return await mediaModel.getAllMediaItems(fetchOption)
|
||||
}
|
||||
}
|
||||
|
||||
private getCount(): number {
|
||||
let contentWidth = screenManager.getWinWidth();
|
||||
let maxThumbWidth = px2vp(WindowConstants.GRID_IMAGE_SIZE) * WindowConstants.GRID_MAX_SIZE_RATIO;
|
||||
let columns = Math.max(WindowConstants.GRID_MIN_COUNT, Math.ceil((contentWidth + WindowConstants.GRID_GUTTER) / (maxThumbWidth + WindowConstants.GRID_GUTTER)));
|
||||
let contentHeight = screenManager.getWinHeight() - WindowConstants.ACTION_BAR_HEIGHT - screenManager.getNaviBarHeight()
|
||||
let rows = Math.ceil((contentHeight + WindowConstants.GRID_GUTTER) / (maxThumbWidth + WindowConstants.GRID_GUTTER)) + 4
|
||||
return columns * rows
|
||||
}
|
||||
|
||||
private async loadReset(items: MediaDataItem[], count) {
|
||||
let itemLen = items.length
|
||||
let countLen = Math.ceil(itemLen / count)
|
||||
for (let i = 1;i < countLen; i++) {
|
||||
let mediaFileAsset: Array<MediaLib.FileAsset> = await this.getMediaItemFileAssets(i * count, count)
|
||||
for (let j = 0;j < count; j++) {
|
||||
if (i * count + j >= itemLen) {
|
||||
return
|
||||
}
|
||||
items[i * count+j].update(mediaFileAsset[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
360
common/base/src/main/ets/model/MediaModel.ts
Normal file
@ -0,0 +1,360 @@
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* Copyright (c) 2022 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 fileIO from '@ohos.fileio';
|
||||
import MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import createOrGet from '../utils/SingleInstanceUtils';
|
||||
import { logDebug, logInfo, logWarn, logError } from '../utils/LoggerUtils'
|
||||
import { startTrace, finishTrace } from '../utils/TraceControllerUtils'
|
||||
|
||||
const TAG = "MediaModel"
|
||||
|
||||
export class MediaModelItem {
|
||||
fileAsset: MediaLib.FileAsset
|
||||
counts: number
|
||||
}
|
||||
|
||||
class MediaModel {
|
||||
private media: MediaLib.MediaLibrary = undefined
|
||||
private imageDir: string = ""
|
||||
private cameraDir: string = ""
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
onCreate(context) {
|
||||
if (this.media == undefined) {
|
||||
this.media = MediaLib.getMediaLibrary(context)
|
||||
}
|
||||
}
|
||||
|
||||
getMediaLibrary(): MediaLib.MediaLibrary{
|
||||
return this.media
|
||||
}
|
||||
|
||||
async getPublicDirectory(directoryType: MediaLib.DirectoryType): Promise<string> {
|
||||
if (directoryType == MediaLib.DirectoryType.DIR_IMAGE) {
|
||||
if (this.imageDir == "" || this.imageDir == undefined) {
|
||||
this.imageDir = await this.media.getPublicDirectory(directoryType)
|
||||
logDebug(TAG, `imageDir ${this.imageDir}`)
|
||||
}
|
||||
logDebug(TAG, `return imageDir ${this.imageDir}`)
|
||||
return this.imageDir
|
||||
} else if (directoryType == MediaLib.DirectoryType.DIR_CAMERA) {
|
||||
if (this.cameraDir == "" || this.cameraDir == undefined) {
|
||||
this.cameraDir = await this.media.getPublicDirectory(directoryType)
|
||||
logDebug(TAG, `cameraDir ${this.cameraDir}`)
|
||||
}
|
||||
logDebug(TAG, `return cameraDir ${this.cameraDir}`)
|
||||
return this.cameraDir
|
||||
} else {
|
||||
logWarn(TAG, `invaild directoryType: ${directoryType}`)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
async createOne(mediaType: MediaLib.MediaType, displayName: string, relativePath: string): Promise<MediaLib.FileAsset> {
|
||||
return await this.media.createAsset(mediaType, displayName, relativePath)
|
||||
}
|
||||
|
||||
async copyOne(source: MediaLib.FileAsset, target: MediaLib.FileAsset) {
|
||||
logInfo(TAG, `copy start: src:${source.uri} target: ${target.uri}`);
|
||||
startTrace('openAssetR')
|
||||
let fd = await this.openAsset('R', source);
|
||||
finishTrace('openAssetR')
|
||||
if (fd <= 0) {
|
||||
throw 'fd is invalid'
|
||||
return;
|
||||
}
|
||||
|
||||
startTrace('openAssetRW')
|
||||
let targetFd = await this.openAsset('RW', target);
|
||||
finishTrace('openAssetRW')
|
||||
if (targetFd <= 0) {
|
||||
throw 'targetFd is invalid'
|
||||
return;
|
||||
}
|
||||
|
||||
startTrace('copyFile')
|
||||
await fileIO.copyFile(fd, targetFd)
|
||||
finishTrace('copyFile')
|
||||
|
||||
startTrace('sourceClose')
|
||||
await this.closeAsset(fd, source)
|
||||
finishTrace('sourceClose')
|
||||
startTrace('targetClose')
|
||||
await this.closeAsset(targetFd, target)
|
||||
finishTrace('targetClose')
|
||||
|
||||
logDebug(TAG, 'copy end')
|
||||
}
|
||||
|
||||
async deleteOne(uri: string) {
|
||||
logDebug(TAG, `deleteAsset uri: ${uri}`);
|
||||
await this.media.deleteAsset(uri);
|
||||
}
|
||||
|
||||
async deleteAll(fetchOption: MediaLib.MediaFetchOptions) {
|
||||
logInfo(TAG, 'deleteAll');
|
||||
startTrace('deleteAll')
|
||||
try {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await this.media.getFileAssets(fetchOption);
|
||||
logDebug(TAG, `deleteAll getFileAssets`);
|
||||
let fileAssets: MediaLib.FileAsset[] = await fetchFileResult.getAllObject();
|
||||
for (let i = 0;i < fileAssets.length; i++) {
|
||||
await fileAssets[i].trash(true)
|
||||
}
|
||||
logDebug(TAG, `deleteAll getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `deleteAll error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('deleteAll')
|
||||
logDebug(TAG, 'deleteAll finish');
|
||||
}
|
||||
|
||||
async getAllMediaItems(fetchOption: MediaLib.MediaFetchOptions): Promise<Array<MediaLib.FileAsset>> {
|
||||
logInfo(TAG, 'getAllMediaItems');
|
||||
startTrace('getAllMediaItems')
|
||||
let fileAssets: Array<MediaLib.FileAsset> = []
|
||||
try {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await this.media.getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllMediaItems getFileAssets:${fetchFileResult.getCount()}`);
|
||||
fileAssets = await fetchFileResult.getAllObject();
|
||||
logDebug(TAG, `getAllMediaItems getAllObject:${fileAssets.length}`);
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllMediaItems error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllMediaItems')
|
||||
logDebug(TAG, 'getAllMediaItems finish');
|
||||
return fileAssets
|
||||
}
|
||||
|
||||
async getAllFavorMediaItems(fetchOption: MediaLib.MediaFetchOptions): Promise<Array<MediaLib.FileAsset>> {
|
||||
logInfo(TAG, 'getAllFavorMediaItems');
|
||||
startTrace('getAllFavorMediaItems')
|
||||
let fileAssets: Array<MediaLib.FileAsset> = []
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_FAVORITE);
|
||||
if (albums.length > 0) {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllFavorMediaItems getFileAssets`);
|
||||
fileAssets = await fetchFileResult.getAllObject();
|
||||
logDebug(TAG, `getAllFavorMediaItems getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
}
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllFavorMediaItems error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllFavorMediaItems')
|
||||
logDebug(TAG, 'getAllFavorMediaItems finish');
|
||||
return fileAssets
|
||||
}
|
||||
|
||||
async getAllTrashMediaItems(fetchOption: MediaLib.MediaFetchOptions): Promise<Array<MediaLib.FileAsset>> {
|
||||
logInfo(TAG, 'getAllTrashMediaItems');
|
||||
startTrace('getAllTrashMediaItems')
|
||||
let fileAssets: Array<MediaLib.FileAsset> = []
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
if (albums.length > 0) {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllTrashMediaItems getFileAssets`);
|
||||
fileAssets = await fetchFileResult.getAllObject();
|
||||
logDebug(TAG, `getAllTrashMediaItems getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
}
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllTrashMediaItems error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllTrashMediaItems')
|
||||
logDebug(TAG, 'getAllTrashMediaItems finish');
|
||||
return fileAssets
|
||||
}
|
||||
|
||||
async getAllMediaItem(albumId: string, fetchOption: MediaLib.MediaFetchOptions, isCountOnly: boolean): Promise<MediaModelItem> {
|
||||
if (albumId == MediaConstants.ALBUM_ID_FAVOR) {
|
||||
return await this.getAllFavorMediaItem(fetchOption, isCountOnly)
|
||||
} else if (albumId == MediaConstants.ALBUM_ID_RECYCLE) {
|
||||
return await this.getAllTrashMediaItem(fetchOption, isCountOnly)
|
||||
} else {
|
||||
return await this.getAllCommonMediaItem(fetchOption, isCountOnly)
|
||||
}
|
||||
}
|
||||
|
||||
async getAllCommonMediaItem(fetchOption: MediaLib.MediaFetchOptions, isCountOnly: boolean): Promise<MediaModelItem> {
|
||||
logInfo(TAG, 'getAllCommonMediaItem');
|
||||
startTrace('getAllCommonMediaItem')
|
||||
let item: MediaModelItem = new MediaModelItem()
|
||||
try {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await this.media.getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllCommonMediaItem getFileAssets`);
|
||||
item.counts = await fetchFileResult.getCount();
|
||||
if (!isCountOnly && item.counts > 0) {
|
||||
item.fileAsset = await fetchFileResult.getFirstObject()
|
||||
}
|
||||
logDebug(TAG, `getAllCommonMediaItem getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllCommonMediaItem error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllCommonMediaItem')
|
||||
logDebug(TAG, 'getAllCommonMediaItem finish');
|
||||
return item
|
||||
}
|
||||
|
||||
async getAllFavorMediaItem(fetchOption: MediaLib.MediaFetchOptions, isCountOnly: boolean): Promise<MediaModelItem> {
|
||||
logInfo(TAG, 'getAllFavorMediaItem');
|
||||
startTrace('getAllFavorMediaItem')
|
||||
let item: MediaModelItem = new MediaModelItem()
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_FAVORITE);
|
||||
if (albums.length > 0) {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllFavorMediaItem getFileAssets`);
|
||||
item.counts = await fetchFileResult.getCount();
|
||||
if (!isCountOnly && item.counts > 0) {
|
||||
item.fileAsset = await fetchFileResult.getFirstObject()
|
||||
}
|
||||
logDebug(TAG, `getAllFavorMediaItem getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
}
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllFavorMediaItem error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllFavorMediaItem')
|
||||
logDebug(TAG, 'getAllFavorMediaItem finish');
|
||||
return item
|
||||
}
|
||||
|
||||
async getAllTrashMediaItem(fetchOption: MediaLib.MediaFetchOptions, isCountOnly: boolean): Promise<MediaModelItem> {
|
||||
logInfo(TAG, 'getAllTrashMediaItem');
|
||||
startTrace('getAllTrashMediaItem')
|
||||
let item: MediaModelItem = new MediaModelItem()
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
if (albums.length > 0) {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getAllTrashMediaItem getFileAssets`);
|
||||
item.counts = await fetchFileResult.getCount();
|
||||
if (!isCountOnly && item.counts > 0) {
|
||||
item.fileAsset = await fetchFileResult.getFirstObject()
|
||||
}
|
||||
logDebug(TAG, `getAllTrashMediaItem getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
}
|
||||
} catch (err) {
|
||||
logError(TAG, `getAllTrashMediaItem error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAllTrashMediaItem')
|
||||
logDebug(TAG, 'getAllTrashMediaItem finish');
|
||||
return item
|
||||
}
|
||||
|
||||
async getAlbumCount(fetchOption: MediaLib.MediaFetchOptions): Promise<number> {
|
||||
logInfo(TAG, 'getAlbumCount');
|
||||
startTrace('getAlbumCount')
|
||||
let count = 0
|
||||
try {
|
||||
let albums: Array<MediaLib.Album> = await this.media.getAlbums(fetchOption);
|
||||
if (albums.length == 0) {
|
||||
return count
|
||||
}
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets()
|
||||
count = fetchFileResult.getCount()
|
||||
fetchFileResult.close()
|
||||
} catch (err) {
|
||||
logError(TAG, `getAlbumCount error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAlbumCount')
|
||||
logDebug(TAG, 'getAlbumCount finish');
|
||||
return count
|
||||
}
|
||||
|
||||
async getActivePeers(): Promise<Array<MediaLib.PeerInfo>> {
|
||||
logInfo(TAG, 'getActivePeers');
|
||||
startTrace('getActivePeers')
|
||||
let peers: Array<MediaLib.PeerInfo> = undefined
|
||||
try {
|
||||
peers = await this.media.getActivePeers();
|
||||
} catch (err) {
|
||||
logError(TAG, `getActivePeers error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getActivePeers')
|
||||
logDebug(TAG, 'getActivePeers finish');
|
||||
return peers
|
||||
}
|
||||
|
||||
async getAlbums(fetchOption: MediaLib.MediaFetchOptions): Promise<Array<MediaLib.Album>> {
|
||||
logInfo(TAG, 'getAlbums');
|
||||
startTrace('getAlbums')
|
||||
let albums: Array<MediaLib.Album> = undefined
|
||||
try {
|
||||
albums = await this.media.getAlbums(fetchOption);
|
||||
logInfo(TAG, `getAlbums albums ${albums.length}`)
|
||||
} catch (err) {
|
||||
logError(TAG, `getAlbums error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getAlbums')
|
||||
logDebug(TAG, 'getAlbums finish');
|
||||
return albums
|
||||
}
|
||||
|
||||
async getTrashMedia(fetchOption: MediaLib.MediaFetchOptions): Promise<MediaLib.FileAsset> {
|
||||
logInfo(TAG, 'getTrashMedia');
|
||||
startTrace('getTrashMedia')
|
||||
let fileAsset: MediaLib.FileAsset = undefined
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
if (albums.length > 0) {
|
||||
let fetchFileResult: MediaLib.FetchFileResult = await albums[0].getFileAssets(fetchOption);
|
||||
logDebug(TAG, `getTrashMedia getFileAssets`);
|
||||
if (fetchFileResult.getCount() > 0) {
|
||||
fileAsset = await fetchFileResult.getFirstObject();
|
||||
}
|
||||
logDebug(TAG, `getTrashMedia getFirstObject`);
|
||||
fetchFileResult.close()
|
||||
}
|
||||
} catch (err) {
|
||||
logError(TAG, `getTrashMedia error:${JSON.stringify(err)}`);
|
||||
}
|
||||
finishTrace('getTrashMedia')
|
||||
logDebug(TAG, 'getTrashMedia finish');
|
||||
return fileAsset
|
||||
}
|
||||
|
||||
async openAsset(mode: string, fileAsset: MediaLib.FileAsset) {
|
||||
logDebug(TAG, 'openAsset start');
|
||||
let fd: number = await fileAsset.open(mode);
|
||||
logInfo(TAG, `openAsset end. fd: ${fd}`);
|
||||
if (fd <= 0) {
|
||||
logInfo(TAG, 'openAsset Fail');
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
async closeAsset(fd: number, fileAsset: MediaLib.FileAsset) {
|
||||
logDebug(TAG, 'closeAsset start');
|
||||
await fileAsset.close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
let mediaModel = createOrGet(MediaModel, TAG);
|
||||
|
||||
export default mediaModel as MediaModel;
|
@ -13,10 +13,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { MediaObserverCallback } from './dataObserver/MediaObserverCallback'
|
||||
import { MediaObserverCallback } from '../interface/MediaObserverCallback'
|
||||
|
||||
export class CommonObserverCallback implements MediaObserverCallback {
|
||||
source: any;
|
||||
private source: any;
|
||||
|
||||
constructor(source: any) {
|
||||
this.source = source;
|
89
common/base/src/main/ets/observer/MediaObserver.ts
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 createOrGet from '../utils/SingleInstanceUtils';
|
||||
import { logInfo, logWarn } from '../utils/LoggerUtils'
|
||||
import { MediaConstants } from '../constants/MediaConstants'
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaObserverCallback } from '../interface/MediaObserverCallback';
|
||||
|
||||
const TAG = "MediaObserver"
|
||||
|
||||
class MediaObserver {
|
||||
callbacks: MediaObserverCallback[] = [];
|
||||
private static readonly OBSERVER_IMAGE_CHANGE: string = 'imageChange'
|
||||
private static readonly OBSERVER_VIDEO_CHANGE: string = 'videoChange'
|
||||
private static readonly OBSERVER_DEVICE_CHANGE: string = 'deviceChange'
|
||||
private static readonly OBSERVER_ALBUM_CHANGE: string = 'albumChange'
|
||||
private static readonly OBSERVER_REMOTE_FILE_CHANGE: string = 'remoteFileChange'
|
||||
|
||||
registerObserver(callback: MediaObserverCallback) {
|
||||
logInfo(TAG, 'registerObserver');
|
||||
if (callback == null) {
|
||||
logWarn(TAG, 'registerObserver with empty callback');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.callbacks.indexOf(callback) < 0) {
|
||||
this.callbacks.push(callback);
|
||||
} else {
|
||||
logInfo(TAG, 'registerObserver already exist');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.callbacks.length == 1) {
|
||||
logInfo(TAG, 'registerObserver register media');
|
||||
mediaModel.getMediaLibrary().on('imageChange', () => {
|
||||
logInfo(TAG, 'registerObserver on image');
|
||||
this.sendNotify(MediaConstants.MEDIA_TYPE_IMAGE);
|
||||
})
|
||||
mediaModel.getMediaLibrary().on('videoChange', () => {
|
||||
logInfo(TAG, 'registerObserver on video');
|
||||
this.sendNotify(MediaConstants.MEDIA_TYPE_VIDEO);
|
||||
})
|
||||
mediaModel.getMediaLibrary().on('deviceChange', () => {
|
||||
logInfo(TAG, 'registerObserver on device');
|
||||
this.sendNotify(MediaConstants.MEDIA_TYPE_DEVICE);
|
||||
})
|
||||
mediaModel.getMediaLibrary().on('albumChange', () => {
|
||||
logInfo(TAG, 'registerObserver on album');
|
||||
this.sendNotify(MediaConstants.MEDIA_TYPE_ALBUM);
|
||||
})
|
||||
mediaModel.getMediaLibrary().on('remoteFileChange', () => {
|
||||
logInfo(TAG, 'registerObserver on remoteFile');
|
||||
this.sendNotify(MediaConstants.MEDIA_TYPE_REMOTE);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sendNotify(mediaType: string) {
|
||||
logInfo(TAG, `registerObserver sendNotify size: ${this.callbacks.length}`);
|
||||
for (let callback of this.callbacks) {
|
||||
callback.onChange(mediaType);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterObserver(callback: MediaObserverCallback) {
|
||||
logInfo(TAG, 'unregisterObserver');
|
||||
const pos = this.callbacks.indexOf(callback);
|
||||
if (pos >= 0) {
|
||||
this.callbacks.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mediaObserver = createOrGet(MediaObserver, TAG);
|
||||
|
||||
export default mediaObserver as MediaObserver;
|
155
common/base/src/main/ets/operation/AlbumSetNewMenuOperation.ts
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 router from '@system.router';
|
||||
import MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { logDebug, logInfo, logWarn, logError } from '../utils/LoggerUtils';
|
||||
import { getResourceString } from '../utils/ResourceUtils';
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import { MenuOperationCallback } from './MenuOperationCallback'
|
||||
import { MenuOperation } from './MenuOperation'
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { JumpSourceToMain } from '../data/JumpSourceToMain'
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
import { getFetchOptionsByItem } from '../helper/MediaDataHelper';
|
||||
import { showToast } from '../utils/UiUtil';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { AlbumDataItem } from '../data/AlbumDataItem';
|
||||
|
||||
const TAG = "AlbumSetNewMenuOperation"
|
||||
|
||||
export class AlbumSetNewMenuOperation implements MenuOperation, MenuOperationCallback {
|
||||
private menuContext: MenuContext;
|
||||
private onOperationEnd: Function;
|
||||
|
||||
constructor(menuContext: MenuContext) {
|
||||
this.menuContext = menuContext;
|
||||
}
|
||||
|
||||
doAction() {
|
||||
if (this.menuContext == null) {
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
getResourceString($r('app.string.album_new_album')).then((name: string) => {
|
||||
logInfo(TAG, `The display name is ${name}`);
|
||||
this.getNewAlbumDisplayName(name).then((newAlbumDisplayName: string) => {
|
||||
logInfo(TAG, `The display name of new album is ${newAlbumDisplayName}`);
|
||||
|
||||
this.confirmCallback = this.confirmCallback.bind(this);
|
||||
this.cancelCallback = this.cancelCallback.bind(this);
|
||||
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.SHOW_NEW_ALBUM_PHOTO_DIALOG,
|
||||
[newAlbumDisplayName, this.confirmCallback, this.cancelCallback]);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private async getNewAlbumDisplayName(name: string): Promise<string> {
|
||||
let relativeRoot = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_CAMERA)
|
||||
return await this.getNewAlbumDefaultName(relativeRoot, name)
|
||||
}
|
||||
|
||||
private async confirmCallback(displayName: string) {
|
||||
logInfo(TAG, `AlbumSet new album confirm and the new name is: ${displayName}`);
|
||||
let relativePath = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_CAMERA) + displayName + "/"
|
||||
let simpleAlbumDataItem: SimpleAlbumDataItem = new SimpleAlbumDataItem("", displayName, relativePath, "", "")
|
||||
if (displayName != undefined && displayName != null) {
|
||||
let isExit = await this.checkAlbumExit(simpleAlbumDataItem)
|
||||
if (isExit) {
|
||||
getResourceString($r('app.string.name_already_use')).then((message: string) => {
|
||||
showToast(message)
|
||||
})
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.onOperationEnd = this.menuContext.onOperationEnd;
|
||||
let onOperationStart: Function = this.menuContext.onOperationStart;
|
||||
onOperationStart && onOperationStart();
|
||||
|
||||
if (this.menuContext.jumpSourceToMain == JumpSourceToMain.ALBUM) {
|
||||
logInfo(TAG, 'go back to photo grid');
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.MEDIA_OPERATION, [simpleAlbumDataItem, this.onCompleted.bind(this)]);
|
||||
} else {
|
||||
router.push({
|
||||
uri: 'feature/albumSelect/view/AlbumSelect',
|
||||
params: {
|
||||
albumInfo: JSON.stringify(simpleAlbumDataItem),
|
||||
isNewAlbum: true
|
||||
}
|
||||
});
|
||||
this.onCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
private async checkAlbumExit(simpleAlbumDataItem: SimpleAlbumDataItem): Promise<boolean> {
|
||||
let fetchOptions: MediaLib.MediaFetchOptions = await getFetchOptionsByItem(simpleAlbumDataItem)
|
||||
return await mediaModel.getAlbumCount(fetchOptions) > 0
|
||||
}
|
||||
|
||||
private cancelCallback(): void {
|
||||
logInfo(TAG, 'AlbumSet new album cancel');
|
||||
}
|
||||
|
||||
onCompleted(): void {
|
||||
logInfo(TAG, 'new album data succeed!');
|
||||
this.onOperationEnd && this.onOperationEnd();
|
||||
}
|
||||
|
||||
onError(): void {
|
||||
logError(TAG, 'new album data failed!');
|
||||
this.onOperationEnd && this.onOperationEnd();
|
||||
}
|
||||
|
||||
private async getNewAlbumDefaultName(root: string, prefixName: string): Promise<string> {
|
||||
let numbers = [];
|
||||
for (let i = 0; i < this.menuContext.dataSource.totalCount(); i++) {
|
||||
let item = this.menuContext.dataSource.getData(i) as AlbumDataItem
|
||||
let res = (await item.getRelativePath()).match(new RegExp(`^${root}${prefixName}[1-9][0-9]*${"/"}$`));
|
||||
if (res != null) {
|
||||
let number = res[0].match(new RegExp(`[1-9][0-9]*`));
|
||||
numbers.push(parseInt(number[0]));
|
||||
}
|
||||
}
|
||||
|
||||
logDebug(TAG, `${JSON.stringify(numbers)}`);
|
||||
|
||||
if (numbers.length <= 0) {
|
||||
return `${prefixName}1`;
|
||||
} else if (numbers.length == 1) {
|
||||
if (numbers[0] - 1 > 0) {
|
||||
return `${prefixName}1`;
|
||||
} else {
|
||||
return `${prefixName}${numbers[0] + 1}`;
|
||||
}
|
||||
}
|
||||
|
||||
numbers.sort(function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
|
||||
if (numbers[0] - 1 > 0) {
|
||||
return `${prefixName}1`;
|
||||
}
|
||||
|
||||
for (let i = 1; i < numbers.length; i++) {
|
||||
let res = numbers[i - 1] + 1;
|
||||
if (res < numbers[i]) {
|
||||
return `${prefixName}${res}`;
|
||||
}
|
||||
}
|
||||
return `${prefixName}${numbers[numbers.length - 1] + 1}`;
|
||||
}
|
||||
}
|
101
common/base/src/main/ets/operation/BatchDeleteMenuOperation.ts
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logInfo, logWarn } from '../utils/LoggerUtils'
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import { ProcessMenuOperation } from './ProcessMenuOperation';
|
||||
import { MediaDataItem } from '../data/MediaDataItem';
|
||||
|
||||
const TAG = "BatchDeleteMenuOperation"
|
||||
|
||||
export class BatchDeleteMenuOperation extends ProcessMenuOperation {
|
||||
constructor(menuContext: MenuContext) {
|
||||
super(menuContext);
|
||||
}
|
||||
|
||||
doAction(): void{
|
||||
logInfo(TAG, 'delete doAction');
|
||||
if (this.menuContext == null) {
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
|
||||
let dataSource: ItemDataSource = this.menuContext.dataSource;
|
||||
if (dataSource == null) {
|
||||
this.count = this.menuContext.items.length
|
||||
} else {
|
||||
this.count = dataSource.getSelectedCount();
|
||||
}
|
||||
if (this.count <= 0) {
|
||||
logWarn(TAG, 'count <= 0, return');
|
||||
return;
|
||||
}
|
||||
|
||||
this.confirmCallback = this.confirmCallback.bind(this);
|
||||
this.cancelCallback = this.cancelCallback.bind(this);
|
||||
|
||||
let resource: Resource = this.getDeleteMessageResource(dataSource)
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.SHOW_DELETE_DIALOG, [resource, this.confirmCallback, this.cancelCallback]);
|
||||
}
|
||||
|
||||
getDeleteMessageResource(dataSource: ItemDataSource): Resource{
|
||||
let resource: Resource
|
||||
if (dataSource && dataSource.isSelect()) {
|
||||
resource = $r('app.string.recycle_all_files_tips')
|
||||
} else if (this.count == 1) {
|
||||
resource = $r('app.string.recycle_single_file_tips')
|
||||
} else {
|
||||
resource = $r('app.string.recycle_files_tips', this.count)
|
||||
}
|
||||
return resource
|
||||
}
|
||||
|
||||
confirmCallback(): void {
|
||||
logInfo(TAG, 'Batch delete confirm');
|
||||
// 1. Variable initialization
|
||||
this.onOperationEnd = this.menuContext.onOperationEnd;
|
||||
|
||||
// 2. onDeleteStart exit selection mode
|
||||
let onOperationStart: Function = this.menuContext.onOperationStart;
|
||||
onOperationStart && onOperationStart();
|
||||
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.DELETE_PROGRESS_DIALOG,
|
||||
[$r('app.string.action_delete'), this.count]);
|
||||
|
||||
// 3. selectManager gets the URI of the data and starts processing deletion in the callback
|
||||
let dataSource: ItemDataSource = this.menuContext.dataSource;
|
||||
if (dataSource == null) {
|
||||
this.items = this.menuContext.items
|
||||
} else {
|
||||
this.items = dataSource.getSelectedItems()
|
||||
}
|
||||
this.processOperation()
|
||||
}
|
||||
|
||||
requestOneBatchOperation() {
|
||||
let item = this.items[this.currentBatch] as MediaDataItem
|
||||
item.onDelete().then(() => {
|
||||
this.currentBatch++
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [this.getExpectProgress(), this.currentBatch]);
|
||||
this.cyclicOperation()
|
||||
})
|
||||
}
|
||||
|
||||
cancelCallback(): void {
|
||||
logInfo(TAG, 'Batch delete cancel');
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { TrashMediaDataItem } from '../data/TrashMediaDataItem';
|
||||
import { logInfo, logWarn } from '../utils/LoggerUtils'
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { ProcessMenuOperation } from './ProcessMenuOperation';
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
|
||||
const TAG = "BatchRecoverMenuOperation"
|
||||
|
||||
export class BatchRecoverMenuOperation extends ProcessMenuOperation {
|
||||
constructor(menuContext: MenuContext) {
|
||||
super(menuContext);
|
||||
}
|
||||
|
||||
doAction(): void{
|
||||
logInfo(TAG, 'delete doAction');
|
||||
if (this.menuContext == null) {
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
|
||||
let dataSource: ItemDataSource = this.menuContext.dataSource;
|
||||
if (dataSource == null) {
|
||||
this.count = this.menuContext.items.length
|
||||
} else {
|
||||
this.count = dataSource.getSelectedCount();
|
||||
}
|
||||
if (this.count <= 0) {
|
||||
logWarn(TAG, 'count <= 0, return');
|
||||
return;
|
||||
}
|
||||
|
||||
this.onOperationEnd = this.menuContext.onOperationEnd;
|
||||
let onOperationStart = this.menuContext.onOperationStart;
|
||||
onOperationStart && onOperationStart();
|
||||
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.DELETE_PROGRESS_DIALOG,
|
||||
[$r('app.string.action_recover'), this.count]);
|
||||
|
||||
|
||||
if (dataSource == null) {
|
||||
this.items = this.menuContext.items
|
||||
} else {
|
||||
this.items = dataSource.getSelectedItems()
|
||||
}
|
||||
this.processOperation()
|
||||
}
|
||||
|
||||
// Delete a batch of data
|
||||
requestOneBatchOperation(): void {
|
||||
let item = this.items[this.currentBatch] as TrashMediaDataItem
|
||||
item.onRecover().then(() => {
|
||||
this.currentBatch++
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [this.getExpectProgress(), this.currentBatch]);
|
||||
this.cyclicOperation()
|
||||
})
|
||||
}
|
||||
}
|
@ -12,19 +12,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { OperationImpl } from '../model/browser/photo/OperationImpl'
|
||||
import { AlbumOperationImpl } from '../model/browser/album/AlbumOperationImpl'
|
||||
import { BrowserOperationInterface } from './BrowserOperationInterface'
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { BatchDeleteMenuOperation } from './BatchDeleteMenuOperation';
|
||||
|
||||
export class BrowserOperationFactory {
|
||||
static readonly TYPE_PHOTO = 'photo';
|
||||
static readonly TYPE_ALBUM = 'album';
|
||||
export class ClearRecycleMenuOperation extends BatchDeleteMenuOperation {
|
||||
constructor(menuContext: MenuContext) {
|
||||
super(menuContext);
|
||||
}
|
||||
|
||||
static getFeature(type: string): BrowserOperationInterface {
|
||||
if (type == BrowserOperationFactory.TYPE_PHOTO) {
|
||||
return new OperationImpl();
|
||||
} else if (type == BrowserOperationFactory.TYPE_ALBUM) {
|
||||
return new AlbumOperationImpl();
|
||||
getDeleteMessageResource(dataSource: ItemDataSource): Resource{
|
||||
if (dataSource && dataSource.isSelect()) {
|
||||
return $r('app.string.recycleAlbum_clear_message')
|
||||
} else {
|
||||
return $r('app.plural.recycleAlbum_delete_message', this.count)
|
||||
}
|
||||
}
|
||||
}
|
182
common/base/src/main/ets/operation/CopyMenuOperation.ts
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { MediaConstants } from '../constants/MediaConstants';
|
||||
import { logInfo, logWarn, logError } from '../utils/LoggerUtils'
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { ProcessMenuOperation, FindSameOperation } from './ProcessMenuOperation'
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { MediaOperationType } from '../data/MediaOperationType'
|
||||
import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils';
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MediaDataItem } from '../data/MediaDataItem';
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
|
||||
const TAG = "CopyMenuOperation"
|
||||
|
||||
export class CopyMenuOperation extends ProcessMenuOperation {
|
||||
private albumInfo: SimpleAlbumDataItem;
|
||||
|
||||
constructor(menuContext: MenuContext) {
|
||||
super(menuContext);
|
||||
this.albumInfo = menuContext.albumInfo;
|
||||
}
|
||||
|
||||
doAction(): void {
|
||||
logInfo(TAG, 'copy doAction');
|
||||
if (this.menuContext == null) {
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
|
||||
let dataSource: ItemDataSource = this.menuContext.dataSource;
|
||||
if (dataSource == null) {
|
||||
this.count = this.menuContext.items.length
|
||||
} else {
|
||||
this.count = dataSource.getSelectedCount();
|
||||
}
|
||||
if (this.count <= 0) {
|
||||
logWarn(TAG, 'count <= 0, return');
|
||||
return;
|
||||
}
|
||||
|
||||
this.onOperationEnd = this.menuContext.onOperationEnd;
|
||||
let onOperationStart = this.menuContext.onOperationStart;
|
||||
|
||||
onOperationStart && onOperationStart();
|
||||
|
||||
if (this.menuContext.deviceId) {
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.SHOW_PROGRESS_DIALOG,
|
||||
[$r('app.string.download_progress_message'),
|
||||
MediaOperationType.Copy, this.cancelFunc.bind(this)]);
|
||||
} else {
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.SHOW_PROGRESS_DIALOG,
|
||||
[$r('app.string.copy_progress_message', this.albumInfo.displayName),
|
||||
MediaOperationType.Copy, this.cancelFunc.bind(this)]);
|
||||
}
|
||||
|
||||
if (dataSource == null) {
|
||||
this.items = this.menuContext.items
|
||||
} else {
|
||||
this.items = dataSource.getSelectedItems()
|
||||
}
|
||||
this.processOperation();
|
||||
}
|
||||
|
||||
requestOneBatchOperation() {
|
||||
let item = this.items[this.currentBatch++] as MediaDataItem
|
||||
this.copyOne(item)
|
||||
}
|
||||
|
||||
private async copyOne(item: MediaDataItem) {
|
||||
if (this.menuContext.deviceId) {
|
||||
let path = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_CAMERA) + MediaConstants.REMOTE_ALBUM_PATH + "/"
|
||||
this.albumInfo = new SimpleAlbumDataItem("", "", path, "", "")
|
||||
|
||||
}
|
||||
let fileAsset = await item.loadFileAsset()
|
||||
let assets = await this.getFileCopyOrMoveInfo(fileAsset, this.albumInfo)
|
||||
if (this.menuContext.deviceId) {
|
||||
let displayName = assets.sourceAsset.displayName;
|
||||
let index = displayName.lastIndexOf('.');
|
||||
let start = displayName.lastIndexOf('_');
|
||||
displayName = `${displayName.slice(0, start)}_${new Date().getTime()}${displayName.slice(index)}`;
|
||||
this.copy(assets.sourceAsset, null, {
|
||||
mediaType: assets.sourceAsset.mediaType,
|
||||
name: displayName,
|
||||
path: this.albumInfo.relativePath
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (assets.targetAsset) {
|
||||
if (assets.targetAsset.uri == assets.sourceAsset.uri) {
|
||||
logInfo(TAG, 'copy same fileAsset');
|
||||
this.onOperateContinue();
|
||||
return;
|
||||
}
|
||||
logInfo(TAG, 'show find same file dialog');
|
||||
switch (this.findSameOperation) {
|
||||
case FindSameOperation.NONE:
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.FIND_SAME_FILE_DIALOG,
|
||||
[assets, this.count, () => {
|
||||
this.copy(assets.sourceAsset, assets.targetAsset);
|
||||
}, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this),
|
||||
this.setFindSameOperation.bind(this)]);
|
||||
break;
|
||||
case FindSameOperation.REPLACE:
|
||||
this.copy(assets.sourceAsset, assets.targetAsset);
|
||||
break;
|
||||
case FindSameOperation.SKIP:
|
||||
this.onOperateContinue();
|
||||
break;
|
||||
default:
|
||||
logWarn(TAG, `findSameOperation is error ${this.findSameOperation}`);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.copy(assets.sourceAsset, null, {
|
||||
mediaType: assets.sourceAsset.mediaType,
|
||||
name: assets.sourceAsset.displayName,
|
||||
path: this.albumInfo.relativePath
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async copy(source, target, param?) {
|
||||
try {
|
||||
if (!target) {
|
||||
startTraceWithTaskId('create', this.currentBatch)
|
||||
target = await mediaModel.createOne(param.mediaType, param.name, param.path);
|
||||
finishTraceWithTaskId('create', this.currentBatch);
|
||||
if (target == null) {
|
||||
logWarn(TAG, `Target file creat failed when copyFile!`);
|
||||
this.onError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
startTraceWithTaskId('openWriteClose', this.currentBatch)
|
||||
await mediaModel.copyOne(source, target);
|
||||
finishTraceWithTaskId('openWriteClose', this.currentBatch)
|
||||
this.onCompleted();
|
||||
} catch (error) {
|
||||
finishTraceWithTaskId('create', this.currentBatch);
|
||||
logError(TAG, `copyFile is error ${error}`);
|
||||
this.onError();
|
||||
}
|
||||
}
|
||||
|
||||
cancelFunc(): void {
|
||||
logInfo(TAG, `progress cancel`);
|
||||
this.onOperatePause();
|
||||
let cancelMessage = $r('app.string.copy_cancel_message', this.getExpectProgress().toString());
|
||||
|
||||
if (this.menuContext.deviceId) {
|
||||
this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.DOWNLOAD_CANCEL_OPERATE,
|
||||
[cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]);
|
||||
} else {
|
||||
this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.CANCEL_OPERATE,
|
||||
[cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy cancel callback
|
||||
onOperateContinue(): void {
|
||||
logInfo(TAG, 'Operate Continue');
|
||||
this.isPause = false;
|
||||
this.cyclicOperation();
|
||||
}
|
||||
}
|
@ -12,27 +12,28 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { MediaItem } from '../../model/browser/photo/MediaItem'
|
||||
import { SelectManager } from '../../model/browser/SelectManager'
|
||||
import { BroadCast } from '../../utils/BroadCast'
|
||||
import { AlbumSetDataSource } from '../../model/browser/album/AlbumSetDataSource'
|
||||
import { AlbumInfo } from '../../model/browser/album/AlbumInfo';
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MediaDataItem } from '../data/MediaDataItem'
|
||||
import { Broadcast } from '../utils/Broadcast'
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
|
||||
export class MenuContext {
|
||||
mediaItem: MediaItem;
|
||||
albumId: string;
|
||||
selectManager: SelectManager;
|
||||
items: any[] = [];
|
||||
dataSource: ItemDataSource;
|
||||
|
||||
albumInfo: SimpleAlbumDataItem
|
||||
|
||||
broadCast: Broadcast
|
||||
onOperationStart: Function;
|
||||
onOperationEnd: Function;
|
||||
broadCast: BroadCast
|
||||
jumpSourceToMain: number;
|
||||
albumSetDataSource: AlbumSetDataSource;
|
||||
deviceId: string;
|
||||
albumInfo: AlbumInfo
|
||||
|
||||
withMediaItem(mediaItem: MediaItem): MenuContext {
|
||||
this.mediaItem = mediaItem;
|
||||
jumpSourceToMain: number;
|
||||
deviceId: string;
|
||||
|
||||
albumId: string;
|
||||
|
||||
withItems(items: MediaDataItem[]): MenuContext {
|
||||
this.items = items;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -41,9 +42,9 @@ export class MenuContext {
|
||||
return this;
|
||||
}
|
||||
|
||||
withSelectManager(selectManager: SelectManager): MenuContext {
|
||||
this.selectManager = selectManager;
|
||||
return this;
|
||||
withDataSource(dataSource): MenuContext{
|
||||
this.dataSource = dataSource
|
||||
return this
|
||||
}
|
||||
|
||||
withOperationStartCallback(onOperationStart: Function): MenuContext {
|
||||
@ -56,7 +57,7 @@ export class MenuContext {
|
||||
return this;
|
||||
}
|
||||
|
||||
withBroadCast(param: BroadCast): MenuContext {
|
||||
withBroadCast(param: Broadcast): MenuContext {
|
||||
this.broadCast = param;
|
||||
return this;
|
||||
}
|
||||
@ -66,17 +67,12 @@ export class MenuContext {
|
||||
return this;
|
||||
}
|
||||
|
||||
withAlbumSetDataSource(albumSetDataSource: AlbumSetDataSource): MenuContext {
|
||||
this.albumSetDataSource = albumSetDataSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
withRemoteDevice(deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
withAlbumInfo(albumInfo) {
|
||||
withAlbumInfo(albumInfo: SimpleAlbumDataItem) {
|
||||
this.albumInfo = albumInfo;
|
||||
return this;
|
||||
}
|
140
common/base/src/main/ets/operation/MoveMenuOperation.ets
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
import { logInfo, logWarn, logError } from '../utils/LoggerUtils'
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { ProcessMenuOperation, FindSameOperation } from './ProcessMenuOperation'
|
||||
import { MediaOperationType } from '../data/MediaOperationType'
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils';
|
||||
import { ItemDataSource } from '../vm/ItemDataSource';
|
||||
import { MediaDataItem } from '../data/MediaDataItem';
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
|
||||
const TAG = "MoveMenuOperation"
|
||||
|
||||
export class MoveMenuOperation extends ProcessMenuOperation {
|
||||
albumInfo: SimpleAlbumDataItem;
|
||||
|
||||
constructor(menuContext: MenuContext) {
|
||||
super(menuContext);
|
||||
this.albumInfo = menuContext.albumInfo;
|
||||
}
|
||||
|
||||
doAction(): void {
|
||||
logInfo(TAG, 'move doAction');
|
||||
if (this.menuContext == null) {
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
|
||||
let dataSource: ItemDataSource = this.menuContext.dataSource;
|
||||
if (dataSource == null) {
|
||||
this.count = this.menuContext.items.length
|
||||
} else {
|
||||
this.count = dataSource.getSelectedCount();
|
||||
}
|
||||
if (this.count <= 0) {
|
||||
logWarn(TAG, 'count <= 0, return');
|
||||
return;
|
||||
}
|
||||
|
||||
this.onOperationEnd = this.menuContext.onOperationEnd;
|
||||
let onOperationStart = this.menuContext.onOperationStart;
|
||||
|
||||
onOperationStart && onOperationStart();
|
||||
|
||||
this.menuContext.broadCast.emit(
|
||||
BroadcastConstants.SHOW_PROGRESS_DIALOG, [$r('app.string.move_progress_message', this.albumInfo.displayName),
|
||||
MediaOperationType.Move, this.cancelFunc.bind(this)]);
|
||||
|
||||
if (dataSource == null) {
|
||||
this.items = this.menuContext.items
|
||||
} else {
|
||||
this.items = dataSource.getSelectedItems()
|
||||
}
|
||||
this.processOperation()
|
||||
}
|
||||
|
||||
requestOneBatchOperation() {
|
||||
let item = this.items[this.currentBatch++] as MediaDataItem
|
||||
this.moveOne(item)
|
||||
}
|
||||
|
||||
private async moveOne(item: MediaDataItem) {
|
||||
let fileAsset = await item.loadFileAsset()
|
||||
let assets = await this.getFileCopyOrMoveInfo(fileAsset, this.albumInfo)
|
||||
if (assets.targetAsset) {
|
||||
if (assets.targetAsset.uri == assets.sourceAsset.uri) {
|
||||
logInfo(TAG, 'move same fileAsset');
|
||||
this.onOperateContinue();
|
||||
return;
|
||||
}
|
||||
logInfo(TAG, 'show find same file dialog');
|
||||
switch (this.findSameOperation) {
|
||||
case FindSameOperation.NONE:
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.FIND_SAME_FILE_DIALOG,
|
||||
[assets, this.count, () => {
|
||||
this.move(assets.sourceAsset, this.albumInfo.relativePath, assets.targetAsset);
|
||||
}, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this),
|
||||
this.setFindSameOperation.bind(this)]);
|
||||
break;
|
||||
case FindSameOperation.REPLACE:
|
||||
this.move(assets.sourceAsset, this.albumInfo.relativePath, assets.targetAsset);
|
||||
break;
|
||||
case FindSameOperation.SKIP:
|
||||
this.onOperateContinue();
|
||||
break;
|
||||
default:
|
||||
logWarn(TAG, `findSameOperation is error ${this.findSameOperation}`);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.move(assets.sourceAsset, this.albumInfo.relativePath)
|
||||
}
|
||||
}
|
||||
|
||||
async move(file: MediaLib.FileAsset, path: string, targetFile?) {
|
||||
startTraceWithTaskId('move', this.currentBatch);
|
||||
try {
|
||||
if (targetFile) {
|
||||
await mediaModel.deleteOne(targetFile.uri);
|
||||
}
|
||||
file.relativePath = path
|
||||
file.commitModify()
|
||||
finishTraceWithTaskId('move', this.currentBatch);
|
||||
this.onCompleted();
|
||||
} catch (error) {
|
||||
logError(TAG, `move error: ${error}`)
|
||||
this.onError();
|
||||
}
|
||||
}
|
||||
|
||||
cancelFunc(): void {
|
||||
logInfo(TAG, `progress cancel`);
|
||||
this.onOperatePause();
|
||||
let cancelMessage = $r('app.string.move_cancel_message', this.getExpectProgress().toString());
|
||||
this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.CANCEL_OPERATE,
|
||||
[cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]);
|
||||
}
|
||||
|
||||
// Move cancel callback
|
||||
onOperateContinue(): void {
|
||||
logInfo(TAG, 'Operate Continue');
|
||||
this.isPause = false;
|
||||
this.cyclicOperation();
|
||||
}
|
||||
}
|
@ -12,16 +12,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AsyncCallback } from '../../model/common/AsyncCallback'
|
||||
import { Logger } from '../../utils/Logger'
|
||||
import MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { AsyncCallback } from '../interface/AsyncCallback'
|
||||
import { logDebug, logInfo, logError } from '../utils/LoggerUtils'
|
||||
import { MenuOperationCallback } from './MenuOperationCallback'
|
||||
import { MenuOperation } from './MenuOperation'
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { BroadCastConstants } from '../../model/common/BroadCastConstants';
|
||||
import { BrowserDataFactory } from '../../interface/BrowserDataFactory'
|
||||
import { StringUtil } from '../../utils/StringUtil'
|
||||
import { TraceControllerUtils } from '../../utils/TraceControllerUtils';
|
||||
import { BroadcastConstants } from '../constants/BroadcastConstants';
|
||||
import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils';
|
||||
import { getFetchOptionsByItem } from '../helper/MediaDataHelper';
|
||||
import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
|
||||
import mediaModel from '../model/MediaModel'
|
||||
|
||||
export enum FindSameOperation {
|
||||
NONE,
|
||||
@ -29,12 +30,15 @@ export enum FindSameOperation {
|
||||
SKIP
|
||||
}
|
||||
|
||||
const TAG = "ProcessMenuOperation"
|
||||
|
||||
export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String[]>, MenuOperationCallback {
|
||||
// Number of data operated in a batch
|
||||
readonly BATCH_SIZE: number = 1;
|
||||
|
||||
// Maximum progress
|
||||
readonly MAX_PROGRESS: number = 100;
|
||||
items: any[] = []
|
||||
menuContext: MenuContext;
|
||||
uris: string[];
|
||||
count: number;
|
||||
@ -51,7 +55,6 @@ export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String
|
||||
isPause: boolean = false;
|
||||
isError: boolean = false;
|
||||
findSameOperation: number = FindSameOperation.NONE;
|
||||
logger: Logger = new Logger('ProcessMenuOperation');
|
||||
requestTime: number;
|
||||
|
||||
constructor(menuContext: MenuContext) {
|
||||
@ -60,7 +63,6 @@ export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String
|
||||
}
|
||||
|
||||
doAction(): void {
|
||||
|
||||
}
|
||||
|
||||
// Asynchronous callback for getSelection
|
||||
@ -69,7 +71,7 @@ export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String
|
||||
}
|
||||
|
||||
onCompleted(): void {
|
||||
this.logger.info(`onCompleted ${this.isPause}`);
|
||||
logInfo(TAG, `onCompleted ${this.isPause}`);
|
||||
this.successBatch++;
|
||||
if (!this.isPause) {
|
||||
this.cyclicOperation();
|
||||
@ -77,41 +79,32 @@ export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String
|
||||
}
|
||||
|
||||
onError(): void {
|
||||
this.logger.error(`Operate the ${this.currentBatch} batch data error, total ${this.totalBatches} batches`);
|
||||
logError(TAG, `Operate the ${this.currentBatch} batch data error, total ${this.totalBatches} batches`);
|
||||
this.isError = true;
|
||||
this.cyclicOperation();
|
||||
}
|
||||
|
||||
// Operate a batch of data
|
||||
requestOneBatchOperation(): void {
|
||||
|
||||
}
|
||||
|
||||
// Start processing operation
|
||||
processOperation(): void {
|
||||
this.logger.info('processOperation start');
|
||||
TraceControllerUtils.startTraceWithTaskId('ProgressOperation', this.requestTime);
|
||||
if (this.uris == null) {
|
||||
this.logger.error('Invalid callback data, uris is null!');
|
||||
return;
|
||||
}
|
||||
let length = this.uris.length;
|
||||
this.logger.info(`selected count: ${this.count}, uris's length: ${length}`);
|
||||
logInfo(TAG, 'processOperation start');
|
||||
startTraceWithTaskId('ProgressOperation', this.requestTime);
|
||||
let length = this.items.length;
|
||||
logInfo(TAG, `selected count: ${this.count}, uris's length: ${length}`);
|
||||
// Batch deletion
|
||||
this.totalBatches = Math.floor(length / this.BATCH_SIZE) + ((length % this.BATCH_SIZE) ? 1 : 0);
|
||||
this.logger.info(`The count to be operate is ${length}, operate in ${this.totalBatches} batches`);
|
||||
logInfo(TAG, `The count to be operate is ${length}, operate in ${this.totalBatches} batches`);
|
||||
if (this.isCancelled) {
|
||||
this.isCancelled = false;
|
||||
}
|
||||
this.startTime = Date.now();
|
||||
this.requestOneBatchOperation();
|
||||
|
||||
this.requestOneBatchOperation()
|
||||
}
|
||||
|
||||
// Batch circular deletion
|
||||
cyclicOperation() {
|
||||
this.logger.info('cyclicOperation');
|
||||
this.menuContext.broadCast.emit(BroadCastConstants.UPDATE_PROGRESS,
|
||||
[this.getExpectProgress(), this.currentBatch]);
|
||||
logInfo(TAG, 'cyclicOperation');
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [this.getExpectProgress(), this.currentBatch]);
|
||||
|
||||
if (this.isCancelled) {
|
||||
this.onProcessDone();
|
||||
@ -124,54 +117,57 @@ export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String
|
||||
}
|
||||
}
|
||||
|
||||
// Operate a batch of data
|
||||
requestOneBatchOperation(): void {
|
||||
}
|
||||
|
||||
onProcessDone(): void {
|
||||
this.menuContext.broadCast.emit(BroadCastConstants.UPDATE_PROGRESS, [100]);
|
||||
this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [100]);
|
||||
this.findSameOperation = FindSameOperation.NONE
|
||||
if (this.startTime != null) {
|
||||
let operateCount = this.currentBatch >= this.totalBatches ? this.count : this.currentBatch * this.BATCH_SIZE;
|
||||
let costTime = Date.now() - this.startTime;
|
||||
this.logger.debug(`process data operate done, operate ${operateCount} items, cost time ${costTime} ms,\
|
||||
logDebug(TAG, `process data operate done, operate ${operateCount} items, cost time ${costTime} ms,\
|
||||
average ${(costTime / operateCount)} ms/item.`);
|
||||
}
|
||||
this.isCancelled = false;
|
||||
TraceControllerUtils.finishTraceWithTaskId('ProgressOperation', this.requestTime);
|
||||
finishTraceWithTaskId('ProgressOperation', this.requestTime);
|
||||
this.onOperationEnd && this.onOperationEnd(this.isError, this.successBatch, this.count);
|
||||
}
|
||||
|
||||
// Operate cancel callback
|
||||
onOperateCancelled(): void {
|
||||
this.logger.info('Operate Cancel');
|
||||
logInfo(TAG, 'Operate Cancel');
|
||||
this.isCancelled = true;
|
||||
this.onProcessDone();
|
||||
}
|
||||
|
||||
// Operate cancel callback
|
||||
onOperatePause(): void {
|
||||
this.logger.info('Operate Pause');
|
||||
logInfo(TAG, 'Operate Pause');
|
||||
this.isPause = true;
|
||||
}
|
||||
|
||||
// Calculate the operation progress according to the batch
|
||||
getExpectProgress(): number {
|
||||
this.logger.info('getExpectProgress');
|
||||
logInfo(TAG, 'getExpectProgress');
|
||||
let progress = Math.min(
|
||||
Math.floor(this.MAX_PROGRESS * this.currentBatch * this.BATCH_SIZE / this.count), this.MAX_PROGRESS);
|
||||
return progress;
|
||||
}
|
||||
|
||||
setFindSameOperation(newOperation: number): void {
|
||||
this.logger.info(`setFindSameOperation ${newOperation}`);
|
||||
logInfo(TAG, `setFindSameOperation ${newOperation}`);
|
||||
this.findSameOperation = newOperation
|
||||
}
|
||||
|
||||
async getFileCopyOrMoveInfo(uri: string, albumInfo: any, deviceId?) {
|
||||
this.logger.debug('getFileCopyOrMoveInfo start');
|
||||
let dataImpl = BrowserDataFactory.getFeature(BrowserDataFactory.TYPE_PHOTO);
|
||||
|
||||
let fileAsset = await dataImpl.getDataById(StringUtil.getIdFromUri(uri), deviceId);
|
||||
let targetAsset = await dataImpl.getDataByName(fileAsset.displayName, albumInfo);
|
||||
async getFileCopyOrMoveInfo(fileAsset: MediaLib.FileAsset, albumInfo: SimpleAlbumDataItem) {
|
||||
logDebug(TAG, 'getFileCopyOrMoveInfo start');
|
||||
let item: SimpleAlbumDataItem = new SimpleAlbumDataItem("", fileAsset.displayName, albumInfo.relativePath, "", "")
|
||||
let fetchOptions = await getFetchOptionsByItem(item)
|
||||
let targetAsset = (await mediaModel.getAllCommonMediaItem(fetchOptions, false)).fileAsset
|
||||
if (targetAsset == null || targetAsset == undefined) {
|
||||
this.logger.debug('targetAsset not found');
|
||||
logDebug(TAG, 'targetAsset not found');
|
||||
}
|
||||
|
||||
return { sourceAsset: fileAsset, targetAsset: targetAsset };
|
@ -12,16 +12,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger } from '../../utils/Logger'
|
||||
import Want from '@ohos.application.Want'
|
||||
import { logDebug, logInfo, logWarn, logError } from '../utils/LoggerUtils'
|
||||
import { startAbility } from '../utils/AbilityUtils';
|
||||
import { MenuOperation } from './MenuOperation'
|
||||
import { MenuContext } from './MenuContext'
|
||||
import { AsyncCallback } from '../../model/common/AsyncCallback'
|
||||
import { SelectManager } from '../../model/browser/SelectManager';
|
||||
import { AsyncCallback } from '../interface/AsyncCallback'
|
||||
|
||||
const TAG = "ShareMenuOperation"
|
||||
|
||||
export class ShareMenuOperation implements MenuOperation, AsyncCallback<string[]> {
|
||||
private menuContext: MenuContext;
|
||||
private logger: Logger = new Logger('ShareMenuOperation');
|
||||
private uris: string[];
|
||||
|
||||
constructor(menuContext: MenuContext) {
|
||||
@ -30,21 +31,9 @@ export class ShareMenuOperation implements MenuOperation, AsyncCallback<string[]
|
||||
|
||||
doAction(): void {
|
||||
if (this.menuContext == null) {
|
||||
this.logger.error('menuContext is null, return');
|
||||
logWarn(TAG, 'menuContext is null, return');
|
||||
return;
|
||||
}
|
||||
let selectManager: SelectManager = this.menuContext.selectManager;
|
||||
if (selectManager == null) {
|
||||
this.logger.error('selectManager is null, return');
|
||||
return;
|
||||
}
|
||||
let count = selectManager.getSelectedCount();
|
||||
if (count <= 0) {
|
||||
this.logger.error('count <= 0, return');
|
||||
return;
|
||||
}
|
||||
|
||||
selectManager.getSelection(this);
|
||||
}
|
||||
|
||||
callback(uris: string[]): void {
|
||||
@ -53,8 +42,8 @@ export class ShareMenuOperation implements MenuOperation, AsyncCallback<string[]
|
||||
}
|
||||
|
||||
shareFileAsset() {
|
||||
this.logger.info('shareFileAsset');
|
||||
globalThis.photosAbilityContext.startAbility({
|
||||
logInfo(TAG, 'shareFileAsset');
|
||||
let want: Want = {
|
||||
'action': 'com.huawei.intent.action.hwCHOOSER',
|
||||
'parameters': {
|
||||
'ability.want.params.INTENT': {
|
||||
@ -65,10 +54,7 @@ export class ShareMenuOperation implements MenuOperation, AsyncCallback<string[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
this.logger.debug('raul startAbility complete');
|
||||
}).catch((error) => {
|
||||
this.logger.error(`raul startAbility failed, error: ${JSON.stringify(error)}`);
|
||||
});
|
||||
}
|
||||
startAbility(want)
|
||||
}
|
||||
}
|
35
common/base/src/main/ets/utils/AbilityUtils.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 Want from "@ohos.application.Want";
|
||||
import { logDebug, logError } from './LoggerUtils'
|
||||
|
||||
const TAG = "AbilityUtils"
|
||||
|
||||
export async function startAbility(want: Want): Promise<void> {
|
||||
try {
|
||||
await globalThis.appContext.startAbility(want)
|
||||
logDebug(TAG, 'raul startAbility complete');
|
||||
} catch (error) {
|
||||
logError(TAG, `raul startAbility failed, error: ${JSON.stringify(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function terminateSelf(): Promise<void> {
|
||||
await globalThis.appContext.terminateSelf()
|
||||
}
|
||||
|
||||
export async function terminateSelfWithResult(parameter): Promise<void> {
|
||||
await globalThis.appContext.terminateSelfWithResult(parameter)
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class BroadCast {
|
||||
export class Broadcast {
|
||||
private callBackArray = [];
|
||||
|
||||
constructor() {
|
117
common/base/src/main/ets/utils/DataStoreUtil.ts
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 preferences from '@ohos.data.preferences'
|
||||
import { logDebug, logInfo, logWarn, logError } from './LoggerUtils'
|
||||
import createOrGet from './SingleInstanceUtils';
|
||||
|
||||
const TAG = "DataStoreUtil"
|
||||
|
||||
class DataStoreUtil {
|
||||
private preferences: preferences.Preferences = undefined;
|
||||
private static readonly PREFERENCES_KEY_MY_FORM_STORE = 'myFormStore'
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public async init(): Promise<void> {
|
||||
logDebug(TAG, 'init start!');
|
||||
if (this.preferences != undefined) {
|
||||
logInfo(TAG, `init preferences before`);
|
||||
return
|
||||
}
|
||||
try {
|
||||
let context = globalThis.applicationContext
|
||||
this.preferences = await preferences.getPreferences(context, DataStoreUtil.PREFERENCES_KEY_MY_FORM_STORE)
|
||||
logInfo(TAG, `init preferences ${preferences}`)
|
||||
} catch (err) {
|
||||
logError(TAG, `init err ${err}`);
|
||||
}
|
||||
logDebug(TAG, 'init end!');
|
||||
}
|
||||
|
||||
public async getData(key: string, defValue) {
|
||||
logDebug(TAG, 'getData start!');
|
||||
if (this.preferences == undefined) {
|
||||
logWarn(TAG, `getData preferences is undefined`);
|
||||
return defValue;
|
||||
}
|
||||
let temValue = defValue;
|
||||
try {
|
||||
temValue = await this.preferences.get(key, defValue)
|
||||
logDebug(TAG, "The value of startup is " + temValue)
|
||||
} catch (err) {
|
||||
logError(TAG, `Get the value failed with err: ${err}`)
|
||||
}
|
||||
return temValue;
|
||||
}
|
||||
|
||||
public async putData(key: string, value) {
|
||||
logDebug(TAG, 'putData start!');
|
||||
if (this.preferences == undefined) {
|
||||
logWarn(TAG, 'putData preferences is undefined');
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await this.preferences.put(key, value)
|
||||
logDebug(TAG, 'Put the value successfully.')
|
||||
} catch (err) {
|
||||
logError(TAG, `Put the value failed with err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async delData(key: string) {
|
||||
logDebug(TAG, 'delData start!');
|
||||
if (this.preferences == undefined) {
|
||||
logWarn(TAG, `delData preferences is undefined`);
|
||||
}
|
||||
try {
|
||||
await this.preferences.delete(key)
|
||||
logDebug(TAG, "Delete the value successfully.");
|
||||
} catch (err) {
|
||||
logError(TAG, `Delete the value failed with err: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async flush() {
|
||||
logDebug(TAG, 'flush start!');
|
||||
if (this.preferences == undefined) {
|
||||
logWarn(TAG, `flush preferences is undefined`);
|
||||
}
|
||||
await this.preferences.flush();
|
||||
}
|
||||
|
||||
public async hasData(key: string) {
|
||||
logDebug(TAG, `hasData start! preferences ${this.preferences}`);
|
||||
let ret = false;
|
||||
if (this.preferences == undefined) {
|
||||
logWarn(TAG, `hasData preferences is undefined`);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
ret = await this.preferences.has(key)
|
||||
logDebug(TAG, "hasData the value successfully.");
|
||||
} catch (err) {
|
||||
ret = false
|
||||
logError(TAG, `hasData the value failed with err: ${err}`);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
let dataStore = createOrGet(DataStoreUtil, TAG);
|
||||
|
||||
export default dataStore as DataStoreUtil;
|
||||
|
@ -13,13 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger } from './Logger'
|
||||
import { logInfo, logWarn } from './LoggerUtils'
|
||||
import i18n from '@ohos.i18n';
|
||||
import Intl from '@ohos.intl';
|
||||
|
||||
const TAG = "DateUtil"
|
||||
|
||||
export class DateUtil {
|
||||
// logger
|
||||
private static logger: Logger = new Logger('DateUtil');
|
||||
private static LANGUAGE_LOCALES_MAP = {
|
||||
'zh': 'zh-CN',
|
||||
'en': 'en-US'
|
||||
@ -96,7 +96,7 @@ export class DateUtil {
|
||||
public static getLocalizedTime(milliseconds: number): string {
|
||||
let locales: string = this.getLocales();
|
||||
let is24HourClock = i18n.is24HourClock();
|
||||
this.logger.info(`get is24HourClock ${is24HourClock}`);
|
||||
logInfo(TAG, `get is24HourClock ${is24HourClock}`);
|
||||
|
||||
return new Intl.DateTimeFormat(locales, this.buildDateTimeOpt('', '', '', (!is24HourClock ? '2-digit' : 'numeric'), '2-digit')).format(new Date(milliseconds));
|
||||
}
|
||||
@ -114,11 +114,11 @@ export class DateUtil {
|
||||
// Format duration
|
||||
public static getFormattedDuration(milliSecond: number): string {
|
||||
if (milliSecond == null) {
|
||||
this.logger.error('getFormattedDuration, input is null!');
|
||||
logWarn(TAG, 'getFormattedDuration, input is null!');
|
||||
return '00:00';
|
||||
}
|
||||
if (milliSecond <= 0) {
|
||||
this.logger.error('getFormattedDuration, input is negative number!');
|
||||
logWarn(TAG, 'getFormattedDuration, input is negative number!');
|
||||
return '00:00';
|
||||
}
|
||||
if (milliSecond < this.MILLISECONDS_PER_SECOND) {
|
||||
@ -137,7 +137,7 @@ export class DateUtil {
|
||||
|
||||
private static checkTime(time: number): string{
|
||||
if (time < 0) {
|
||||
this.logger.error('checkTime, input is negative number!');
|
||||
logWarn(TAG, 'checkTime, input is negative number!');
|
||||
return '00';
|
||||
}
|
||||
let formatTime: string = time.toString();
|
61
common/base/src/main/ets/utils/ImageUtil.ts
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logInfo } from './LoggerUtils'
|
||||
|
||||
const TAG = "ImageUtil"
|
||||
const MAX_BIT = 30;
|
||||
const BIT_SIXTEEN = 16;
|
||||
const BIT_EIGHT = 8;
|
||||
const BIT_FOUR = 4;
|
||||
const BIT_TWO = 2;
|
||||
const BIT_ONE = 1;
|
||||
|
||||
export function computeSampleSize(width: number, height: number, minSideLength: number, maxNumOfPixels: number): number {
|
||||
if (width == 0 || height == 0 || minSideLength == 0 || maxNumOfPixels == 0) {
|
||||
return 2;
|
||||
}
|
||||
let initialSize = computeInitialSampleSize(width, height, minSideLength, maxNumOfPixels);
|
||||
logInfo(TAG, `initialSize: ${initialSize}`);
|
||||
return initialSize <= 8 ? nextPowerOf2(initialSize) : Math.floor((initialSize + 8 - 1) / 8) * 8;
|
||||
}
|
||||
|
||||
function computeInitialSampleSize(width: number, height: number, minSideLength: number, maxNumOfPixels: number): number {
|
||||
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
|
||||
return 1;
|
||||
}
|
||||
let lowerBound: number = (maxNumOfPixels == -1) ? 1 : Math.ceil(Math.sqrt((width * height) / maxNumOfPixels));
|
||||
logInfo(TAG, `lowerBound: ${lowerBound}`);
|
||||
if (minSideLength == -1) {
|
||||
return lowerBound;
|
||||
} else {
|
||||
let sampleSize = Math.min(width / minSideLength, height / minSideLength);
|
||||
return Math.max(sampleSize, lowerBound);
|
||||
}
|
||||
}
|
||||
|
||||
function nextPowerOf2(value: number): number {
|
||||
let useValue = value;
|
||||
if (useValue <= 0 || useValue > (1 << MAX_BIT)) {
|
||||
}
|
||||
useValue -= 1;
|
||||
useValue |= useValue >> BIT_SIXTEEN;
|
||||
useValue |= useValue >> BIT_EIGHT;
|
||||
useValue |= useValue >> BIT_FOUR;
|
||||
useValue |= useValue >> BIT_TWO;
|
||||
useValue |= useValue >> BIT_ONE;
|
||||
logInfo(TAG, `nextPowerOf2:${useValue}`);
|
||||
return useValue + 1;
|
||||
}
|
@ -13,24 +13,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface LoadingListener {
|
||||
export function logDebug(TAG: string, message: string | number): void {
|
||||
console.debug('Photos_' + TAG + ': ' + message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Quantity change notice
|
||||
*
|
||||
* @param size Total number of media
|
||||
*/
|
||||
onSizeLoadingFinished(size: number): void;
|
||||
export function logInfo(TAG: string, message: string | number): void {
|
||||
console.info('Photos_' + TAG + ': ' + message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Data loading completion notification
|
||||
*/
|
||||
onDataLoadingFinished(): void;
|
||||
export function logWarn(TAG: string, message: string | number): void {
|
||||
console.warn('Photos_' + TAG + ': ' + message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Data change notification
|
||||
*
|
||||
* @param dataIndex dataIndex
|
||||
*/
|
||||
onDataChanged(dataIndex: number): void;
|
||||
export function logError(TAG: string, message: string | number): void {
|
||||
console.error('Photos_' + TAG + ': ' + message)
|
||||
}
|
@ -13,12 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface BrowserDataInterface {
|
||||
getData(callback: any, param: any): void;
|
||||
export function distance(x1: number, y1: number, x2: number, y2: number): number {
|
||||
let dstX = x1 - x2;
|
||||
let dstY = y1 - y2;
|
||||
return Math.sqrt(dstX * dstX + dstY * dstY);
|
||||
}
|
||||
|
||||
getDataCount(callback: any, param: any): void;
|
||||
|
||||
getDataById(id: any, deviceId?: any): any;
|
||||
|
||||
getDataByName(name: string, albumInfo: any): any;
|
||||
export function clamp(num: number, min: number, max: number): number {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
}
|
35
common/base/src/main/ets/utils/ResourceUtils.ts
Normal file
@ -0,0 +1,35 @@
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* Copyright (c) 2022 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 resourceManager from '@ohos.resourceManager';
|
||||
import { logDebug, logWarn, logError } from './LoggerUtils'
|
||||
|
||||
const TAG = "ResourceUtils"
|
||||
|
||||
export async function getResourceString(resource: Resource): Promise<string> {
|
||||
try {
|
||||
logDebug(TAG, `getResourceString: ${JSON.stringify(resource)}`);
|
||||
let mgr: resourceManager.ResourceManager = await resourceManager.getResourceManager(globalThis.appContext);
|
||||
if (mgr != null || mgr != undefined) {
|
||||
return await mgr.getString(resource.id);
|
||||
} else {
|
||||
logWarn(TAG, `getResourceManager instance is none`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
logError(TAG, `getResourceString error: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
26
common/base/src/main/ets/utils/SingleInstanceUtils.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2021-2022 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 { logDebug } from './LoggerUtils';
|
||||
|
||||
const TAG = "SingleInstanceHelper";
|
||||
|
||||
export default function createOrGet<T>(objectClass: { new(): T }, storageKey: string): T {
|
||||
if (!globalThis[storageKey]) {
|
||||
globalThis[storageKey] = new objectClass();
|
||||
logDebug(TAG, `Create key of ${storageKey}`);
|
||||
}
|
||||
return globalThis[storageKey];
|
||||
}
|
@ -13,12 +13,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger as RootLogger } from '../../../common/utils/Logger'
|
||||
import { logInfo } from './LoggerUtils'
|
||||
|
||||
const MODULE_TIMELINE = 'Timeline_';
|
||||
const TAG = "StringUtil"
|
||||
|
||||
export class Logger extends RootLogger {
|
||||
constructor(module: string) {
|
||||
super(MODULE_TIMELINE + module);
|
||||
}
|
||||
export function getIdFromUri(uri: string): number {
|
||||
let srcIndex = uri.lastIndexOf('/');
|
||||
let srcEnd = uri.length;
|
||||
let srcId = uri.substring(srcIndex + 1, srcEnd);
|
||||
let fileId = new Number(srcId);
|
||||
logInfo(TAG, `getIdByUri fileId: ${fileId}`);
|
||||
return fileId.valueOf();
|
||||
}
|
37
common/base/src/main/ets/utils/TraceControllerUtils.ts
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 bytrace from '@ohos.bytrace'
|
||||
|
||||
// Used to track the start of sequential tasks
|
||||
export function startTrace(name: string): void {
|
||||
bytrace.startTrace(name, 1);
|
||||
}
|
||||
|
||||
// Used to track the end of sequential tasks. The name must be the same as that at start
|
||||
export function finishTrace(name: string): void {
|
||||
bytrace.finishTrace(name, 1);
|
||||
}
|
||||
|
||||
// Used to track the start of cross tasks
|
||||
// (scenarios where the next task starts before the previous task is finished)
|
||||
export function startTraceWithTaskId(name: string, taskId: number): void {
|
||||
bytrace.startTrace(name, taskId);
|
||||
}
|
||||
|
||||
// Used to track the end of cross tasks. The name and taskId must be the same as at start
|
||||
export function finishTraceWithTaskId(name: string, taskId: number): void {
|
||||
bytrace.finishTrace(name, taskId);
|
||||
}
|
@ -12,23 +12,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import prompt from '@system.prompt';
|
||||
import { logDebug } from './LoggerUtils';
|
||||
import screenManager from '../manager/ScreenManager';
|
||||
|
||||
export interface BrowserOperationInterface {
|
||||
create(param: any): any;
|
||||
|
||||
delete(uri: string): any;
|
||||
|
||||
trash(uri: string, isTrash: boolean): any;
|
||||
|
||||
copy(source: any, target: any): any;
|
||||
|
||||
favor(uri: string, isFavor: boolean): void;
|
||||
|
||||
setName(source: any, name: string): void;
|
||||
|
||||
setOrientation(source: any, orientation: number): void;
|
||||
|
||||
setRelativePath(source: any, relativePath: string): void;
|
||||
|
||||
commitChanges(source: any): any;
|
||||
const TAG = "UiUtil"
|
||||
const TOAST_DURATION = 3000;
|
||||
export function showToast(message: string) {
|
||||
let naviBarHeight = screenManager.getNaviBarHeight()
|
||||
logDebug(TAG, `showToast: ${message}`);
|
||||
prompt.showToast({
|
||||
message: message,
|
||||
duration: TOAST_DURATION,
|
||||
bottom: `${64 + naviBarHeight}vp`
|
||||
});
|
||||
}
|
129
common/base/src/main/ets/vm/AlbumsDataSource.ts
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logDebug, logWarn, logError } from '../utils/LoggerUtils';
|
||||
import { AlbumDataImpl } from '../model/AlbumDataImpl'
|
||||
import { ItemDataSource } from './ItemDataSource'
|
||||
import { AlbumDataItem } from '../data/AlbumDataItem'
|
||||
|
||||
const TAG = "AlbumsDataSource"
|
||||
|
||||
export class AlbumsDataSource extends ItemDataSource {
|
||||
private albumDataItems: AlbumDataItem[] = []
|
||||
private albumDataImpl: AlbumDataImpl = new AlbumDataImpl()
|
||||
|
||||
setBlackList(blackList: string[]) {
|
||||
this.albumDataImpl.setBlackList(blackList)
|
||||
}
|
||||
|
||||
setSelectType(selectType: number) {
|
||||
this.albumDataImpl.setSelectType(selectType)
|
||||
}
|
||||
|
||||
setDeviceId(deviceId: string) {
|
||||
this.albumDataImpl.setDeviceId(deviceId)
|
||||
}
|
||||
|
||||
totalCount(): number {
|
||||
return this.albumDataItems.length
|
||||
}
|
||||
|
||||
getData(index: number): any{
|
||||
if (index < 0 || index >= this.albumDataItems.length) {
|
||||
logWarn(TAG, `${index}/${this.albumDataItems.length}`)
|
||||
return undefined
|
||||
}
|
||||
this.albumDataItems[index].index = index
|
||||
return this.albumDataItems[index]
|
||||
}
|
||||
|
||||
isSelect(): boolean {
|
||||
let isSelect = true
|
||||
for (let i = 0;i < this.albumDataItems.length; i++) {
|
||||
if (!this.albumDataItems[i].isSelect) {
|
||||
isSelect = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return isSelect
|
||||
}
|
||||
|
||||
isDisableRename(): boolean {
|
||||
let isDisableRename = false
|
||||
for (let i = 0;i < this.albumDataItems.length; i++) {
|
||||
if (this.albumDataItems[i].isSelect && this.albumDataItems[i].isDisableRename) {
|
||||
isDisableRename = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return isDisableRename
|
||||
}
|
||||
|
||||
isDisableDelete(): boolean {
|
||||
let isDisableDelete = false
|
||||
for (let i = 0;i < this.albumDataItems.length; i++) {
|
||||
if (this.albumDataItems[i].isSelect && this.albumDataItems[i].isDisableDelete) {
|
||||
isDisableDelete = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return isDisableDelete
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.albumDataItems.forEach((item: AlbumDataItem) => {
|
||||
item.setSelect(isSelect)
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedCount(): number {
|
||||
let count = 0
|
||||
for (let i = 0;i < this.albumDataItems.length; i++) {
|
||||
if (this.albumDataItems[i].isSelect) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
getSelectedItems(): AlbumDataItem[]{
|
||||
let items: AlbumDataItem[] = []
|
||||
this.albumDataItems.forEach((item: AlbumDataItem) => {
|
||||
if (item.isSelect) {
|
||||
items.push(item)
|
||||
}
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
dataReload() {
|
||||
this.reloadAlbumItemData().then((isEmpty: boolean) => {
|
||||
this.notifyDataReload()
|
||||
})
|
||||
}
|
||||
|
||||
dataRemove() {
|
||||
for (let i = this.albumDataItems.length - 1;i >= 0; i--) {
|
||||
if (this.albumDataItems[i].isDeleted()) {
|
||||
this.albumDataItems.splice(i, 1)
|
||||
super.notifyDataDelete(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async reloadAlbumItemData(): Promise<boolean> {
|
||||
this.albumDataItems = await this.albumDataImpl.reloadAlbumItemData()
|
||||
return this.albumDataItems.length == 0
|
||||
}
|
||||
}
|
77
common/base/src/main/ets/vm/DistributedDataSource.ts
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { DistributedDataImpl } from '../model/DistributedDataImpl'
|
||||
import { ItemDataSource } from './ItemDataSource'
|
||||
import { PeerDataItem } from '../data/PeerDataItem'
|
||||
|
||||
export class DistributedDataSource extends ItemDataSource {
|
||||
private peerDataItems: PeerDataItem[] = []
|
||||
private distributedDataImpl: DistributedDataImpl = new DistributedDataImpl()
|
||||
|
||||
totalCount(): number {
|
||||
return this.peerDataItems.length
|
||||
}
|
||||
|
||||
getData(index: number): any{
|
||||
this.peerDataItems[index].index = index
|
||||
return this.peerDataItems[index]
|
||||
}
|
||||
|
||||
isSelect(): boolean {
|
||||
let isSelect = true
|
||||
for (let i = 0;i < this.peerDataItems.length; i++) {
|
||||
if (!this.peerDataItems[i].isSelect) {
|
||||
isSelect = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return isSelect
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.peerDataItems.forEach((item: PeerDataItem) => {
|
||||
item.setSelect(isSelect)
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedCount(): number {
|
||||
let count = 0
|
||||
for (let i = 0;i < this.peerDataItems.length; i++) {
|
||||
if (this.peerDataItems[i].isSelect) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
getSelectedItems(): any[]{
|
||||
return []
|
||||
}
|
||||
|
||||
dataReload(): void {
|
||||
this.reloadAlbumItemData().then((isEmpty: number) => {
|
||||
this.notifyDataReload()
|
||||
})
|
||||
}
|
||||
|
||||
dataRemove(): void {
|
||||
}
|
||||
|
||||
async reloadAlbumItemData(): Promise<number> {
|
||||
let before = this.peerDataItems.length
|
||||
this.peerDataItems = await this.distributedDataImpl.reloadAlbumItemData()
|
||||
return this.peerDataItems.length - before
|
||||
}
|
||||
}
|
143
common/base/src/main/ets/vm/GroupItemDataSource.ts
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logDebug, logInfo, logWarn } from '../utils/LoggerUtils'
|
||||
import { GroupDataImpl } from '../model/GroupDataImpl'
|
||||
import { ItemDataSource } from '../vm/ItemDataSource'
|
||||
import { MediaDataItem } from '../data/MediaDataItem';
|
||||
|
||||
const TAG = "GroupItemDataSource"
|
||||
|
||||
export class GroupItemDataSource extends ItemDataSource {
|
||||
groupDataItem: MediaDataItem[] = []
|
||||
private groupDataImpl: GroupDataImpl = new GroupDataImpl()
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
setSelectType(selectType: number) {
|
||||
this.groupDataImpl.setSelectType(selectType)
|
||||
}
|
||||
|
||||
setAlbumId(id: string) {
|
||||
logInfo(TAG, `setAlbumId: ${id}`)
|
||||
this.groupDataImpl.setAlbumId(id)
|
||||
}
|
||||
|
||||
setDeviceId(id: string) {
|
||||
logInfo(TAG, `setDeviceId: ${id}`)
|
||||
this.groupDataImpl.setDeviceId(id)
|
||||
}
|
||||
|
||||
totalCount(): number {
|
||||
return this.groupDataItem.length
|
||||
}
|
||||
|
||||
getIndexByItem(item: MediaDataItem): number{
|
||||
let index = -1
|
||||
let length = this.groupDataItem.length
|
||||
for (let i = 0;i < length; i++) {
|
||||
if (this.groupDataItem[i].uri == item.uri) {
|
||||
index = i;
|
||||
break
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
getData(index: number): any{
|
||||
if (index < 0 || index >= this.groupDataItem.length) {
|
||||
logWarn(TAG, `${index}/${this.groupDataItem.length}`)
|
||||
return undefined
|
||||
}
|
||||
this.groupDataItem[index].index = index
|
||||
return this.groupDataItem[index]
|
||||
}
|
||||
|
||||
isSelect(): boolean {
|
||||
let isSelect = true
|
||||
for (let i = 0;i < this.groupDataItem.length; i++) {
|
||||
if (!this.groupDataItem[i].isSelect) {
|
||||
isSelect = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return isSelect
|
||||
}
|
||||
|
||||
getSelectedCount(): number {
|
||||
let count = 0
|
||||
this.groupDataItem.forEach((item: MediaDataItem) => {
|
||||
if (item.isSelect) {
|
||||
count++
|
||||
}
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
getItems(): MediaDataItem[]{
|
||||
let items: MediaDataItem[] = []
|
||||
this.groupDataItem.forEach((item: MediaDataItem) => {
|
||||
items.push(item)
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
getSelectedItems(): MediaDataItem[]{
|
||||
let items: MediaDataItem[] = []
|
||||
this.groupDataItem.forEach((item: MediaDataItem) => {
|
||||
if (item.isSelect) {
|
||||
items.push(item)
|
||||
}
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
getSelectedUris(): string[]{
|
||||
let uris: string[] = []
|
||||
this.groupDataItem.forEach((item: MediaDataItem) => {
|
||||
if (item.isSelect) {
|
||||
uris.push(item.uri)
|
||||
}
|
||||
})
|
||||
return uris
|
||||
}
|
||||
|
||||
setSelect(isSelect: boolean) {
|
||||
this.groupDataItem.forEach((item: MediaDataItem) => {
|
||||
item.setSelect(isSelect)
|
||||
})
|
||||
}
|
||||
|
||||
async reloadGroupItemData(isGrid: boolean): Promise<boolean> {
|
||||
this.groupDataItem = await this.groupDataImpl.reloadGroupItemData(isGrid)
|
||||
return this.groupDataItem.length == 0
|
||||
}
|
||||
|
||||
dataReload(isGrid: boolean) {
|
||||
this.reloadGroupItemData(isGrid).then((isEmpty: boolean) => {
|
||||
this.notifyDataReload()
|
||||
})
|
||||
}
|
||||
|
||||
dataRemove() {
|
||||
for (let i = this.groupDataItem.length - 1;i >= 0; i--) {
|
||||
if (this.groupDataItem[i].isDeleted()) {
|
||||
this.groupDataItem.splice(i, 1)
|
||||
super.notifyDataDelete(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
69
common/base/src/main/ets/vm/ItemDataSource.ts
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { logInfo } from '../utils/LoggerUtils'
|
||||
import { MediaDataItem } from '../data/MediaDataItem'
|
||||
|
||||
const TAG = "ItemDataSource"
|
||||
|
||||
export abstract class ItemDataSource implements IDataSource {
|
||||
private listeners: DataChangeListener[] = [];
|
||||
|
||||
abstract totalCount(): number
|
||||
|
||||
abstract getData(index: number): any
|
||||
|
||||
abstract isSelect(): boolean
|
||||
|
||||
abstract getSelectedCount(): number
|
||||
|
||||
abstract getSelectedItems(): any[]
|
||||
|
||||
abstract dataRemove(): void
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void{
|
||||
logInfo(TAG, 'registerDataChangeListener');
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener);
|
||||
logInfo(TAG, `registerDataChangeListener, add listener, length: ${this.listeners.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void{
|
||||
logInfo(TAG, 'unregisterDataChangeListener');
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
logInfo(TAG, `registerDataChangeListener, remove listener, length: ${this.listeners.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataChange(index: number): void {
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataChange(index)
|
||||
})
|
||||
}
|
||||
|
||||
notifyDataReload(): void {
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataReloaded()
|
||||
})
|
||||
}
|
||||
|
||||
notifyDataDelete(index: number): void {
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataDelete(index)
|
||||
})
|
||||
}
|
||||
}
|
11
common/base/src/main/module.json5
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"module": {
|
||||
"name": "base",
|
||||
"type": "har",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"uiSyntax": "ets"
|
||||
}
|
||||
}
|
52
common/base/src/main/resources/base/element/color.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "white",
|
||||
"value": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "black",
|
||||
"value": "#000000"
|
||||
},
|
||||
{
|
||||
"name": "album_cover_stroke_color",
|
||||
"value": "#14000000"
|
||||
},
|
||||
{
|
||||
"name": "album_cover_gradient_start_color",
|
||||
"value": "#33000000"
|
||||
},
|
||||
{
|
||||
"name": "album_scrollbar_color",
|
||||
"value": "#ffb3b3b3"
|
||||
},
|
||||
{
|
||||
"name": "transparent",
|
||||
"value": "#00000000"
|
||||
},
|
||||
{
|
||||
"name": "text_color_above_picture",
|
||||
"value": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "item_selection_bg_color",
|
||||
"value": "#80FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "default_background_color",
|
||||
"value": "#FFF1F3F5"
|
||||
},
|
||||
{
|
||||
"name": "empty_or_recycle_album_icon",
|
||||
"value": "#99FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "empty_or_recycle_album_back",
|
||||
"value": "#9E9E9E"
|
||||
},
|
||||
{
|
||||
"name": "color_control_highlight",
|
||||
"value": "#007DFF"
|
||||
}
|
||||
]
|
||||
}
|
144
common/base/src/main/resources/base/element/float.json
Normal file
@ -0,0 +1,144 @@
|
||||
{
|
||||
"float": [
|
||||
{
|
||||
"name": "icon_size",
|
||||
"value": "24vp"
|
||||
},
|
||||
{
|
||||
"name": "icon_size_hot",
|
||||
"value": "32vp"
|
||||
},
|
||||
{
|
||||
"name": "max_padding_start",
|
||||
"value": "24vp"
|
||||
},
|
||||
{
|
||||
"name": "max_padding_end",
|
||||
"value": "24vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_text_line_height",
|
||||
"value": "12vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_duration_markAnchor_x",
|
||||
"value": "-4vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_duration_markAnchor_y",
|
||||
"value": "16vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_duration_margin_right",
|
||||
"value": "32vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_favor_markAnchor_x",
|
||||
"value": "28vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_favor_markAnchor_y",
|
||||
"value": "-4vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_preview_padding",
|
||||
"value": "4vp"
|
||||
},
|
||||
{
|
||||
"name": "grid_item_checkbox_markAnchor",
|
||||
"value": "28vp"
|
||||
},
|
||||
{
|
||||
"name": "scroll_bar_margin_small",
|
||||
"value": "48vp"
|
||||
},
|
||||
{
|
||||
"name": "scroll_bar_small_width",
|
||||
"value": "32vp"
|
||||
},
|
||||
{
|
||||
"name": "scroll_bar_small_height",
|
||||
"value": "56vp"
|
||||
},
|
||||
{
|
||||
"name": "scroll_bar_big_width",
|
||||
"value": "40vp"
|
||||
},
|
||||
{
|
||||
"name": "scroll_bar_big_height",
|
||||
"value": "69vp"
|
||||
},
|
||||
{
|
||||
"name": "album_scrollbar_normal_size",
|
||||
"value": "6vp"
|
||||
},
|
||||
{
|
||||
"name": "album_scrollbar_select_size",
|
||||
"value": "12vp"
|
||||
},
|
||||
{
|
||||
"name": "album_scrollbar_height_size",
|
||||
"value": "80vp"
|
||||
},
|
||||
{
|
||||
"name": "album_scrollbar_radius",
|
||||
"value": "50vp"
|
||||
},
|
||||
{
|
||||
"name": "recycle_album_cover_icon_size",
|
||||
"value": "48vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_name_margin_right",
|
||||
"value": "16vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_count_margin_left",
|
||||
"value": "8vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_count_margin_bottom",
|
||||
"value": "8vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_new_style_icon",
|
||||
"value": "22vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_tab_bar_height",
|
||||
"value": "56vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_page_padding_end",
|
||||
"value": "56vp"
|
||||
},
|
||||
{
|
||||
"name": "album_set_page_padding_end_112",
|
||||
"value": "112vp"
|
||||
},
|
||||
{
|
||||
"name": "album_cover_stroke_width",
|
||||
"value": "0.5vp"
|
||||
},
|
||||
{
|
||||
"name": "crop_vertical_padding",
|
||||
"value": "16vp"
|
||||
},
|
||||
{
|
||||
"name": "dialog_border_radius",
|
||||
"value": "36vp"
|
||||
},
|
||||
{
|
||||
"name": "dialog_title_height",
|
||||
"value": "56vp"
|
||||
},
|
||||
{
|
||||
"name": "dialog_content_margin",
|
||||
"value": "24vp"
|
||||
},
|
||||
{
|
||||
"name": "details_dialog_button_height",
|
||||
"value": "40vp"
|
||||
}
|
||||
]
|
||||
}
|
52
common/base/src/main/resources/base/element/string.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "page_show",
|
||||
"value": "page from npm package"
|
||||
},
|
||||
{
|
||||
"name": "id_text_font_family_medium",
|
||||
"value": "HwChinese-medium"
|
||||
},
|
||||
{
|
||||
"name": "id_text_font_family_regular",
|
||||
"value": "sans-serif"
|
||||
},
|
||||
{
|
||||
"name": "album_all",
|
||||
"value": "All photos"
|
||||
},
|
||||
{
|
||||
"name": "album_camera",
|
||||
"value": "Camera"
|
||||
},
|
||||
{
|
||||
"name": "album_video",
|
||||
"value": "Videos"
|
||||
},
|
||||
{
|
||||
"name": "album_favor",
|
||||
"value": "My favorites"
|
||||
},
|
||||
{
|
||||
"name": "album_remote_device",
|
||||
"value": "From other devices"
|
||||
},
|
||||
{
|
||||
"name": "album_screen_shot",
|
||||
"value": "Screenshots"
|
||||
},
|
||||
{
|
||||
"name": "album_recycle",
|
||||
"value": "Recently deleted"
|
||||
},
|
||||
{
|
||||
"name": "yes",
|
||||
"value": "OK"
|
||||
},
|
||||
{
|
||||
"name": "no",
|
||||
"value": "CANCEL"
|
||||
}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
48
common/base/src/main/resources/zh_CN/element/string.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "id_text_font_family_medium",
|
||||
"value": "中粗"
|
||||
},
|
||||
{
|
||||
"name": "id_text_font_family_regular",
|
||||
"value": "标准"
|
||||
},
|
||||
{
|
||||
"name": "album_all",
|
||||
"value": "所有照片"
|
||||
},
|
||||
{
|
||||
"name": "album_camera",
|
||||
"value": "相机"
|
||||
},
|
||||
{
|
||||
"name": "album_video",
|
||||
"value": "视频"
|
||||
},
|
||||
{
|
||||
"name": "album_favor",
|
||||
"value": "我的收藏"
|
||||
},
|
||||
{
|
||||
"name": "album_screen_shot",
|
||||
"value": "截屏录屏"
|
||||
},
|
||||
{
|
||||
"name": "album_remote_device",
|
||||
"value": "其他设备保存"
|
||||
},
|
||||
{
|
||||
"name": "album_recycle",
|
||||
"value": "最近删除"
|
||||
},
|
||||
{
|
||||
"name": "yes",
|
||||
"value": "确认"
|
||||
},
|
||||
{
|
||||
"name": "no",
|
||||
"value": "取消"
|
||||
}
|
||||
]
|
||||
}
|
12
common/base/src/main/resources/zz_ZX/element/string.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "yes",
|
||||
"value": "[CJ_874431]_OK"
|
||||
},
|
||||
{
|
||||
"name": "no",
|
||||
"value": "[CJ_874432]_Cancel"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,11 +1,22 @@
|
||||
{
|
||||
"devDependencies": {},
|
||||
"name": "entry",
|
||||
"ohos": {
|
||||
"org": "huawei",
|
||||
"directoryLevel": "module",
|
||||
"buildTool": "hvigor"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
"devDependencies": {},
|
||||
"name": "entry",
|
||||
"ohos": {
|
||||
"org": "huawei",
|
||||
"directoryLevel": "module",
|
||||
"buildTool": "hvigor"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/base": "file:../common/base",
|
||||
"@ohos/album": "file:../features/album",
|
||||
"@ohos/browser": "file:../features/browser",
|
||||
"@ohos/distributed": "file:../features/distributed",
|
||||
"@ohos/formEditor": "file:../features/formEditor",
|
||||
"@ohos/grid": "file:../features/grid",
|
||||
"@ohos/mediaOperation": "file:../features/mediaOperation",
|
||||
"@ohos/selectAlbums": "file:../features/selectAlbum",
|
||||
"@ohos/third": "file:../features/third",
|
||||
"@ohos/timeline": "file:../features/timeline"
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ import AbilityStage from "@ohos.application.AbilityStage"
|
||||
|
||||
export default class PhotosAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
globalThis.photosGlobalContext = this.context;
|
||||
globalThis.applicationContext = this.context;
|
||||
}
|
||||
}
|
@ -18,16 +18,19 @@ import { Logger } from './common/Logger'
|
||||
import { FormControllerManager } from './controller/FormControllerManager'
|
||||
import { FormController } from './controller/FormController'
|
||||
import { Constants } from './common/Constants'
|
||||
import mediaModel from '@ohos/base/src/main/ets/model/MediaModel'
|
||||
|
||||
export default class FormAbility extends FormExtension {
|
||||
private logger: Logger = new Logger('FormAbility');
|
||||
|
||||
onCreate(want) {
|
||||
this.logger.info(`form onCreate. want ${JSON.stringify(want)}`);
|
||||
mediaModel.onCreate(this.context)
|
||||
globalThis.appContext = this.context
|
||||
let param = want.parameters;
|
||||
let formId = param['ohos.extra.param.key.form_identity'];
|
||||
this.logger.info(`form onCreate formId: ${formId}`);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance(this.context);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance();
|
||||
formControllerManager.initData(formId, Constants.PHOTOS_FORM_OPERATION_MODE_NONE).then(() => {
|
||||
let formController: FormController = formControllerManager.getController(formId);
|
||||
this.logger.info(`form onCreate. formController ${formController}`);
|
||||
@ -50,13 +53,13 @@ export default class FormAbility extends FormExtension {
|
||||
|
||||
onUpdate(formId) {
|
||||
this.logger.info(`onUpdate, formId: ${formId} context ${JSON.stringify(this.context)}`);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance(this.context);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance();
|
||||
formControllerManager.updateController(formId);
|
||||
}
|
||||
|
||||
onVisibilityChange(newStatus) {
|
||||
this.logger.info(`onVisibilityChange, newStatus: ${JSON.stringify(newStatus)}`);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance(this.context);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance();
|
||||
for (let key in newStatus) {
|
||||
this.logger.info(`onVisibilityChange, key:${key} value ${newStatus[key]}`);
|
||||
let formId = key;
|
||||
@ -66,13 +69,13 @@ export default class FormAbility extends FormExtension {
|
||||
|
||||
onEvent(formId, message) {
|
||||
this.logger.info(`onEvent, formId: ${formId}, message: ${message}`);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance(this.context);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance();
|
||||
formControllerManager.onEvent(formId, message);
|
||||
}
|
||||
|
||||
onDestroy(formId) {
|
||||
this.logger.info(`onDestroy, formId: ${formId}`);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance(this.context);
|
||||
let formControllerManager: FormControllerManager = FormControllerManager.getInstance();
|
||||
formControllerManager.destroyController(formId);
|
||||
}
|
||||
};
|
@ -31,7 +31,6 @@ export class Constants {
|
||||
static readonly CURRENT_INDEX = 'currentIndex_';
|
||||
static readonly FLEX_GROW = 2;
|
||||
static readonly DIALOG_BOTTOM_OFFSET: number = 12;
|
||||
static readonly DEFAULT_TIME = 30;
|
||||
static readonly NUMBER_2 = 2;
|
||||
static readonly NUMBER_3 = 3;
|
||||
static readonly NUMBER_4: number = 4;
|
||||
@ -40,6 +39,4 @@ export class Constants {
|
||||
static readonly NUMBER_24: number = 24;
|
||||
static readonly FROM_PLAYBACK_INTERVAL = 'form_playback_interval';
|
||||
static readonly PHOTOS_FORM_DEFAULT_PERIOD = 30;
|
||||
static readonly SELECT_ALBUM: string = 'selectAlbum';
|
||||
static readonly SELECT_PHOTO: string = 'selectPhoto';
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import { startAbility } from '../../../../../../common/base/src/main/ets/utils/AbilityUtils';
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -12,18 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Want from '@ohos.application.Want'
|
||||
import { MediaDataManager } from '../data/MediaDataManager'
|
||||
import { Logger } from '../common/Logger'
|
||||
import formBindingData from '@ohos.application.formBindingData';
|
||||
import { Constants } from '../common/Constants'
|
||||
import { DataStoreUtil } from '../../common/utils/DataStoreUtil'
|
||||
import formProvider from '@ohos.application.formProvider';
|
||||
import { MediaLibraryAccess } from '../../common/access/MediaLibraryAccess'
|
||||
import { Constants as commonConstants } from '../../common/model/common/Constants'
|
||||
|
||||
export class FormController {
|
||||
private context: any;
|
||||
private formId: string;
|
||||
private operationMode: number = Constants.PHOTOS_FORM_OPERATION_MODE_NONE;
|
||||
private logger: Logger = new Logger('FormController');
|
||||
@ -31,12 +29,11 @@ export class FormController {
|
||||
private static readonly MSG_ROUTER_PHOTOS = 'routerPhotos'
|
||||
mediaDataManager: MediaDataManager;
|
||||
|
||||
constructor(context: any, formId: string, operationMode: number, callback?: Function) {
|
||||
this.context = context;
|
||||
constructor(formId: string, operationMode: number, callback?: Function) {
|
||||
this.formId = formId;
|
||||
this.operationMode = operationMode;
|
||||
this.callback = callback;
|
||||
this.mediaDataManager = new MediaDataManager(context, formId, operationMode, this);
|
||||
this.mediaDataManager = new MediaDataManager(formId, operationMode, this);
|
||||
}
|
||||
|
||||
bindFormData(formId: string): any {
|
||||
@ -89,7 +86,6 @@ export class FormController {
|
||||
onDestroy() {
|
||||
this.logger.info('onDestroy start!');
|
||||
this.mediaDataManager.closeFd();
|
||||
MediaLibraryAccess.getInstance().onDestroy();
|
||||
this.callback = null;
|
||||
this.logger.info('onDestroy done end!');
|
||||
}
|
||||
@ -101,7 +97,7 @@ export class FormController {
|
||||
|
||||
routerPhotoBrowser() {
|
||||
this.logger.debug('routerPhotoBrowser start!');
|
||||
let param = {
|
||||
let param: Want = {
|
||||
'bundleName': 'com.ohos.photos',
|
||||
'abilityName': 'com.ohos.photos.MainAbility',
|
||||
'parameters': {
|
||||
@ -113,10 +109,9 @@ export class FormController {
|
||||
}
|
||||
};
|
||||
this.logger.debug(`routerPhotoBrowser parm ${JSON.stringify(param)}`);
|
||||
this.context.startAbility(param).then(() => {
|
||||
this.logger.info(`raul startAbility complete`);
|
||||
startAbility(param).then(() => {
|
||||
AppStorage.Delete(Constants.FROM_CONTROLLER_MANAGER);
|
||||
});
|
||||
})
|
||||
this.onDestroy();
|
||||
this.logger.debug('routerPhotoBrowser end!');
|
||||
}
|
||||
|
@ -15,22 +15,19 @@
|
||||
import { Constants } from '../common/Constants'
|
||||
import { FormController } from './FormController'
|
||||
import { Logger } from '../common/Logger'
|
||||
import { DataStoreUtil } from '../../common/utils/DataStoreUtil'
|
||||
import dataStore from '../../../../../../common/base/src/main/ets/utils/DataStoreUtil'
|
||||
|
||||
export class FormControllerManager {
|
||||
private context: any;
|
||||
private formControllerMap = new Map();
|
||||
private logger: Logger = new Logger('FormControllerManager');
|
||||
|
||||
private constructor(context) {
|
||||
private constructor() {
|
||||
this.logger.info('new FormControllerManager');
|
||||
this.context = context;
|
||||
DataStoreUtil.getInstance(globalThis.photosGlobalContext);
|
||||
}
|
||||
|
||||
public static getInstance(context: any): FormControllerManager {
|
||||
public static getInstance(): FormControllerManager {
|
||||
if (AppStorage.Get(Constants.FROM_CONTROLLER_MANAGER) == null) {
|
||||
AppStorage.SetOrCreate(Constants.FROM_CONTROLLER_MANAGER, new FormControllerManager(context));
|
||||
AppStorage.SetOrCreate(Constants.FROM_CONTROLLER_MANAGER, new FormControllerManager());
|
||||
}
|
||||
return AppStorage.Get(Constants.FROM_CONTROLLER_MANAGER);
|
||||
}
|
||||
@ -41,7 +38,7 @@ export class FormControllerManager {
|
||||
this.logger.info('formId is 0 or formName is null!');
|
||||
return null;
|
||||
}
|
||||
let controller = new FormController(this.context, formId, operationMode, callback);
|
||||
let controller = new FormController(formId, operationMode, callback);
|
||||
|
||||
if (controller == null || controller == undefined) {
|
||||
this.logger.error('It is failed to create FormController!');
|
||||
@ -54,16 +51,17 @@ export class FormControllerManager {
|
||||
|
||||
async initData(formId: string, operationMode: number, callback?: Function): Promise<void> {
|
||||
this.logger.debug(`initData start! operationMode: ${operationMode}`);
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).init().then(async () => {
|
||||
try {
|
||||
await dataStore.init()
|
||||
let formIdKey: string = 'formId_' + formId;
|
||||
let hasFormId = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(formIdKey);
|
||||
let hasFormId = await dataStore.hasData(formIdKey);
|
||||
this.logger.debug(`The value of hasFormId is ${hasFormId}`);
|
||||
if (hasFormId) {
|
||||
this.createFormController(formId, operationMode, callback);
|
||||
}
|
||||
}).catch((err) => {
|
||||
} catch (err) {
|
||||
this.logger.error(`init err ${err}`);
|
||||
})
|
||||
}
|
||||
this.logger.debug('initData end!');
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -15,11 +14,12 @@
|
||||
*/
|
||||
import { MediaData } from './MediaData'
|
||||
import { Constants } from '../common/Constants'
|
||||
import { MediaConstants } from '@ohos/base/src/main/ets/constants/MediaConstants';
|
||||
import { Logger } from '../common/Logger'
|
||||
import { AlbumDefine } from '../../common/model/browser/AlbumDefine'
|
||||
import { DataStoreUtil } from '../../common/utils/DataStoreUtil'
|
||||
import { MediaLibraryAccess } from '../../common/access/MediaLibraryAccess'
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
import dataStore from '../../../../../../common/base/src/main/ets/utils/DataStoreUtil'
|
||||
import mediaModel from '@ohos/base/src/main/ets/model/MediaModel'
|
||||
import { getResourceString } from '@ohos/base/src/main/ets/utils/ResourceUtils'
|
||||
import { getAlbumDisplayName, getFetchOptions } from '@ohos/base/src/main/ets/helper/MediaDataHelper'
|
||||
|
||||
export class MediaDataManager {
|
||||
private mediaData: MediaData = null;
|
||||
@ -30,78 +30,37 @@ export class MediaDataManager {
|
||||
private fd: number = -1;
|
||||
private key: string = '';
|
||||
private operationMode: number = Constants.PHOTOS_FORM_OPERATION_MODE_NONE;
|
||||
private context: any;
|
||||
private isNextFag: boolean = true;
|
||||
private isUpdate: boolean = false;
|
||||
|
||||
constructor(context: any, formId: string, operationMode: number, formController: any) {
|
||||
constructor(formId: string, operationMode: number, formController: any) {
|
||||
this.formController = formController;
|
||||
this.operationMode = operationMode;
|
||||
this.context = context;
|
||||
this.initData(formId);
|
||||
}
|
||||
|
||||
async getResourceString(resource: Resource) {
|
||||
try {
|
||||
this.logger.info(`getResourceString: ${JSON.stringify(resource)}`);
|
||||
let mgr: resourceManager.ResourceManager = await resourceManager.getResourceManager(this.context);
|
||||
if (mgr != null || mgr != undefined) {
|
||||
return await mgr.getString(resource.id);
|
||||
} else {
|
||||
this.logger.error(`getResourceManager instance is none`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`getResourceString error: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async initData(formId: string) {
|
||||
this.logger.info(`initData formId ${formId}`);
|
||||
MediaLibraryAccess.getInstance().onCreate(this.context);
|
||||
MediaLibraryAccess.getInstance().getPublicDirectory().then(async () => {
|
||||
await this.storageRead(formId);
|
||||
if (this.mediaData == null || this.mediaData == undefined) {
|
||||
this.logger.info('initData new MediaData!');
|
||||
this.mediaData = new MediaData(formId,
|
||||
await this.getResourceString($r('app.string.album_camera')),
|
||||
Constants.PHOTOS_FORM_CAMERA_NAME, AlbumDefine.ALBUM_ID_CAMERA, '', 0,
|
||||
Constants.PHOTOS_FORM_DEFAULT_PERIOD, 1, 0);
|
||||
}
|
||||
this.logger.info(`initData formId ${this.mediaData.formId}
|
||||
albumName ${this.mediaData.albumName} currentIndex ${this.mediaData.currentIndex}`);
|
||||
let displayName = await this.getAlbumDisplayName(this.mediaData.albumId);
|
||||
if (displayName != null) {
|
||||
this.mediaData.displayName = displayName;
|
||||
this.logger.info('initData displayName' + this.mediaData.displayName)
|
||||
}
|
||||
await this.loadData();
|
||||
});
|
||||
}
|
||||
|
||||
private async getAlbumDisplayName(formId) {
|
||||
this.logger.debug('getAlbumDisplayName name ' + formId)
|
||||
switch (formId) {
|
||||
case AlbumDefine.ALBUM_ID_ALL:
|
||||
return await this.getResourceString($r('app.string.album_all'));
|
||||
case AlbumDefine.ALBUM_ID_CAMERA:
|
||||
return await this.getResourceString($r('app.string.album_camera'));
|
||||
case AlbumDefine.ALBUM_ID_FAVOR:
|
||||
return await this.getResourceString($r('app.string.album_favor'));
|
||||
case AlbumDefine.ALBUM_ID_REMOTE:
|
||||
return await this.getResourceString($r('app.string.album_remote_device'));
|
||||
case AlbumDefine.ALBUM_ID_SNAPSHOT:
|
||||
return await this.getResourceString($r('app.string.album_screen_shot'));
|
||||
default:
|
||||
break;
|
||||
await this.storageRead(formId);
|
||||
if (this.mediaData == null || this.mediaData == undefined) {
|
||||
this.logger.info('initData new MediaData!');
|
||||
this.mediaData = new MediaData(formId,
|
||||
await getResourceString($r('app.string.album_camera')),
|
||||
Constants.PHOTOS_FORM_CAMERA_NAME, MediaConstants.ALBUM_ID_CAMERA, '', 0,
|
||||
Constants.PHOTOS_FORM_DEFAULT_PERIOD, 1, 0);
|
||||
}
|
||||
return null;
|
||||
this.logger.info(`initData formId ${this.mediaData.formId}
|
||||
albumName ${this.mediaData.albumName} currentIndex ${this.mediaData.currentIndex}`);
|
||||
let displayName = await getAlbumDisplayName(this.mediaData.albumId);
|
||||
if (displayName != null) {
|
||||
this.mediaData.displayName = displayName;
|
||||
this.logger.info('initData displayName' + this.mediaData.displayName)
|
||||
}
|
||||
await this.loadData();
|
||||
}
|
||||
|
||||
async saveData() {
|
||||
this.logger.debug('saveData');
|
||||
this.filterOutVideoMediaData();
|
||||
this.updateMediaData();
|
||||
if (((this.operationMode != Constants.PHOTOS_FORM_OPERATION_MODE_EVENT)
|
||||
&& (this.operationMode != Constants.PHOTOS_FORM_OPERATION_MODE_DESTROY)
|
||||
@ -146,32 +105,32 @@ export class MediaDataManager {
|
||||
async storageRead(formId: string) {
|
||||
this.logger.debug('storageRead start!');
|
||||
let formIdKey: string = 'formId_' + formId
|
||||
let hasFormId = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(formIdKey);
|
||||
let hasFormId = await dataStore.hasData(formIdKey);
|
||||
this.logger.debug(`The value of hasFormId is ${hasFormId}`)
|
||||
if (hasFormId) {
|
||||
let displayNameKey = 'displayName_' + formId;
|
||||
let displayName = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(displayNameKey, '') as string;
|
||||
let displayName = await dataStore.getData(displayNameKey, '') as string;
|
||||
this.logger.debug(`The value of albumName is ${displayName}`);
|
||||
let albumNameKey = 'albumName_' + formId;
|
||||
let albumName = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(albumNameKey, '') as string;
|
||||
let albumName = await dataStore.getData(albumNameKey, '') as string;
|
||||
this.logger.debug(`The value of albumName is ${albumName}`);
|
||||
let albumIdKey = 'albumId_' + formId;
|
||||
let albumId = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(albumIdKey, '') as string;
|
||||
let albumId = await dataStore.getData(albumIdKey, '') as string;
|
||||
this.logger.debug(`The value of albumId is ${albumId}`);
|
||||
let currentUriKey = 'currentUri_' + formId;
|
||||
let currentUri = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(currentUriKey, '') as string;
|
||||
let currentUri = await dataStore.getData(currentUriKey, '') as string;
|
||||
this.logger.debug(`The value of currentUri is ${currentUri}`);
|
||||
let currentIndexKey = 'currentIndex_' + formId;
|
||||
let currentIndex = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(currentIndexKey, 0) as number;
|
||||
let currentIndex = await dataStore.getData(currentIndexKey, 0) as number;
|
||||
this.logger.debug(`The value of currentIndex is ${currentIndex}`);
|
||||
let intervalTimeKey = 'intervalTime_' + formId;
|
||||
let intervalTime = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(intervalTimeKey, 0) as number;
|
||||
let intervalTime = await dataStore.getData(intervalTimeKey, 0) as number;
|
||||
this.logger.debug(`The value of intervalTime is ${intervalTime}`);
|
||||
let isShowKey = 'isShow_' + formId;
|
||||
let isShow = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(isShowKey, 0) as number;
|
||||
let isShow = await dataStore.getData(isShowKey, 0) as number;
|
||||
this.logger.debug(`The value of isShow is ${isShow}`);
|
||||
let arkUriKey = 'arkUri_' + formId;
|
||||
let arkUri = await DataStoreUtil.getInstance(globalThis.photosGlobalContext).getData(arkUriKey, 0) as number;
|
||||
let arkUri = await dataStore.getData(arkUriKey, 0) as number;
|
||||
this.logger.debug(`The value of arkUri is ${arkUri}`);
|
||||
if (arkUri == 0) {
|
||||
arkUri = 1;
|
||||
@ -187,107 +146,78 @@ export class MediaDataManager {
|
||||
async storageSet() {
|
||||
this.logger.debug('storageSet start!');
|
||||
let formIdKey = 'formId_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(formIdKey, this.mediaData.formId);
|
||||
await dataStore.putData(formIdKey, this.mediaData.formId);
|
||||
let displayNameKey = 'displayName_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(displayNameKey, this.mediaData.displayName);
|
||||
await dataStore.putData(displayNameKey, this.mediaData.displayName);
|
||||
let albumNameKey = 'albumName_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(albumNameKey, this.mediaData.albumName);
|
||||
await dataStore.putData(albumNameKey, this.mediaData.albumName);
|
||||
let albumIdKey = 'albumId_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(albumIdKey, this.mediaData.albumId);
|
||||
await dataStore.putData(albumIdKey, this.mediaData.albumId);
|
||||
let currentUriKey = 'currentUri_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(currentUriKey, this.mediaData.currentUri);
|
||||
await dataStore.putData(currentUriKey, this.mediaData.currentUri);
|
||||
let currentIndexKey = 'currentIndex_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(currentIndexKey, this.mediaData.currentIndex);
|
||||
await dataStore.putData(currentIndexKey, this.mediaData.currentIndex);
|
||||
let intervalTimeKey = 'intervalTime_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(intervalTimeKey, this.mediaData.intervalTime);
|
||||
await dataStore.putData(intervalTimeKey, this.mediaData.intervalTime);
|
||||
let isShowKey = 'isShow_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(isShowKey, this.mediaData.isShowAlbumName);
|
||||
await dataStore.putData(isShowKey, this.mediaData.isShowAlbumName);
|
||||
let arkUriKey = 'arkUri_' + this.mediaData.formId;
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).putData(arkUriKey, this.mediaData.arkUri);
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).flush();
|
||||
await dataStore.putData(arkUriKey, this.mediaData.arkUri);
|
||||
await dataStore.flush();
|
||||
this.logger.debug('storageSet end!');
|
||||
}
|
||||
|
||||
async storageDelete() {
|
||||
this.logger.debug('storageDelete start!');
|
||||
let formIdKey = 'formId_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(formIdKey)) {
|
||||
if (await dataStore.hasData(formIdKey)) {
|
||||
this.logger.debug('storageDelete formId');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(formIdKey);
|
||||
await dataStore.delData(formIdKey);
|
||||
}
|
||||
let displayNameKey = 'displayName_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(displayNameKey)) {
|
||||
if (await dataStore.hasData(displayNameKey)) {
|
||||
this.logger.debug('storageDelete displayName');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(displayNameKey);
|
||||
await dataStore.delData(displayNameKey);
|
||||
}
|
||||
let albumNameKey = 'albumName_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(albumNameKey)) {
|
||||
if (await dataStore.hasData(albumNameKey)) {
|
||||
this.logger.debug('storageDelete albumName');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(albumNameKey);
|
||||
await dataStore.delData(albumNameKey);
|
||||
}
|
||||
let albumIdKey = 'albumId_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(albumIdKey)) {
|
||||
if (await dataStore.hasData(albumIdKey)) {
|
||||
this.logger.debug('storageDelete albumId');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(albumIdKey);
|
||||
await dataStore.delData(albumIdKey);
|
||||
}
|
||||
let currentUriKey = 'currentUri_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(currentUriKey)) {
|
||||
if (await dataStore.hasData(currentUriKey)) {
|
||||
this.logger.debug('storageDelete currentUri');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(currentUriKey);
|
||||
await dataStore.delData(currentUriKey);
|
||||
}
|
||||
let currentIndexKey = 'currentIndex_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(currentIndexKey)) {
|
||||
if (await dataStore.hasData(currentIndexKey)) {
|
||||
this.logger.debug('storageDelete currentIndex');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(currentIndexKey);
|
||||
await dataStore.delData(currentIndexKey);
|
||||
}
|
||||
let intervalTimeKey = 'intervalTime_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(intervalTimeKey)) {
|
||||
if (await dataStore.hasData(intervalTimeKey)) {
|
||||
this.logger.debug('storageDelete intervalTime');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(intervalTimeKey);
|
||||
await dataStore.delData(intervalTimeKey);
|
||||
}
|
||||
let isShowKey = 'isShow_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(isShowKey)) {
|
||||
if (await dataStore.hasData(isShowKey)) {
|
||||
this.logger.debug('storageDelete isShowAlbumName');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(isShowKey);
|
||||
await dataStore.delData(isShowKey);
|
||||
}
|
||||
let arkUriKey = 'arkUri_' + this.mediaData.formId;
|
||||
if (await DataStoreUtil.getInstance(globalThis.photosGlobalContext).hasData(arkUriKey)) {
|
||||
if (await dataStore.hasData(arkUriKey)) {
|
||||
this.logger.debug('storageDelete arkUri');
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).delData(arkUriKey);
|
||||
await dataStore.delData(arkUriKey);
|
||||
}
|
||||
await DataStoreUtil.getInstance(globalThis.photosGlobalContext).flush();
|
||||
await dataStore.flush();
|
||||
this.logger.debug('storageDelete end!');
|
||||
}
|
||||
|
||||
filterOutVideoMediaData() {
|
||||
this.logger.debug('filterOutVideoMediaData start!');
|
||||
if (this.items.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (this.items[this.mediaData.currentIndex].mediaType == MediaLibraryAccess.MEDIA_TYPE_IMAGE) {
|
||||
return;
|
||||
}
|
||||
let currentIndex = this.mediaData.currentIndex;
|
||||
for (let i = currentIndex; i < this.items.length; i++) {
|
||||
let type = this.items[i].mediaType;
|
||||
if (type == MediaLibraryAccess.MEDIA_TYPE_IMAGE) {
|
||||
this.mediaData.currentIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (currentIndex != 0) {
|
||||
for (let i = 0; i < this.items.length; i++) {
|
||||
let type = this.items[i].mediaType;
|
||||
if (type == MediaLibraryAccess.MEDIA_TYPE_IMAGE) {
|
||||
this.mediaData.currentIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.mediaData.currentIndex = 0;
|
||||
this.logger.debug('filterOutVideoMediaData end!');
|
||||
}
|
||||
|
||||
updateMediaData() {
|
||||
this.logger.debug('updateMediaData start! index ${this.mediaData.currentIndex}');
|
||||
if (this.mediaData.currentIndex == -1) {
|
||||
@ -387,7 +317,7 @@ export class MediaDataManager {
|
||||
async openCurrentFd(): Promise<number> {
|
||||
let fileAsset = this.getCurrentItem();
|
||||
this.logger.info(`openCurrentFd uri: ${this.mediaData.currentUri}`);
|
||||
let fd = (fileAsset != null) ? await MediaLibraryAccess.getInstance().openAsset('R', fileAsset) : -1;
|
||||
let fd = (fileAsset != null) ? await mediaModel.openAsset('R', fileAsset) : -1;
|
||||
this.logger.info(`openCurrentFd the fd: ${fd}`);
|
||||
return fd;
|
||||
}
|
||||
@ -400,7 +330,7 @@ export class MediaDataManager {
|
||||
this.logger.info(`close the fd: ${this.fd}`);
|
||||
let fileAsset = this.getCurrentItem();
|
||||
if (fileAsset != null && this.fd != -1) {
|
||||
await MediaLibraryAccess.getInstance().closeAsset(this.fd, fileAsset);
|
||||
await mediaModel.closeAsset(this.fd, fileAsset);
|
||||
this.fd = -1;
|
||||
}
|
||||
}
|
||||
@ -416,18 +346,13 @@ export class MediaDataManager {
|
||||
this.logger.debug('loadData end!');
|
||||
}
|
||||
|
||||
async getItems(albumId: string, startIndex?: number, count?: number, deviceId?) {
|
||||
async getItems(albumId: string) {
|
||||
this.logger.info('getItems start!');
|
||||
let fetchOpt = AlbumDefine.getFileFetchOpt(albumId, deviceId, startIndex, count);
|
||||
switch (albumId) {
|
||||
case AlbumDefine.ALBUM_ID_ALL:
|
||||
let allObject = await MediaLibraryAccess.getInstance().getAllObject(fetchOpt);
|
||||
return allObject;
|
||||
break;
|
||||
default:
|
||||
return await MediaLibraryAccess.getInstance().getEntityAlbumObject(AlbumDefine.getAlbumFetchOpt(
|
||||
albumId, deviceId), fetchOpt);
|
||||
break;
|
||||
let fetchOpt = await getFetchOptions(MediaConstants.SELECT_TYPE_IMAGE, albumId, "")
|
||||
if (albumId == MediaConstants.ALBUM_ID_FAVOR) {
|
||||
return await mediaModel.getAllFavorMediaItems(fetchOpt)
|
||||
} else {
|
||||
return await mediaModel.getAllMediaItems(fetchOpt)
|
||||
}
|
||||
}
|
||||
}
|
@ -14,25 +14,21 @@
|
||||
*/
|
||||
|
||||
import deviceInfo from '@ohos.deviceInfo';
|
||||
import window from '@ohos.window';
|
||||
import Ability from '@ohos.application.Ability'
|
||||
import wantConstant from '@ohos.ability.wantConstant'
|
||||
import { Logger } from '../common/utils/Logger'
|
||||
import { ScreenManager } from '../common/model/common/ScreenManager'
|
||||
import { PixelMapManager } from '../common/model/common/PixelMapManager'
|
||||
import { StatusBarColorController } from '../common/model/common/StatusBarColorController'
|
||||
import { MediaLibraryAccess } from '../common/access/MediaLibraryAccess'
|
||||
import { TimelineDataSourceManager } from '../feature/timeline/model/TimelineDataSourceManager'
|
||||
import screenManager from '../../../../../common/base/src/main/ets/manager/ScreenManager'
|
||||
import { Constants } from '../common/model/common/Constants'
|
||||
import { MediaDataSource } from '../common/model/browser/photo/MediaDataSource'
|
||||
import { BroadCastManager } from '../common/model/common/BroadCastManager';
|
||||
import { TraceControllerUtils } from '../common/utils/TraceControllerUtils';
|
||||
import { BroadCastConstants } from '../common/model/common/BroadCastConstants'
|
||||
import broadcastManager from '../../../../../common/base/src/main/ets/manager/BroadcastManager';
|
||||
import { startTrace, finishTrace } from '../../../../../common/base/src/main/ets/utils/TraceControllerUtils';
|
||||
import { BroadcastConstants } from '../../../../../common/base/src/main/ets/constants/BroadcastConstants'
|
||||
import mediaModel from '@ohos/base/src/main/ets/model/MediaModel'
|
||||
import router from '@system.router'
|
||||
|
||||
const appLogger: Logger = new Logger('app');
|
||||
let isFromCard = false;
|
||||
let isFromCamera = false;
|
||||
let appBroadCast = BroadCastManager.getInstance().getBroadCast();
|
||||
let appBroadcast = broadcastManager.getBroadcast();
|
||||
var pagePath: string = deviceInfo.deviceType == ('phone' || 'default') ? 'product/phone/view/index' : 'product/pad/view/index';
|
||||
|
||||
export default class MainAbility extends Ability {
|
||||
@ -43,12 +39,12 @@ export default class MainAbility extends Ability {
|
||||
|
||||
onCreate(want, launchParam) {
|
||||
appLogger.info('Application onCreate');
|
||||
TraceControllerUtils.startTrace('onCreate');
|
||||
startTrace('onCreate');
|
||||
// Ability is creating, initialize resources for this ability
|
||||
globalThis.photosAbilityContext = this.context;
|
||||
globalThis.appContext = this.context;
|
||||
mediaModel.onCreate(this.context)
|
||||
let action = want.parameters;
|
||||
if (action != null && action != undefined && action.uri == MainAbility.ACTION_URI_PHOTO_DETAIL) {
|
||||
isFromCamera = true;
|
||||
AppStorage.SetOrCreate(Constants.ENTRY_FROM_HAP, Constants.ENTRY_FROM_CAMERA);
|
||||
} else if (action != null && action != undefined && action.uri == MainAbility.ACTION_URI_SINGLE_SELECT) {
|
||||
AppStorage.SetOrCreate(Constants.ENTRY_FROM_HAP, Constants.ENTRY_FROM_SINGLE_SELECT);
|
||||
@ -78,8 +74,8 @@ export default class MainAbility extends Ability {
|
||||
"ohos.permission.MEDIA_LOCATION",
|
||||
"ohos.permission.DISTRIBUTED_DATASYNC"
|
||||
];
|
||||
TraceControllerUtils.startTrace('requestPermissionsFromUser');
|
||||
globalThis.photosAbilityContext.requestPermissionsFromUser(requestPermissionList).then(function (data) {
|
||||
startTrace('requestPermissionsFromUser');
|
||||
this.context.requestPermissionsFromUser(requestPermissionList).then(function (data) {
|
||||
appLogger.info(`requestPermissionsFromUser data: ${JSON.stringify(data)}`)
|
||||
let result = 0
|
||||
for (let i = 0; i < data.authResults.length; i++) {
|
||||
@ -88,14 +84,8 @@ export default class MainAbility extends Ability {
|
||||
if (result >= 0) {
|
||||
// Improve cold startup performance. Initialize the timeline in advance
|
||||
AppStorage.SetOrCreate(Constants.PERMISSION_STATUS, true);
|
||||
TraceControllerUtils.finishTrace('requestPermissionsFromUser');
|
||||
MediaLibraryAccess.getInstance().onCreate(globalThis.photosAbilityContext)
|
||||
if (!isFromCard && !isFromCamera) {
|
||||
TraceControllerUtils.finishTrace('onCreate');
|
||||
TimelineDataSourceManager.getInstance();
|
||||
} else {
|
||||
TraceControllerUtils.finishTrace('onCreate');
|
||||
}
|
||||
finishTrace('requestPermissionsFromUser');
|
||||
finishTrace('onCreate');
|
||||
} else {
|
||||
AppStorage.SetOrCreate(Constants.PERMISSION_STATUS, false);
|
||||
}
|
||||
@ -103,12 +93,12 @@ export default class MainAbility extends Ability {
|
||||
appLogger.error(`Failed to requestPermissionsFromUser, ${err.code}`);
|
||||
});
|
||||
|
||||
appBroadCast.on(BroadCastConstants.THIRD_ROUTE_PAGE, this.thirdRouterPage.bind(this));
|
||||
appBroadcast.on(BroadcastConstants.THIRD_ROUTE_PAGE, this.thirdRouterPage.bind(this));
|
||||
appLogger.info('Application onCreate end');
|
||||
}
|
||||
|
||||
onNewWant(want) {
|
||||
TraceControllerUtils.startTrace('onNewWant');
|
||||
startTrace('onNewWant');
|
||||
let action = want.parameters;
|
||||
if (action != null && action != undefined && action.uri == MainAbility.ACTION_URI_PHOTO_DETAIL) {
|
||||
AppStorage.SetOrCreate(Constants.ENTRY_FROM_HAP, Constants.ENTRY_FROM_CAMERA);
|
||||
@ -132,63 +122,33 @@ export default class MainAbility extends Ability {
|
||||
} else {
|
||||
AppStorage.SetOrCreate(Constants.ENTRY_FROM_HAP, Constants.ENTRY_FROM_NONE);
|
||||
}
|
||||
TraceControllerUtils.finishTrace('onNewWant');
|
||||
finishTrace('onNewWant');
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
// Ability is creating, release resources for this ability
|
||||
appLogger.info('Application onDestroy');
|
||||
let pixelMapManager: PixelMapManager = PixelMapManager.getInstance();
|
||||
pixelMapManager.release();
|
||||
let statusBarColorController: StatusBarColorController = StatusBarColorController.getInstance();
|
||||
statusBarColorController.release();
|
||||
AppStorage.Delete(Constants.ENTRY_FROM_HAP);
|
||||
MediaLibraryAccess.getInstance().onDestroy();
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage) {
|
||||
TraceControllerUtils.startTrace('onWindowStageCreate');
|
||||
startTrace('onWindowStageCreate');
|
||||
// Main window is created, set main page for this ability
|
||||
appLogger.info('Application onWindowStageCreate');
|
||||
globalThis.photosWindowStage = windowStage;
|
||||
ScreenManager.getInstance().on(ScreenManager.ON_LEFT_BLANK_CHANGED, data => {
|
||||
appLogger.info(`onleftBlankChanged: ${data}`);
|
||||
AppStorage.SetOrCreate(Constants.LEFT_BLANK, data);
|
||||
});
|
||||
ScreenManager.getInstance().on(ScreenManager.ON_SPLIT_MODE_CHANGED, mode => {
|
||||
appLogger.info(`onSplitModeChanged: ${JSON.stringify(mode)}`);
|
||||
AppStorage.SetOrCreate(Constants.IS_SPLIT_MODE, mode);
|
||||
});
|
||||
TraceControllerUtils.startTrace('getMainWindow');
|
||||
windowStage.getMainWindow().then((win) => {
|
||||
startTrace('getMainWindow');
|
||||
windowStage.getMainWindow().then((win: window.Window) => {
|
||||
AppStorage.SetOrCreate(Constants.MAIN_WINDOW, win);
|
||||
TraceControllerUtils.finishTrace('getMainWindow');
|
||||
TraceControllerUtils.startTrace('initializationSize');
|
||||
ScreenManager.getInstance().initializationSize(win).then(() => {
|
||||
TraceControllerUtils.finishTrace('initializationSize');
|
||||
finishTrace('getMainWindow');
|
||||
startTrace('initializationSize');
|
||||
screenManager.initializationSize(win).then(() => {
|
||||
finishTrace('initializationSize');
|
||||
if (isFromCard) {
|
||||
MediaLibraryAccess.getInstance().getPublicDirectory().then(() => {
|
||||
let dataSource: MediaDataSource = new MediaDataSource(Constants.DEFAULT_SLIDING_WIN_SIZE);
|
||||
dataSource.setAlbumId(AppStorage.Get(Constants.FROM_ALBUM_ID));
|
||||
dataSource.initialize();
|
||||
let times = 0;
|
||||
//该场景是卡片跳转到大图指定图片,需要等大图数据获取完成再跳转,否则组件无法跳转。
|
||||
let intervalId = setInterval(() => {
|
||||
appLogger.info(`setInterval go`);
|
||||
if (dataSource.getRawData(0) || times >= MainAbility.RETRY_MAX_TIMES) {
|
||||
AppStorage.SetOrCreate(Constants.APP_KEY_PHOTO_BROWSER, dataSource);
|
||||
windowStage.setUIContent(this.context, 'feature/browser/view/PhotoBrowser', null);
|
||||
ScreenManager.getInstance().initWindowMode();
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
times++;
|
||||
}, 50)
|
||||
});
|
||||
windowStage.setUIContent(this.context, 'feature/browser/view/PhotoBrowser', null);
|
||||
} else {
|
||||
windowStage.setUIContent(this.context, pagePath, null);
|
||||
ScreenManager.getInstance().initWindowMode();
|
||||
}
|
||||
TraceControllerUtils.finishTrace('onWindowStageCreate');
|
||||
finishTrace('onWindowStageCreate');
|
||||
}).catch(() => {
|
||||
appLogger.error(`get device screen info failed.`);
|
||||
});
|
||||
@ -205,7 +165,6 @@ export default class MainAbility extends Ability {
|
||||
}
|
||||
|
||||
thirdRouterPage() {
|
||||
TraceControllerUtils.startTrace('thirdRouterPage');
|
||||
let entryFrom = AppStorage.Get(Constants.ENTRY_FROM_HAP);
|
||||
let permission = AppStorage.Get(Constants.PERMISSION_STATUS);
|
||||
appLogger.info(`thirdRouterPage entryFromHap: ${entryFrom} permission: ${permission}`);
|
||||
@ -237,27 +196,10 @@ export default class MainAbility extends Ability {
|
||||
};
|
||||
router.replace(options);
|
||||
} else if (entryFrom == Constants.ENTRY_FROM_FORM_ABILITY) {
|
||||
let dataSource: MediaDataSource = new MediaDataSource(Constants.DEFAULT_SLIDING_WIN_SIZE);
|
||||
dataSource.setAlbumId(AppStorage.Get(Constants.FROM_ALBUM_ID));
|
||||
dataSource.initialize();
|
||||
let times = 0;
|
||||
//该场景是卡片跳转到大图指定图片,需要等大图数据获取完成再跳转,否则组件无法跳转。
|
||||
let intervalId = setInterval(() => {
|
||||
if (dataSource.getRawData(0) || times >= MainAbility.RETRY_MAX_TIMES) {
|
||||
AppStorage.SetOrCreate(Constants.APP_KEY_PHOTO_BROWSER, dataSource);
|
||||
let options = {
|
||||
uri: 'feature/browser/view/PhotoBrowser',
|
||||
params: {
|
||||
pageFrom: Constants.ENTRY_FROM.CARD,
|
||||
albumId: AppStorage.Get(Constants.FROM_ALBUM_ID),
|
||||
position: AppStorage.Get(Constants.FROM_CURRENT_INDEX)
|
||||
}
|
||||
};
|
||||
router.replace(options);
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
times++;
|
||||
}, 50)
|
||||
let options = {
|
||||
uri: 'feature/browser/view/PhotoBrowser',
|
||||
};
|
||||
router.replace(options);
|
||||
} else if (entryFrom == Constants.ENTRY_FROM_FORM_ABILITY_NONE) {
|
||||
let options = {
|
||||
uri: pagePath
|
||||
@ -285,6 +227,5 @@ export default class MainAbility extends Ability {
|
||||
router.clear();
|
||||
AppStorage.SetOrCreate(Constants.ENTRY_FROM_HAP, 0)
|
||||
}, 50);
|
||||
TraceControllerUtils.finishTrace('thirdRouterPage');
|
||||
}
|
||||
}
|
@ -1,504 +0,0 @@
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* Copyright (c) 2022 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 { Logger } from '../utils/Logger'
|
||||
import MediaLib from '@ohos.multimedia.mediaLibrary';
|
||||
import { Constants } from '../model/common/Constants'
|
||||
import { TraceControllerUtils } from '../utils/TraceControllerUtils';
|
||||
|
||||
export class MediaLibraryAccess {
|
||||
private logger: Logger = new Logger('MediaLibraryAccess');
|
||||
static readonly MEDIA_TYPE_IMAGE = MediaLib.MediaType.IMAGE;
|
||||
static readonly MEDIA_TYPE_VIDEO = MediaLib.MediaType.VIDEO;
|
||||
static readonly DIRECTORY_TYPE_IMAGE = MediaLib.DirectoryType.DIR_IMAGE;
|
||||
static readonly DIRECTORY_TYPE_CAMERA = MediaLib.DirectoryType.DIR_CAMERA;
|
||||
static readonly FILE_KEY_ID = MediaLib.FileKey.ID;
|
||||
static readonly FILE_KEY_MEDIA_TYPE = MediaLib.FileKey.MEDIA_TYPE;
|
||||
static readonly FILE_KEY_ALBUM_NAME = MediaLib.FileKey.ALBUM_NAME;
|
||||
static readonly FILE_KEY_ALBUM_ID = MediaLib.FileKey.ALBUM_ID;
|
||||
static readonly FILE_KEY_DISPLAY_NAME = MediaLib.FileKey.DISPLAY_NAME;
|
||||
static readonly FILE_KEY_RELATIVE_PATH = MediaLib.FileKey.RELATIVE_PATH;
|
||||
static readonly FILE_KEY_DATE_TAKEN = MediaLib.FileKey.DATE_ADDED; // TODO dateTaken is not supported, use dateAdded
|
||||
static readonly FILE_KEY_DATE_TRASHED = 'date_trashed' //TODO dataTrashed is not define in FileKey
|
||||
|
||||
PUBLIC_PATH_IMAGE = '';
|
||||
PUBLIC_PATH_CAMERA = '';
|
||||
private media = null;
|
||||
private requestTime: number;
|
||||
|
||||
public static getInstance(): MediaLibraryAccess {
|
||||
if (AppStorage.Get(Constants.APP_KEY_INSTANCE_MEDIA_LIBRARY_ACCESS) == null) {
|
||||
AppStorage.SetOrCreate(Constants.APP_KEY_INSTANCE_MEDIA_LIBRARY_ACCESS, new MediaLibraryAccess());
|
||||
}
|
||||
return AppStorage.Get(Constants.APP_KEY_INSTANCE_MEDIA_LIBRARY_ACCESS);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.requestTime = Date.now();
|
||||
}
|
||||
|
||||
onCreate(context) {
|
||||
this.logger.debug(`Photos_MediaLibraryAccess onCreate ${context}`);
|
||||
if (this.media) {
|
||||
this.logger.debug(`Photos_MediaLibraryAccess onCreate already`);
|
||||
return;
|
||||
}
|
||||
this.media = MediaLib.getMediaLibrary(context);
|
||||
this.logger.debug('Photos_MediaLibraryAccess onCreate end');
|
||||
if (this.media == null || this.media == undefined) {
|
||||
this.logger.error('get media library instance failed!');
|
||||
}
|
||||
|
||||
this.getPublicDirectory();
|
||||
this.logger.info('onCreate done');
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
try {
|
||||
this.media && this.media.release();
|
||||
this.media = null;
|
||||
this.logger.info('onDestroy done');
|
||||
} catch (e) {
|
||||
this.logger.error(`onDestroy error: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
getMediaLibrary() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
async getAllObject(fetchOpt) {
|
||||
this.logger.info(`getAllObject: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
TraceControllerUtils.startTraceWithTaskId('getAllObject', this.requestTime);
|
||||
let dataList = await this.media.getFileAssets(fetchOpt);
|
||||
if (dataList == null) {
|
||||
this.logger.warn('get all Object Data with empty dataList');
|
||||
return [];
|
||||
}
|
||||
this.logger.debug(`get all Object Data raw data size: ${dataList.getCount()}`);
|
||||
if (dataList.getCount() <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let result = await dataList.getAllObject();
|
||||
dataList.close();
|
||||
TraceControllerUtils.finishTraceWithTaskId('getAllObject', this.requestTime);
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(`getAllObject error: ${error}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getCount(fetchOpt) {
|
||||
this.logger.info(`getCount: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
TraceControllerUtils.startTraceWithTaskId('getCount', this.requestTime);
|
||||
let dataList = await this.media.getFileAssets(fetchOpt);
|
||||
if (dataList == null) {
|
||||
this.logger.warn('get count dataList is 0');
|
||||
return 0;
|
||||
}
|
||||
this.logger.debug(`get count raw data size: ${dataList.getCount()}`);
|
||||
let result = dataList.getCount();
|
||||
dataList.close();
|
||||
TraceControllerUtils.finishTraceWithTaskId('getCount', this.requestTime);
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(`get Count error: ${error}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getFirstObject(fetchOpt) {
|
||||
let result = {
|
||||
count: 0,
|
||||
obj: null,
|
||||
}
|
||||
this.logger.info(`getFirstObject: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
TraceControllerUtils.startTraceWithTaskId('getFirstObject', this.requestTime);
|
||||
let fileResult = await this.media.getFileAssets(fetchOpt);
|
||||
if (fileResult != undefined) {
|
||||
result.count = fileResult.getCount();
|
||||
this.logger.error(`getFirstObject count is ${result.count}`);
|
||||
if (result.count <= 0) {
|
||||
return result;
|
||||
}
|
||||
let file = await fileResult.getFirstObject();
|
||||
if (file) {
|
||||
result.obj = file;
|
||||
return result;
|
||||
} else {
|
||||
this.logger.error('Failed getFirstObject');
|
||||
}
|
||||
fileResult.close();
|
||||
}
|
||||
TraceControllerUtils.finishTraceWithTaskId('getFirstObject', this.requestTime);
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(`getFirstObject loadData error: ${error}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteAsset(uri: string) {
|
||||
this.logger.debug(`deleteAsset uri: ${uri}`);
|
||||
await this.media.deleteAsset(uri);
|
||||
}
|
||||
|
||||
async getPublicDirectory() {
|
||||
this.PUBLIC_PATH_IMAGE =
|
||||
await this.media.getPublicDirectory(MediaLibraryAccess.DIRECTORY_TYPE_IMAGE);
|
||||
this.PUBLIC_PATH_CAMERA =
|
||||
await this.media.getPublicDirectory(MediaLibraryAccess.DIRECTORY_TYPE_CAMERA);
|
||||
}
|
||||
|
||||
async createAsset(mediaType: any, displayName: string, relativePath: string) {
|
||||
this.logger.debug('createAsset start');
|
||||
if (relativePath == null || relativePath == undefined) {
|
||||
this.logger.error('createAsset with empty relativePath');
|
||||
return null;
|
||||
}
|
||||
this.logger.info(`createAsset ${mediaType} ${displayName} ${relativePath}`);
|
||||
let fileAsset = await this.media.createAsset(mediaType, displayName, relativePath);
|
||||
this.logger.debug(`createAsset end. new fileAsset: ${fileAsset}`);
|
||||
if (fileAsset == null || fileAsset == undefined) {
|
||||
this.logger.error('createAsset Fail');
|
||||
return null;
|
||||
}
|
||||
return fileAsset;
|
||||
}
|
||||
|
||||
async openAsset(mode: string, fileAsset: any) {
|
||||
this.logger.debug('openAsset start');
|
||||
let fd = await fileAsset.open(mode);
|
||||
this.logger.info(`openAsset end. fd: ${fd}`);
|
||||
if (fd <= 0) {
|
||||
this.logger.error('openAsset Fail');
|
||||
return;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
async closeAsset(fd: number, fileAsset: any) {
|
||||
this.logger.debug('closeAsset start');
|
||||
await fileAsset.close(fd);
|
||||
}
|
||||
|
||||
async trashAsset(isTrash: boolean, fileAsset: any) {
|
||||
this.logger.debug('trashAsset start');
|
||||
await fileAsset.trash(isTrash);
|
||||
}
|
||||
|
||||
async getFavoriteObject(fetchOpt) {
|
||||
this.logger.info(`Get favorite object: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_FAVORITE);
|
||||
this.logger.debug(`[getFavoriteObject] get smart albums length:${albums.length} name:${albums[0].albumName}`);
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
this.logger.debug(`[getFavoriteObject] object count :${fileResult.getCount()}`);
|
||||
let objects = await fileResult.getAllObject();
|
||||
this.logger.debug(`[getFavoriteObject] objects done`);
|
||||
fileResult.close();
|
||||
return objects;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get favorite object exception! msg: ${err}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getTrashObject(fetchOpt) {
|
||||
this.logger.info(`Get trash object: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
this.logger.debug(`[getTrashObject] get smart albums length:${albums.length} name:${albums[0].albumName}`);
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
this.logger.debug(`[getTrashObject] object count :${fileResult.getCount()}`);
|
||||
let objects = await fileResult.getAllObject();
|
||||
this.logger.debug(`[getTrashObject] get objects done`);
|
||||
fileResult.close();
|
||||
return objects;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Trash Object exception! msg: ${err}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getEntityAlbumObject(fetchOpt, fileFetchOpt) {
|
||||
this.logger.info(`getEntityAlbumObject opt${JSON.stringify(fetchOpt)} fileOpt${JSON.stringify(fileFetchOpt)}`);
|
||||
try {
|
||||
let albums = await this.media.getAlbums(fetchOpt);
|
||||
this.logger.debug(`[getEntityAlbumObject]Get Albums done`);
|
||||
this.logger.debug(`[getEntityAlbumObject]Album length:${albums.length}`);
|
||||
if (albums.length == 0) {
|
||||
return []
|
||||
}
|
||||
this.logger.debug(`[getEntityAlbumObject]Albums name:${albums[0].albumName}`);
|
||||
let fileResult = await albums[0].getFileAssets(fileFetchOpt);
|
||||
this.logger.debug(`[getEntityAlbumObject]objects count :${fileResult.getCount()}`);
|
||||
if (fileResult.getCount() == 0) {
|
||||
return []
|
||||
}
|
||||
let objects = await fileResult.getAllObject();
|
||||
this.logger.debug(`[getEntityAlbumObject]Get objects done`);
|
||||
fileResult.close();
|
||||
return objects;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Entity Album Object exception! msg: ${err}`);
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
async getFavoriteCount() {
|
||||
this.logger.debug(`getFavoriteCount`);
|
||||
let fetchOpt = {
|
||||
selections: '',
|
||||
selectionArgs: [],
|
||||
order: ''
|
||||
}
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_FAVORITE);
|
||||
this.logger.debug(`[getFavoriteCount]Get smart Albums length:${albums.length} name:${albums[0].albumName}`);
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
this.logger.debug(`[getFavoriteCount]Get objects done`);
|
||||
let count = fileResult.getCount();
|
||||
fileResult.close();
|
||||
return count;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Favorite count exception! msg: ${err}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getTrashCount() {
|
||||
this.logger.debug(`getTrashCount`);
|
||||
let fetchOpt = {
|
||||
selections: '',
|
||||
selectionArgs: [],
|
||||
order: ''
|
||||
}
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
this.logger.debug(`[getTrashCount]Get smart Albums length:${albums.length} name:${albums[0].albumName}`);
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
this.logger.debug(`[getTrashCount]Get objects done`);
|
||||
let count = fileResult.getCount();
|
||||
fileResult.close();
|
||||
return count;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Trash count exception! msg: ${err}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getEntityAlbumCount(fetchOpt, fileFetchOpt?) {
|
||||
this.logger.info(`getEntityAlbumCount opt: ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
let albums = await this.media.getAlbums(fetchOpt);
|
||||
this.logger.debug(`[getEntityAlbumCount]Get entity Albums length:${albums.length} name:${albums[0].albumName}`);
|
||||
let fileFetchOp;
|
||||
if (fileFetchOpt == undefined) {
|
||||
fileFetchOp = {
|
||||
selections: '',
|
||||
selectionArgs: []
|
||||
}
|
||||
} else {
|
||||
fileFetchOp = fileFetchOpt;
|
||||
}
|
||||
this.logger.debug(`[getEntityAlbumCount]file opt: ${JSON.stringify(fileFetchOp)}`);
|
||||
let fileResult = await albums[0].getFileAssets(fileFetchOp);
|
||||
this.logger.debug(`[getEntityAlbumCount]Get objects done`);
|
||||
let count = fileResult.getCount();
|
||||
fileResult.close();
|
||||
return count;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Entity Album count exception! msg: ${err}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getAlbums(fetchOpt) {
|
||||
this.logger.info(`getAlbums ${JSON.stringify(fetchOpt)}`);
|
||||
try {
|
||||
let albums = await this.media.getAlbums(fetchOpt);
|
||||
this.logger.debug(`[getAlbums]Get Albums done`);
|
||||
this.logger.debug(`[getAlbums]length :${albums.length}`);
|
||||
return albums;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Album exception! msg: ${err}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getFavoriteAlbum(fetchOpt) {
|
||||
this.logger.debug(`getFavoriteObject`);
|
||||
let result = {
|
||||
count: 0,
|
||||
file: undefined,
|
||||
}
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_FAVORITE);
|
||||
this.logger.debug(`[getFavoriteAlbum]Get smart Albums done`);
|
||||
this.logger.debug(`[getFavoriteAlbum]Albums length:${albums.length}`);
|
||||
if (albums.length > 0) {
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
result.count = fileResult.getCount();
|
||||
this.logger.debug(`[getFavoriteAlbum]object count: ${result.count}`);
|
||||
if (result.count > 0) {
|
||||
result.file = await fileResult.getFirstObject();
|
||||
}
|
||||
fileResult.close();
|
||||
}
|
||||
return result;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Favorite album exception! msg: ${err}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
async getTrashAlbum(fetchOpt) {
|
||||
this.logger.debug(`getTrashAlbum`);
|
||||
let result = {
|
||||
count: 0,
|
||||
file: undefined,
|
||||
}
|
||||
try {
|
||||
let albums = await this.media.getPrivateAlbum(MediaLib.PrivateAlbumType.TYPE_TRASH);
|
||||
this.logger.debug(`[getTrashAlbum]Get smart Albums done`);
|
||||
this.logger.debug(`[getTrashAlbum]Albums length:${albums.length}`);
|
||||
if (albums.length > 0) {
|
||||
let fileResult = await albums[0].getFileAssets(fetchOpt);
|
||||
result.count = fileResult.getCount();
|
||||
this.logger.debug(`[getTrashAlbum]trash photo count ${result.count}`);
|
||||
if (result.count > 0) {
|
||||
result.file = await fileResult.getFirstObject();
|
||||
}
|
||||
fileResult.close();
|
||||
}
|
||||
return result;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Trash album exception! msg: ${err}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
async getConnectedRemoteDevice() {
|
||||
this.logger.debug(`getConnectedRemoteDevice`);
|
||||
try {
|
||||
let result = await this.media.getActivePeers();
|
||||
this.logger.debug(`[getConnectedRemoteDevice]device count: ${result.length}`);
|
||||
return result;
|
||||
} catch (err) {
|
||||
this.logger.error(`Get Connected Remote Device exception! msg: ${err}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class FetchOptionBuilder {
|
||||
private fetchOption = {
|
||||
selections: '',
|
||||
selectionArgs: [],
|
||||
order: ''
|
||||
}
|
||||
|
||||
constructor(fetchOpt?) {
|
||||
if (fetchOpt) {
|
||||
this.fetchOption = fetchOpt;
|
||||
}
|
||||
}
|
||||
|
||||
build(): any{
|
||||
return this.fetchOption;
|
||||
}
|
||||
|
||||
media(mediaType: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_MEDIA_TYPE} =?`;
|
||||
this.fetchOption.selectionArgs.push(mediaType);
|
||||
return this;
|
||||
}
|
||||
|
||||
order(key: string, isAsc = true) {
|
||||
let order = isAsc ? '' : ' DESC';
|
||||
this.fetchOption.order = `${this.prefix(this.fetchOption.order)}${key}${order}`;
|
||||
return this;
|
||||
}
|
||||
|
||||
select(start: number, count: number) {
|
||||
this.fetchOption.order = `${this.prefix(this.fetchOption.order)}LIMIT ${start},${count}`
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
device(deviceId: string) {
|
||||
this.fetchOption['networkId'] = deviceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
fileId(id: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_ID} =?`;
|
||||
this.fetchOption.selectionArgs.push(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
albumId(id: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_ALBUM_ID} =?`;
|
||||
this.fetchOption.selectionArgs.push(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
relativePath(path: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_RELATIVE_PATH} =?`;
|
||||
this.fetchOption.selectionArgs.push(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
albumName(name: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_ALBUM_NAME} =?`;
|
||||
this.fetchOption.selectionArgs.push(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
displayName(name: string) {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}${MediaLibraryAccess.FILE_KEY_DISPLAY_NAME} =?`;
|
||||
this.fetchOption.selectionArgs.push(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
logicalAnd() {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}AND`;
|
||||
return this;
|
||||
}
|
||||
|
||||
logicalOr() {
|
||||
this.fetchOption.selections = `${this.prefix(this.fetchOption.selections)}OR`;
|
||||
return this;
|
||||
}
|
||||
|
||||
parentheses() {
|
||||
this.fetchOption.selections = `(${this.fetchOption.selections})`
|
||||
return this;
|
||||
}
|
||||
|
||||
private prefix(str: string) {
|
||||
if (str.length > 0) {
|
||||
return `${str} `;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { TimelineDataImpl } from '../model/browser/photo/TimelineDataImpl';
|
||||
import { PhotoDataImpl } from '../model/browser/photo/PhotoDataImpl';
|
||||
import { AlbumDataImpl } from '../model/browser/album/AlbumDataImpl';
|
||||
import { DistributedDataImpl } from '../model/browser/album/DistributedDataImpl'
|
||||
import { BrowserDataInterface } from './BrowserDataInterface'
|
||||
|
||||
export class BrowserDataFactory {
|
||||
static readonly TYPE_PHOTO = 'photo';
|
||||
static readonly TYPE_ALBUM = 'album';
|
||||
static readonly TYPE_GROUP = 'group';
|
||||
static readonly TYPE_DISTRIBUTED = 'distributed';
|
||||
|
||||
static getFeature(type: string, param?: any): BrowserDataInterface {
|
||||
if (type == BrowserDataFactory.TYPE_ALBUM) {
|
||||
return new AlbumDataImpl(param);
|
||||
} else if (type == BrowserDataFactory.TYPE_PHOTO) {
|
||||
return new PhotoDataImpl();
|
||||
} else if (type == BrowserDataFactory.TYPE_GROUP) {
|
||||
return new TimelineDataImpl();
|
||||
} else if (type == BrowserDataFactory.TYPE_DISTRIBUTED) {
|
||||
return new DistributedDataImpl();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { MenuOperation } from '../view/browserOperation/MenuOperation'
|
||||
import { MenuContext } from '../view/browserOperation/MenuContext'
|
||||
import { Logger } from '../utils/Logger'
|
||||
import { Constants } from '../model/common/Constants'
|
||||
|
||||
export class MenuOperationFactory {
|
||||
private logger: Logger = new Logger('MenuOperationFactory');
|
||||
|
||||
private constructor() {
|
||||
this.logger.info('constructor');
|
||||
}
|
||||
|
||||
public static getInstance(): MenuOperationFactory {
|
||||
if (AppStorage.Get(Constants.APP_KEY_MENU_OPERATION_FACTORY) == null) {
|
||||
AppStorage.SetOrCreate(Constants.APP_KEY_MENU_OPERATION_FACTORY, new MenuOperationFactory());
|
||||
}
|
||||
return AppStorage.Get(Constants.APP_KEY_MENU_OPERATION_FACTORY);
|
||||
}
|
||||
|
||||
public createMenuOperation<T extends MenuOperation>
|
||||
(operation: { new(menuContext: MenuContext): T }, menuContext: MenuContext): T {
|
||||
this.logger.info(`createMenuOperation: ${operation.name}`);
|
||||
return new operation(menuContext);
|
||||
}
|
||||
}
|
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 { Logger } from '../../utils/Logger'
|
||||
import { LoadingListener } from './LoadingListener'
|
||||
|
||||
// Abs DataSource
|
||||
export abstract class AbsDataSource implements IDataSource {
|
||||
// logger
|
||||
logger: Logger = new Logger('AbsDataSource');
|
||||
|
||||
// Last data change time
|
||||
lastChangeTime = 0;
|
||||
|
||||
// Last refresh time
|
||||
lastUpdateTime = 0;
|
||||
|
||||
// Data change monitoring
|
||||
listeners: DataChangeListener[] = [];
|
||||
|
||||
// callbacks
|
||||
mCallbacks = {};
|
||||
|
||||
// Is data initialized
|
||||
isInitData: boolean;
|
||||
|
||||
// Are there any new data changes
|
||||
hasNewChange = false;
|
||||
|
||||
// Freeze data refresh
|
||||
isFreezeDataUpdate = false;
|
||||
|
||||
// Whether the page is in the foreground, and the data can be refreshed in the foreground
|
||||
isActive = true;
|
||||
|
||||
// Data loading listener
|
||||
private loadingListeners: Array<LoadingListener> = new Array<LoadingListener>();
|
||||
|
||||
constructor() {
|
||||
this.registerObserver();
|
||||
}
|
||||
|
||||
abstract initData(): void;
|
||||
|
||||
abstract loadData(): void;
|
||||
|
||||
abstract totalCount(): number;
|
||||
|
||||
abstract getData(index: number): any;
|
||||
|
||||
initialize(): void {
|
||||
if (!this.isInitData) {
|
||||
this.initData();
|
||||
this.isInitData = true;
|
||||
}
|
||||
}
|
||||
|
||||
registerDataChangeListener(listener: DataChangeListener): void {
|
||||
this.logger.info('registerDataChangeListener');
|
||||
if (this.listeners.indexOf(listener) < 0) {
|
||||
this.listeners.push(listener);
|
||||
this.logger.info(`registerDataChangeListener, add listener, length: ${this.listeners.length}`);
|
||||
}
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
unregisterDataChangeListener(listener: DataChangeListener): void {
|
||||
this.logger.info('unregisterDataChangeListener');
|
||||
const pos = this.listeners.indexOf(listener);
|
||||
if (pos >= 0) {
|
||||
this.listeners.splice(pos, 1);
|
||||
this.logger.info(`registerDataChangeListener, remove listener, length: ${this.listeners.length}`);
|
||||
}
|
||||
this.unregisterObserver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overall refresh of notification framework
|
||||
*/
|
||||
onDataReloaded(): void {
|
||||
if (this.isFreezeDataUpdate) {
|
||||
return;
|
||||
}
|
||||
this.logger.info(`onDataReloaded listeners size ${this.listeners.length}`)
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataReloaded();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification frame refresh by index
|
||||
*
|
||||
* @param layoutIndex index
|
||||
*/
|
||||
onDataChanged(layoutIndex: number): void {
|
||||
if (this.isFreezeDataUpdate) {
|
||||
return;
|
||||
}
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataChanged(layoutIndex);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete frame refresh by index
|
||||
*
|
||||
* @param layoutIndex index
|
||||
*/
|
||||
onDataDeleted(layoutIndex: number): void {
|
||||
if (this.isFreezeDataUpdate) {
|
||||
return;
|
||||
}
|
||||
this.listeners.forEach(listener => {
|
||||
listener.onDataDeleted(layoutIndex);
|
||||
})
|
||||
}
|
||||
|
||||
public registerObserver(): void {
|
||||
}
|
||||
|
||||
public unregisterObserver(): void {
|
||||
}
|
||||
|
||||
registerCallback(name: string, cb: Function) {
|
||||
this.mCallbacks[name] = cb;
|
||||
}
|
||||
|
||||
unregisterCallback(name) {
|
||||
this.mCallbacks[name] = undefined;
|
||||
}
|
||||
|
||||
addLoadingListener(listener: LoadingListener): void {
|
||||
if (listener == null) {
|
||||
this.logger.error('listener is null');
|
||||
return;
|
||||
}
|
||||
if (this.loadingListeners.indexOf(listener) > -1) {
|
||||
return;
|
||||
}
|
||||
this.loadingListeners.push(listener);
|
||||
}
|
||||
|
||||
removeLoadingListener(listener: LoadingListener): void {
|
||||
if (listener == null) {
|
||||
this.logger.error('listener is null');
|
||||
return;
|
||||
}
|
||||
let index = this.loadingListeners.indexOf(listener);
|
||||
if (index > -1) {
|
||||
this.loadingListeners.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataChanged(dataIndex: number): void {
|
||||
this.logger.debug(`notifyDataChanged,loadingListeners size:${this.loadingListeners.length},index:${dataIndex}`);
|
||||
for (let listener of this.loadingListeners) {
|
||||
listener.onDataChanged(dataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataLoadingFinished(): void {
|
||||
this.logger.info(`notifyDataLoadingFinished, loadingListeners size:${this.loadingListeners.length}`);
|
||||
for (let listener of this.loadingListeners) {
|
||||
listener.onDataLoadingFinished();
|
||||
}
|
||||
}
|
||||
|
||||
notifySizeLoadingFinished(size: number): void {
|
||||
this.logger.info(`notifySizeLoadingFinished, loadingListeners size: ${this.loadingListeners.length}`);
|
||||
for (let listener of this.loadingListeners) {
|
||||
listener.onSizeLoadingFinished(size);
|
||||
}
|
||||
}
|
||||
|
||||
onActive(): void {
|
||||
this.logger.info('onActive');
|
||||
this.isActive = true;
|
||||
if (this.lastUpdateTime < this.lastChangeTime) {
|
||||
// Page back to the foreground, if there is a refresh media library reload refresh.
|
||||
this.loadData();
|
||||
}
|
||||
}
|
||||
|
||||
onInActive(): void {
|
||||
this.logger.info('onInActive');
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
freeze(): void {
|
||||
this.logger.info('freeze')
|
||||
this.isFreezeDataUpdate = true;
|
||||
}
|
||||
|
||||
unfreeze(): void {
|
||||
this.logger.info('unfreeze')
|
||||
this.isFreezeDataUpdate = false;
|
||||
}
|
||||
|
||||
onChange(mediaType) {
|
||||
this.lastChangeTime = Date.now();
|
||||
this.logger.debug(`onChange mediaType: ${mediaType} ${this.hasNewChange} ${this.isActive}`);
|
||||
if (!this.hasNewChange) {
|
||||
this.hasNewChange = true;
|
||||
if (this.isActive) {
|
||||
this.loadData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|