调整架构 添加base 基础工具模块
This commit is contained in:
6
base/.gitignore
vendored
Normal file
6
base/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/.preview
|
||||
/build
|
||||
/.cxx
|
||||
/.test
|
8
base/Index.ets
Normal file
8
base/Index.ets
Normal file
@@ -0,0 +1,8 @@
|
||||
export { Log } from "./src/main/ets/utils/Log"
|
||||
|
||||
export { ScreenUtil } from './src/main/ets/utils/ScreenUtil'
|
||||
|
||||
export { BaseLocalStorage, BaseLocalStorageKey } from './src/main/ets/utils/BaseLocalStorage'
|
||||
|
||||
export { Emitter, EmitterItem } from './src/main/ets/event/Emitter'
|
||||
export { WebViewEventKey } from './src/main/ets/event/EventKey'
|
25
base/build-profile.json5
Normal file
25
base/build-profile.json5
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
},
|
||||
"buildOptionSet": [
|
||||
{
|
||||
"name": "release",
|
||||
"arkOptions": {
|
||||
"obfuscation": {
|
||||
"ruleOptions": {
|
||||
"enable": true,
|
||||
"files": [
|
||||
"./obfuscation-rules.txt"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
]
|
||||
}
|
6
base/hvigorfile.ts
Normal file
6
base/hvigorfile.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { hspTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
|
||||
export default {
|
||||
system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||
}
|
18
base/obfuscation-rules.txt
Normal file
18
base/obfuscation-rules.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
# Define project specific obfuscation rules here.
|
||||
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||
#
|
||||
# For more details, see
|
||||
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
|
||||
|
||||
# Obfuscation options:
|
||||
# -disable-obfuscation: disable all obfuscations
|
||||
# -enable-property-obfuscation: obfuscate the property names
|
||||
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||
# -compact: remove unnecessary blank spaces and all line feeds
|
||||
# -remove-log: remove all console.* statements
|
||||
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||
# -apply-namecache: reuse the given cache file
|
||||
|
||||
# Keep options:
|
||||
# -keep-property-name: specifies property names that you want to keep
|
||||
# -keep-global-name: specifies names that you want to keep in the global scope
|
11
base/oh-package.json5
Normal file
11
base/oh-package.json5
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "base",
|
||||
"version": "1.0.0",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "Index.ets",
|
||||
"author": "",
|
||||
"license": "Apache-2.0",
|
||||
"packageType": "InterfaceHar",
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
110
base/src/main/ets/event/Emitter.ets
Normal file
110
base/src/main/ets/event/Emitter.ets
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
export interface EmitterItem {
|
||||
key: string
|
||||
listener: Function
|
||||
}
|
||||
|
||||
type EmitterAllType = string | object | boolean | number | Object | Number | BigInt;
|
||||
|
||||
export class Emitter {
|
||||
private static instance: Emitter;
|
||||
private static events: Map<string, EmitterItem[]> = new Map
|
||||
private static viscosityData: Map<string, EmitterAllType[]> = new Map
|
||||
|
||||
public static getInstance(): Emitter {
|
||||
if (!Emitter.instance) {
|
||||
Emitter.instance = new Emitter();
|
||||
}
|
||||
|
||||
return Emitter.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加监听
|
||||
* @param key
|
||||
* @param listener
|
||||
* @returns
|
||||
*/
|
||||
public on(key: string, listener: Function): EmitterItem {
|
||||
let item: EmitterItem = {key: key, listener: listener};
|
||||
if (typeof listener !== "function") {
|
||||
throw new TypeError('the listener not a function')
|
||||
}
|
||||
let items: EmitterItem[] | undefined = Emitter.events.get(key);
|
||||
if (!items) {
|
||||
items = []
|
||||
}
|
||||
items.push(item)
|
||||
Emitter.events.set(key, items)
|
||||
if (Emitter.viscosityData.has(key)) {
|
||||
let value = Emitter.viscosityData.get(key)
|
||||
if (value == undefined) {
|
||||
listener();
|
||||
} else {
|
||||
listener(...value);
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消监听
|
||||
* @param listener
|
||||
*/
|
||||
public off(listener: EmitterItem): void {
|
||||
let items = Emitter.events.get(listener.key)
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
items = items.filter((it)=> {
|
||||
return it !== listener;
|
||||
})
|
||||
Emitter.events.set(listener.key, items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布普通消息
|
||||
* @param key
|
||||
* @param args
|
||||
*/
|
||||
public emmit<T>(key: string, ...args: T[]) {
|
||||
let items = Emitter.events.get(key)
|
||||
if (!items || items.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
items.forEach((item: EmitterItem, index: number) => {
|
||||
if (typeof item.listener === 'function') {
|
||||
item.listener(...args)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布粘性消息
|
||||
* @param key
|
||||
* @param args
|
||||
*/
|
||||
public emmitViscosity<T>(key: string, ...args: T[]) {
|
||||
this.emmit(key, ...args);
|
||||
Emitter.viscosityData.set(key, args as EmitterAllType[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除粘性消息
|
||||
* @param key
|
||||
*/
|
||||
public deleteViscosity<T>(key: string) {
|
||||
if (Emitter.viscosityData.has(key)) {
|
||||
Emitter.viscosityData.delete(key)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除所有监听
|
||||
*/
|
||||
public removeAllListener() {
|
||||
Emitter.events = new Map;
|
||||
}
|
||||
|
||||
}
|
5
base/src/main/ets/event/EventKey.ets
Normal file
5
base/src/main/ets/event/EventKey.ets
Normal file
@@ -0,0 +1,5 @@
|
||||
export class WebViewEventKey {
|
||||
public static readonly TitleEvent: string = "web_view_event_title";
|
||||
public static readonly DarkModeChangedEvent: string = "web_view_event_dark_mode_changed";
|
||||
public static readonly UrlChangedEvent: string = "web_view_event_url_change_changed";
|
||||
}
|
17
base/src/main/ets/pages/Index.ets
Normal file
17
base/src/main/ets/pages/Index.ets
Normal file
@@ -0,0 +1,17 @@
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State message: string = 'Hello World';
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize(50)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
65
base/src/main/ets/utils/BaseLocalStorage.ets
Normal file
65
base/src/main/ets/utils/BaseLocalStorage.ets
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
import { Context } from '@kit.AbilityKit';
|
||||
import dataPreferences from '@ohos.data.preferences';
|
||||
import { Log } from './Log';
|
||||
|
||||
export class BaseLocalStorageKey {
|
||||
static readonly KEY_SERVER_CONFIG = "key_config";
|
||||
}
|
||||
|
||||
export class BaseLocalStorage {
|
||||
|
||||
private static instance: BaseLocalStorage;
|
||||
private static lock: boolean = false;
|
||||
private static readonly XY_DP_Name = "LocalData";
|
||||
static getInstance(): BaseLocalStorage {
|
||||
if (!BaseLocalStorage.instance) {
|
||||
if (!BaseLocalStorage.lock) {
|
||||
BaseLocalStorage.lock = true;
|
||||
BaseLocalStorage.instance = new BaseLocalStorage();
|
||||
BaseLocalStorage.lock = false;
|
||||
}
|
||||
}
|
||||
return BaseLocalStorage.instance;
|
||||
}
|
||||
|
||||
private context: Context | null = null;
|
||||
private preferences: dataPreferences.Preferences | null = null;
|
||||
private constructor() {
|
||||
}
|
||||
|
||||
public init(context: Context): void {
|
||||
if (!this.context) {
|
||||
this.context = context.getApplicationContext();
|
||||
let options: dataPreferences.Options = { name: BaseLocalStorage.XY_DP_Name };
|
||||
this.preferences = dataPreferences.getPreferencesSync(this.context, options);
|
||||
} else {
|
||||
Log.i("LocalStorage is already init.")
|
||||
}
|
||||
}
|
||||
|
||||
public putData(key: string, value: dataPreferences.ValueType) {
|
||||
Log.i(`put sp data, key:${key}, value:${value}`)
|
||||
this.preferences?.putSync(key, value);
|
||||
this.preferences?.flush();
|
||||
}
|
||||
|
||||
public clearData(key: string) {
|
||||
this.preferences?.delete(key);
|
||||
this.preferences?.flush();
|
||||
}
|
||||
|
||||
public getData(key: string, defaultValue: dataPreferences.ValueType): dataPreferences.ValueType | undefined {
|
||||
let value = this.preferences?.getSync(key, defaultValue);
|
||||
Log.i(`get sp data, key:${key}, value:${value}`)
|
||||
return value;
|
||||
}
|
||||
|
||||
public getObject<T>(key: string): T {
|
||||
let value = this.getData(key, "{}") as string;
|
||||
if (value.toString().length > 0) {
|
||||
return JSON.parse(value) as T;
|
||||
}
|
||||
return "{}" as T;
|
||||
}
|
||||
}
|
33
base/src/main/ets/utils/Log.ets
Normal file
33
base/src/main/ets/utils/Log.ets
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
let domain: number = 0xFF00;
|
||||
let prefix: string = 'HM4Demo';
|
||||
let format: string = `%{public}s, %{public}s`;
|
||||
|
||||
export class Log {
|
||||
|
||||
static d(...args: string[]) {
|
||||
hilog.debug(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static i(...args: string[]) {
|
||||
hilog.info(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static w(...args: string[]) {
|
||||
hilog.warn(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static e(...args: string[]) {
|
||||
hilog.error(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static f(...args: string[]) {
|
||||
hilog.fatal(domain,prefix, format, args);
|
||||
}
|
||||
|
||||
static isLoggable(level: number) {
|
||||
hilog.isLoggable(domain, prefix, level);
|
||||
}
|
||||
}
|
115
base/src/main/ets/utils/ScreenUtil.ets
Normal file
115
base/src/main/ets/utils/ScreenUtil.ets
Normal file
@@ -0,0 +1,115 @@
|
||||
import window from '@ohos.window';
|
||||
import mediaquery from '@ohos.mediaquery';
|
||||
import { Log } from './Log';
|
||||
|
||||
export class ScreenUtil {
|
||||
// TODO: 工具待抽离, key统一定义
|
||||
static readonly isPortraitKey: string = "xy_screen_is_portrait";
|
||||
private static instance: ScreenUtil;
|
||||
public width: number = 0
|
||||
public height: number = 0
|
||||
public statusBarHeight: number = 0
|
||||
public bottomSafeHeight: number = 0
|
||||
public contentHeight: number = 0;
|
||||
|
||||
public layoutWidth: number = 0
|
||||
public layoutHeight: number = 0
|
||||
|
||||
|
||||
private portraitListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: portrait)');
|
||||
|
||||
public static getInstance(): ScreenUtil {
|
||||
if (!ScreenUtil.instance) {
|
||||
ScreenUtil.instance = new ScreenUtil();
|
||||
}
|
||||
return ScreenUtil.instance;
|
||||
}
|
||||
|
||||
initScreenSize(): void {
|
||||
this.portraitListener.on('change', (result)=> {
|
||||
AppStorage.setOrCreate(ScreenUtil.isPortraitKey, result.matches)
|
||||
})
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
|
||||
let avoidArea = windowClass.getWindowAvoidArea(type);
|
||||
this.bottomSafeHeight = px2vp(avoidArea.bottomRect.height); // 获取到导航条区域的高度
|
||||
type = window.AvoidAreaType.TYPE_SYSTEM;
|
||||
avoidArea = windowClass.getWindowAvoidArea(type);
|
||||
this.statusBarHeight = px2vp(avoidArea.topRect.height);
|
||||
this.width = px2vp(windowClass.getWindowProperties().windowRect.width);
|
||||
this.height = px2vp(windowClass.getWindowProperties().windowRect.height);
|
||||
this.layoutWidth = this.width;
|
||||
this.layoutHeight = this.height - this.statusBarHeight - this.bottomSafeHeight;
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setPreferredOrientation(orientation: window.Orientation): void {
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setPreferredOrientation(orientation);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setPreferredOrientationCallBack(orientation: window.Orientation, callback: ()=>void): void{
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setPreferredOrientation(orientation,callback);
|
||||
AppStorage.setOrCreate(ScreenUtil.isPortraitKey, orientation == window.Orientation.PORTRAIT || orientation == window.Orientation.PORTRAIT_INVERTED);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setWindowLayoutFullScreen(isLayoutFullScreen: boolean): void {
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen);
|
||||
windowClass.setSpecificSystemBarEnabled('status', !isLayoutFullScreen);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setWindowSystemBarProperties(systemBarProperties: window.SystemBarProperties): void {
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setWindowSystemBarProperties(systemBarProperties, (err) => {
|
||||
if (err.code) {
|
||||
console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
|
||||
return;
|
||||
}
|
||||
console.info('Succeeded in setting the system bar properties.');
|
||||
});
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setWindowSystemBarEnable(names:Array<'status' | 'navigation'>){
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setWindowSystemBarEnable(names, (err) => {
|
||||
if (err.code) {
|
||||
console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
|
||||
return;
|
||||
}
|
||||
console.info('Succeeded in setting the system bar properties.');
|
||||
});
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
})
|
||||
}
|
||||
|
||||
setWindowKeepScreenOn(isKeep: boolean) {
|
||||
Log.i(`setWindowKeepScreenOn:${isKeep}`)
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setWindowKeepScreenOn(isKeep);
|
||||
});
|
||||
}
|
||||
}
|
14
base/src/main/module.json5
Normal file
14
base/src/main/module.json5
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"module": {
|
||||
"name": "base",
|
||||
"type": "shared",
|
||||
"description": "$string:shared_desc",
|
||||
"deviceTypes": [
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"pages": "$profile:main_pages"
|
||||
}
|
||||
}
|
8
base/src/main/resources/base/element/color.json
Normal file
8
base/src/main/resources/base/element/color.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "white",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
8
base/src/main/resources/base/element/string.json
Normal file
8
base/src/main/resources/base/element/string.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "shared_desc",
|
||||
"value": "description"
|
||||
}
|
||||
]
|
||||
}
|
5
base/src/main/resources/base/profile/main_pages.json
Normal file
5
base/src/main/resources/base/profile/main_pages.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"pages/Index"
|
||||
]
|
||||
}
|
5
base/src/test/List.test.ets
Normal file
5
base/src/test/List.test.ets
Normal file
@@ -0,0 +1,5 @@
|
||||
import localUnitTest from './LocalUnit.test';
|
||||
|
||||
export default function testsuite() {
|
||||
localUnitTest();
|
||||
}
|
33
base/src/test/LocalUnit.test.ets
Normal file
33
base/src/test/LocalUnit.test.ets
Normal file
@@ -0,0 +1,33 @@
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function localUnitTest() {
|
||||
describe('localUnitTest',() => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
});
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user