From 49c1a70bb1013e5a04f9b9b3c0786858fee755b6 Mon Sep 17 00:00:00 2001 From: "Gpound.liu" <141617023+Gggpound@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:57:04 +0800 Subject: [PATCH] feat(user): add user model (#2137) --- packages/core/src/index.ts | 1 + .../user-manager/user-manager.service.ts | 49 +++++++++++++++++++ packages/core/src/univer.ts | 2 + .../conditional-formatting.service.ts | 12 +++-- 4 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 packages/core/src/services/user-manager/user-manager.service.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 7335aec1a83..8dbf74e7df3 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -114,6 +114,7 @@ export { } from './services/undoredo/undoredo.service'; export * from './shared'; export { fromCallback } from './shared/rxjs'; +export { UserManagerService } from './services/user-manager/user-manager.service'; // #region sheet diff --git a/packages/core/src/services/user-manager/user-manager.service.ts b/packages/core/src/services/user-manager/user-manager.service.ts new file mode 100644 index 00000000000..a8d132a8a7a --- /dev/null +++ b/packages/core/src/services/user-manager/user-manager.service.ts @@ -0,0 +1,49 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { IUser } from '@univerjs/protocol'; +import { Subject } from 'rxjs'; + + +export class UserManagerService { + private _model = new Map(); + private _userChange$ = new Subject<{ type: 'add' | 'delete'; user: IUser } | { type: 'clear' }>(); + public userChange$ = this._userChange$.asObservable(); + + addUser(user: IUser) { + this._model.set(user.userID, user); + this._userChange$.next({ type: 'add', user }); + } + + getUser(userId: string, callBack?: () => void) { + const user = this._model.get(userId); + if (user) { + return user; + } + callBack && callBack(); + } + + delete(userId: string) { + const user = this.getUser(userId); + this._model.delete(userId); + user && this._userChange$.next({ type: 'delete', user }); + } + + clear() { + this._model.clear(); + this._userChange$.next({ type: 'clear' }); + } +} diff --git a/packages/core/src/univer.ts b/packages/core/src/univer.ts index a9ce1e2b460..cac072aecc0 100644 --- a/packages/core/src/univer.ts +++ b/packages/core/src/univer.ts @@ -49,6 +49,7 @@ import { PluginService } from './services/plugin/plugin.service'; import type { Plugin, PluginCtor } from './services/plugin/plugin'; import type { DependencyOverride } from './services/plugin/plugin-override'; import { mergeOverrideWithDependencies } from './services/plugin/plugin-override'; +import { UserManagerService } from './services/user-manager/user-manager.service'; export class Univer { private _startedTypes = new Set(); @@ -170,6 +171,7 @@ function createUniverInjector(parentInjector?: Injector, override?: DependencyOv [LifecycleInitializerService], [UniverPermissionService], [PluginService], + [UserManagerService], // abstract services [IUniverInstanceService, { useClass: UniverInstanceService }], diff --git a/packages/sheets-conditional-formatting/src/services/conditional-formatting.service.ts b/packages/sheets-conditional-formatting/src/services/conditional-formatting.service.ts index 63e7c0ff750..4c3adcc08a7 100644 --- a/packages/sheets-conditional-formatting/src/services/conditional-formatting.service.ts +++ b/packages/sheets-conditional-formatting/src/services/conditional-formatting.service.ts @@ -42,9 +42,8 @@ interface IComputeCache { status: ComputeStatus }; const beforeUpdateRuleResult = createInterceptorKey<{ subUnitId: string; unitId: string; cfId: string }, undefined>('conditional-formatting-before-update-rule-result'); @OnLifecycle(LifecycleStages.Starting, ConditionalFormattingService) export class ConditionalFormattingService extends Disposable { - // >> - private _afterInitApplyPromise: Promise; + // >> private _ruleCacheMap: Map>> = new Map(); private _ruleComputeStatus$: Subject<{ status: ComputeStatus; result?: ObjectMatrix; unitId: string; subUnitId: string; cfId: string }> = new Subject(); @@ -372,19 +371,22 @@ export class ConditionalFormattingService extends Disposable { result.forValue((row, col, value) => { this._conditionalFormattingViewModel.setCellCfRuleCache(unitId, subUnitId, row, col, cfId, value); }); - this._deleteComputeCache(unitId, subUnitId, cfId); } })); } private async _handleCalculateUnit(unitId: string, subUnitId: string, rule: IConditionFormattingRule) { + await this._afterInitApplyPromise; + // We need to perform a secondary verification, as the rule may have been deleted after initApply. + if (!this._conditionalFormattingRuleModel.getRule(unitId, subUnitId, rule.cfId)) { + return; + } const workbook = this._univerInstanceService.getUnit(unitId); const worksheet = workbook?.getSheetBySheetId(subUnitId); let cache = this._getComputedCache(unitId, subUnitId, rule.cfId); - if (cache && cache.status === 'computing') { + if (cache && ['computing', 'end'].includes(cache.status)) { return; } - await this._afterInitApplyPromise; if (!cache) { cache = { status: 'computing' }; this._setComputedCache(unitId, subUnitId, rule.cfId, cache);