/* * 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. */ #include "frameworks/bridge/declarative_frontend/jsview/js_refresh.h" #include #include "base/log/ace_scoring_log.h" #include "bridge/declarative_frontend/jsview/js_view_common_def.h" #include "bridge/declarative_frontend/jsview/models/refresh_model_impl.h" #include "core/components/refresh/refresh_theme.h" #include "core/components_ng/pattern/refresh/refresh_model_ng.h" namespace OHOS::Ace { namespace { constexpr int32_t DEFAULT_FRICTION = 62; constexpr int32_t MAX_FRICTION = 100; } // namespace std::unique_ptr RefreshModel::instance_ = nullptr; RefreshModel* RefreshModel::GetInstance() { if (!instance_) { #ifdef NG_BUILD instance_.reset(new NG::RefreshModelNG()); #else if (Container::IsCurrentUseNewPipeline()) { instance_.reset(new NG::RefreshModelNG()); } else { instance_.reset(new Framework::RefreshModelImpl()); } #endif } return instance_.get(); } } // namespace OHOS::Ace namespace OHOS::Ace::Framework { void ParseRefreshingObject(const JSCallbackInfo& info, const JSRef& refreshing) { JSRef changeEventVal = refreshing->GetProperty("changeEvent"); CHECK_NULL_VOID(changeEventVal->IsFunction()); auto jsFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(changeEventVal)); auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); if (param != "true" && param != "false") { LOGE("param is not equal true or false, invalid."); return; } bool newValue = StringToBool(param); ACE_SCORING_EVENT("Refresh.ChangeEvent"); auto newJSVal = JSRef::Make(ToJSValue(newValue)); func->ExecuteJS(1, &newJSVal); }; RefreshModel::GetInstance()->SetChangeEvent(std::move(changeEvent)); } void JSRefresh::JSBind(BindingTarget globalObj) { JSClass::Declare("Refresh"); MethodOptions opt = MethodOptions::NONE; JSClass::StaticMethod("create", &JSRefresh::Create, opt); JSClass::StaticMethod("pop", &JSRefresh::Pop); JSClass::StaticMethod("onStateChange", &JSRefresh::OnStateChange); JSClass::StaticMethod("onRefreshing", &JSRefresh::OnRefreshing); JSClass::StaticMethod("onAppear", &JSInteractableView::JsOnAppear); JSClass::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear); JSClass::Inherit(); JSClass::Bind(globalObj); } void JSRefresh::Create(const JSCallbackInfo& info) { if (info.Length() < 1 || !info[0]->IsObject()) { LOGE("refresh create error, info is non-valid"); return; } RefPtr theme = GetTheme(); if (!theme) { LOGE("Refresh Theme is null"); return; } auto paramObject = JSRef::Cast(info[0]); auto refreshing = paramObject->GetProperty("refreshing"); auto jsOffset = paramObject->GetProperty("offset"); auto friction = paramObject->GetProperty("friction"); RefreshModel::GetInstance()->Create(); RefreshModel::GetInstance()->SetLoadingDistance(theme->GetLoadingDistance()); RefreshModel::GetInstance()->SetRefreshDistance(theme->GetRefreshDistance()); RefreshModel::GetInstance()->SetProgressDistance(theme->GetProgressDistance()); RefreshModel::GetInstance()->SetProgressDiameter(theme->GetProgressDiameter()); RefreshModel::GetInstance()->SetMaxDistance(theme->GetMaxDistance()); RefreshModel::GetInstance()->SetShowTimeDistance(theme->GetShowTimeDistance()); RefreshModel::GetInstance()->SetTextStyle(theme->GetTextStyle()); RefreshModel::GetInstance()->SetProgressColor(theme->GetProgressColor()); RefreshModel::GetInstance()->SetProgressBackgroundColor(theme->GetBackgroundColor()); if (refreshing->IsBoolean()) { RefreshModel::GetInstance()->SetRefreshing(refreshing->ToBoolean()); } else { JSRef refreshingObj = JSRef::Cast(refreshing); ParseRefreshingObject(info, refreshingObj); RefreshModel::GetInstance()->SetRefreshing(refreshingObj->GetProperty("value")->ToBoolean()); } Dimension offset; if (ParseJsDimensionVp(jsOffset, offset)) { if (LessNotEqual(offset.Value(), 0.0) || offset.Unit() == DimensionUnit::PERCENT) { RefreshModel::GetInstance()->SetRefreshDistance(theme->GetRefreshDistance()); } else { RefreshModel::GetInstance()->SetUseOffset(true); RefreshModel::GetInstance()->SetIndicatorOffset(offset); } } if (friction->IsNumber()) { auto frictionNumber = friction->ToNumber(); if (frictionNumber < 0 || frictionNumber > MAX_FRICTION) { frictionNumber = DEFAULT_FRICTION; } RefreshModel::GetInstance()->SetFriction(frictionNumber); if (friction->ToNumber() <= 0) { RefreshModel::GetInstance()->IsRefresh(true); } } } void JSRefresh::Pop() { RefreshModel::GetInstance()->Pop(); } void JSRefresh::OnStateChange(const JSCallbackInfo& args) { auto jsFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(args[0])); auto onStateChange = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const int32_t& value) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("Refresh.OnStateChange"); auto newJSVal = JSRef::Make(ToJSValue(value)); func->ExecuteJS(1, &newJSVal); }; RefreshModel::GetInstance()->SetOnStateChange(std::move(onStateChange)); } void JSRefresh::OnRefreshing(const JSCallbackInfo& args) { auto jsFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(args[0])); auto onRefreshing = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("Refresh.OnRefreshing"); auto newJSVal = JSRef::Make(); func->ExecuteJS(1, &newJSVal); }; RefreshModel::GetInstance()->SetOnRefreshing(std::move(onRefreshing)); } } // namespace OHOS::Ace::Framework