From 3a574a408755ae292064b0a89cb5141822dc7fe6 Mon Sep 17 00:00:00 2001 From: ipuppet Date: Sat, 21 May 2022 14:53:23 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.json | 2 +- scripts/lib/easy-jsbox.js | 797 ++++++++++++++++++++++++-------------- 2 files changed, 512 insertions(+), 287 deletions(-) diff --git a/config.json b/config.json index 3ec8cd4..b5f6e4e 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "info": { "name": "WAIO", - "version": "1.6.4", + "version": "1.6.5", "author": "ipuppet", "module": false }, diff --git a/scripts/lib/easy-jsbox.js b/scripts/lib/easy-jsbox.js index 5c73793..7cd9169 100644 --- a/scripts/lib/easy-jsbox.js +++ b/scripts/lib/easy-jsbox.js @@ -1,4 +1,4 @@ -const VERSION = "1.2.1" +const VERSION = "1.2.2" String.prototype.trim = function (char, type) { if (char) { @@ -290,8 +290,9 @@ class UIKit { type: "canvas", props: props, layout: (make, view) => { - if (view.prev === undefined) return false - if (align === UIKit.align.bottom) { + if (view.prev === undefined) { + make.top.equalTo(view.super) + } else if (align === UIKit.align.bottom) { make.top.equalTo(view.prev.bottom) } else { make.top.equalTo(view.prev.top) @@ -731,158 +732,6 @@ class Sheet extends View { } } -class NavigationBar extends View { - static pageSheetNavigationBarHeight = 56 - - prefersLargeTitles = true - largeTitleFontSize = 34 - navigationBarTitleFontSize = 17 - addStatusBarHeight = true - contentViewHeightOffset = 10 - navigationBarNormalHeight = $objc("UINavigationController").invoke("alloc.init").$navigationBar().jsValue().frame.height - navigationBarLargeTitleHeight = $objc("UITabBarController").invoke("alloc.init").$tabBar().jsValue().frame.height + this.navigationBarNormalHeight - - pageSheetMode() { - this.navigationBarLargeTitleHeight -= this.navigationBarNormalHeight - this.navigationBarNormalHeight = NavigationBar.pageSheetNavigationBarHeight - this.navigationBarLargeTitleHeight += this.navigationBarNormalHeight - this.addStatusBarHeight = false - return this - } - - withStatusBarHeight() { - this.addStatusBarHeight = true - return this - } - - withoutStatusBarHeight() { - this.addStatusBarHeight = false - return this - } - - setNavigationItem(navigationItem) { - this.navigationItem = navigationItem - } - - setBackgroundColor(backgroundColor) { - this.backgroundColor = backgroundColor - return this - } - - setPrefersLargeTitles(bool) { - this.prefersLargeTitles = bool - return this - } - - setContentViewHeightOffset(offset) { - this.contentViewHeightOffset = offset - return this - } - - /** - * 页面大标题 - */ - getLargeTitleView() { - return this.prefersLargeTitles - && this.navigationItem.largeTitleDisplayMode !== NavigationItem.largeTitleDisplayModeNever - ? { - type: "label", - props: { - id: this.id + "-large-title", - text: this.navigationItem.title, - textColor: UIKit.textColor, - align: $align.left, - font: $font("bold", this.largeTitleFontSize), - line: 1 - }, - layout: (make, view) => { - make.left.equalTo(view.super.safeArea).offset(15) - make.height.equalTo(this.largeTitleFontSize + 5) - make.top.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) - } - } : {} - } - - getNavigationBarView() { - const getButtonView = (buttons, align) => { - return buttons.length > 0 ? { - type: "view", - views: [{ - type: "view", - views: buttons, - layout: $layout.fill - }], - layout: (make, view) => { - make.top.equalTo(view.super.safeAreaTop) - make.bottom.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) - if (align === UIKit.align.left) make.left.equalTo(view.super.safeArea).offset(5) - else make.right.equalTo(view.super.safeArea).offset(-5) - make.width.equalTo(buttons.length * BarButtonItem.size.width) - } - } : {} - } - const rightButtonView = getButtonView(this.navigationItem.rightButtons, UIKit.align.right) - const leftButtonView = this.navigationItem.popButtonView ?? getButtonView(this.navigationItem.leftButtons, UIKit.align.left) - const isHideBackground = this.prefersLargeTitles - const isHideTitle = !this.prefersLargeTitles || this.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever - return { // 顶部 bar - type: "view", - props: { - id: this.id + "-navigation", - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.left.top.right.inset(0) - make.bottom.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) - }, - views: [ - this.backgroundColor ? { - type: "view", - props: { - hidden: isHideBackground, - bgcolor: this.backgroundColor, - id: this.id + "-background" - }, - layout: $layout.fill - } : UIKit.blurBox({ - hidden: isHideBackground, - id: this.id + "-background" - }), - UIKit.separatorLine({ - id: this.id + "-underline", - alpha: isHideBackground ? 0 : 1 - }), - { - type: "view", - props: { - hidden: true, - bgcolor: $color("clear"), - id: this.id + "-large-title-mask" - }, - layout: $layout.fill - }, - { // 标题 - type: "label", - props: { - id: this.id + "-small-title", - alpha: isHideTitle ? 1 : 0, // 不显示大标题则显示小标题 - text: this.navigationItem.title, - font: $font("bold", this.navigationBarTitleFontSize), - align: $align.center, - bgcolor: $color("clear"), - textColor: UIKit.textColor - }, - layout: (make, view) => { - make.left.right.inset(0) - make.height.equalTo(20) - make.centerY.equalTo(view.super.safeArea) - } - } - ].concat(rightButtonView, leftButtonView) - } - } -} - /** * 用于创建一个靠右侧按钮(自动布局) * this.events.tapped 按钮点击事件,会传入三个函数,start()、done()和cancel() @@ -1064,6 +913,8 @@ class BarButtonItem extends View { class BarTitleView extends View { height = 20 + topOffset = 15 + bottomOffset = 10 controller = {} setController(controller) { @@ -1074,6 +925,8 @@ class BarTitleView extends View { class SearchBar extends BarTitleView { height = 35 + topOffset = 15 + bottomOffset = 10 kbType = $kbType.search placeholder = $l10n("SEARCH") @@ -1082,38 +935,47 @@ class SearchBar extends BarTitleView { this.setController(new SearchBarController()) this.controller.setSearchBar(this) - } - - setPlaceholder(placeholder) { - this.placeholder = placeholder - return this - } - setKbType(kbType) { - this.kbType = kbType - return this + this.init() } - getView() { - return { + init() { + this.props = { + id: this.id, + smoothCorners: true, + cornerRadius: 6, + bgcolor: $color("#EEF1F1", "#212121") + } + this.views = [{ type: "input", props: { - id: this.id, + id: this.id + "-input", type: this.kbType, + bgcolor: $color("clear"), placeholder: this.placeholder }, - layout: (make, view) => { - //make.top.equalTo(view.prev.bottom).offset(15) - make.top.equalTo(view.prev.bottom).offset(15) - make.left.equalTo(view.super.safeArea).offset(15) - make.right.equalTo(view.super.safeArea).offset(-15) - make.height.equalTo(this.height) - }, + layout: $layout.fill, events: { changed: sender => this.controller.callEvent("onChange", sender.text) } + }] + this.layout = (make, view) => { + make.height.equalTo(this.height) + make.top.equalTo(view.super.safeArea).offset(this.topOffset) + make.left.equalTo(view.super.safeArea).offset(15) + make.right.equalTo(view.super.safeArea).offset(-15) } } + + setPlaceholder(placeholder) { + this.placeholder = placeholder + return this + } + + setKbType(kbType) { + this.kbType = kbType + return this + } } class SearchBarController extends Controller { @@ -1124,42 +986,46 @@ class SearchBarController extends Controller { updateSelector() { this.selector = { - input: $(this.searchBar.id) + inputBox: $(this.searchBar.id), + input: $(this.searchBar.id + "-input") } } hide() { this.updateSelector() - this.selector.input.updateLayout(make => { + this.selector.inputBox.updateLayout(make => { make.height.equalTo(0) }) } show() { this.updateSelector() - this.selector.input.updateLayout(make => { + this.selector.inputBox.updateLayout(make => { make.height.equalTo(this.searchBar.height) }) } didScroll(contentOffset) { this.updateSelector() + // 调整大小 let height = this.searchBar.height - contentOffset height = height > 0 ? (height > this.searchBar.height ? this.searchBar.height : height) : 0 - this.selector.input.updateLayout(make => { + this.selector.inputBox.updateLayout(make => { make.height.equalTo(height) }) // 隐藏内容 if (contentOffset > 0) { - this.selector.input.placeholder = "" + const alpha = (this.searchBar.height / 2 - 5 - contentOffset) / 10 + this.selector.input.alpha = alpha } else { - this.selector.input.placeholder = this.searchBar.placeholder + this.selector.input.alpha = 1 } } didEndDragging(contentOffset, decelerate, scrollToOffset, zeroOffset) { this.updateSelector() + if ( contentOffset >= 0 && contentOffset <= this.searchBar.height @@ -1184,6 +1050,7 @@ class NavigationItem { hasbutton = false largeTitleDisplayMode = NavigationItem.largeTitleDisplayModeAutomatic largeTitleHeightOffset = 20 + isPinTitleView = false setTitle(title) { this.title = title @@ -1195,11 +1062,21 @@ class NavigationItem { return this } + pinTitleView() { + this.isPinTitleView = true + return this + } + setLargeTitleDisplayMode(mode) { this.largeTitleDisplayMode = mode return this } + setFixedFooterView(fixedFooterView) { + this.fixedFooterView = fixedFooterView + return this + } + setBackgroundColor(backgroundColor) { this.backgroundColor = backgroundColor return this @@ -1282,6 +1159,159 @@ class NavigationItem { } } +class NavigationBar extends View { + static pageSheetNavigationBarHeight = 56 + + prefersLargeTitles = true + largeTitleFontSize = 34 + largeTitleLabelHeightOffset = 5 + navigationBarTitleFontSize = 17 + addStatusBarHeight = true + contentViewHeightOffset = 10 + navigationBarNormalHeight = $objc("UINavigationController").invoke("alloc.init").$navigationBar().jsValue().frame.height + navigationBarLargeTitleHeight = $objc("UITabBarController").invoke("alloc.init").$tabBar().jsValue().frame.height + this.navigationBarNormalHeight + + pageSheetMode() { + this.navigationBarLargeTitleHeight -= this.navigationBarNormalHeight + this.navigationBarNormalHeight = NavigationBar.pageSheetNavigationBarHeight + this.navigationBarLargeTitleHeight += this.navigationBarNormalHeight + this.addStatusBarHeight = false + return this + } + + withStatusBarHeight() { + this.addStatusBarHeight = true + return this + } + + withoutStatusBarHeight() { + this.addStatusBarHeight = false + return this + } + + setNavigationItem(navigationItem) { + this.navigationItem = navigationItem + } + + setBackgroundColor(backgroundColor) { + this.backgroundColor = backgroundColor + return this + } + + setPrefersLargeTitles(bool) { + this.prefersLargeTitles = bool + return this + } + + setContentViewHeightOffset(offset) { + this.contentViewHeightOffset = offset + return this + } + + /** + * 页面大标题 + */ + getLargeTitleView() { + return this.prefersLargeTitles + && this.navigationItem.largeTitleDisplayMode !== NavigationItem.largeTitleDisplayModeNever + ? { + type: "label", + props: { + id: this.id + "-large-title", + text: this.navigationItem.title, + textColor: UIKit.textColor, + align: $align.left, + font: $font("bold", this.largeTitleFontSize), + line: 1 + }, + layout: (make, view) => { + make.left.equalTo(view.super.safeArea).offset(15) + make.height.equalTo(this.largeTitleFontSize + this.largeTitleLabelHeightOffset) + make.top.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) + } + } : {} + } + + getNavigationBarView() { + const getButtonView = (buttons, align) => { + return buttons.length > 0 ? { + type: "view", + views: [{ + type: "view", + views: buttons, + layout: $layout.fill + }], + layout: (make, view) => { + make.top.equalTo(view.super.safeAreaTop) + make.bottom.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) + if (align === UIKit.align.left) make.left.equalTo(view.super.safeArea).offset(5) + else make.right.equalTo(view.super.safeArea).offset(-5) + make.width.equalTo(buttons.length * BarButtonItem.size.width) + } + } : {} + } + const rightButtonView = getButtonView(this.navigationItem.rightButtons, UIKit.align.right) + const leftButtonView = this.navigationItem.popButtonView ?? getButtonView(this.navigationItem.leftButtons, UIKit.align.left) + const isHideBackground = this.prefersLargeTitles + const isHideTitle = !this.prefersLargeTitles || this.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever + return { // 顶部 bar + type: "view", + props: { + id: this.id + "-navigation", + bgcolor: $color("clear") + }, + layout: (make, view) => { + make.left.top.right.inset(0) + make.bottom.equalTo(view.super.safeAreaTop).offset(this.navigationBarNormalHeight) + }, + views: [ + this.backgroundColor ? { + type: "view", + props: { + hidden: isHideBackground, + bgcolor: this.backgroundColor, + id: this.id + "-background" + }, + layout: $layout.fill + } : UIKit.blurBox({ + hidden: isHideBackground, + id: this.id + "-background" + }), + UIKit.separatorLine({ + id: this.id + "-underline", + alpha: isHideBackground ? 0 : 1 + }), + { + type: "view", + props: { + hidden: true, + bgcolor: $color("clear"), + id: this.id + "-large-title-mask" + }, + layout: $layout.fill + }, + { // 标题 + type: "label", + props: { + id: this.id + "-small-title", + alpha: isHideTitle ? 1 : 0, // 不显示大标题则显示小标题 + text: this.navigationItem.title, + font: $font("bold", this.navigationBarTitleFontSize), + align: $align.center, + bgcolor: $color("clear"), + textColor: UIKit.textColor + }, + layout: (make, view) => { + make.left.right.inset(0) + make.height.equalTo(20) + make.centerY.equalTo(view.super.safeArea) + } + } + ].concat(rightButtonView, leftButtonView) + } + } +} + /** * events: * - onPop(navigationView) @@ -1291,16 +1321,19 @@ class NavigationController extends Controller { static largeTitleViewLargeMode = 1 navigationBar = new NavigationBar() - largeTitleScrollTrigger = this.navigationBar.largeTitleFontSize - 3 + largeTitleScrollTrigger = this.navigationBar.navigationBarNormalHeight updateSelector() { this.selector = { navigation: $(this.navigationBar.id + "-navigation"), largeTitleView: $(this.navigationBar.id + "-large-title"), smallTitleView: $(this.navigationBar.id + "-small-title"), - underlineView: $(this.navigationBar.id + "-underline"), + underlineView: this.navigationBar?.navigationItem?.isPinTitleView + ? $(this.navigationBar.id + "-title-view-underline") + : $(this.navigationBar.id + "-underline"), largeTitleMaskView: $(this.navigationBar.id + "-large-title-mask"), - backgroundView: $(this.navigationBar.id + "-background") + backgroundView: $(this.navigationBar.id + "-background"), + titleViewBackgroundView: $(this.navigationBar.id + "-title-view-background") } } @@ -1352,53 +1385,64 @@ class NavigationController extends Controller { #largeTitleScrollAction(contentOffset) { const titleSizeMax = 40 // 下拉放大字体最大值 + // 标题跟随 this.selector.largeTitleView.updateLayout((make, view) => { - make.top.equalTo(view.super.safeAreaTop).offset(this.navigationBar.navigationBarNormalHeight - contentOffset) + if (this.navigationBar.navigationBarNormalHeight - contentOffset > 0) { + // 标题上移致隐藏后停止移动 + make.top.equalTo(view.super.safeAreaTop).offset(this.navigationBar.navigationBarNormalHeight - contentOffset) + } else { + make.top.equalTo(view.super.safeAreaTop).offset(0) + } }) if (contentOffset > 0) { - if (contentOffset > this.largeTitleScrollTrigger) { + if (contentOffset >= this.largeTitleScrollTrigger) { this.#changeLargeTitleView(NavigationController.largeTitleViewSmallMode) } else { this.#changeLargeTitleView(NavigationController.largeTitleViewLargeMode) } - } else if (contentOffset < -20) { + } else { // 切换模式 this.#changeLargeTitleView(NavigationController.largeTitleViewLargeMode) - // 下拉放大字体 - let size = this.navigationBar.largeTitleFontSize - contentOffset * 0.04 - if (size > titleSizeMax) size = titleSizeMax - this.selector.largeTitleView.font = $font("bold", size) + if (contentOffset < -20) { + // 下拉放大字体 + let size = this.navigationBar.largeTitleFontSize - contentOffset * 0.04 + if (size > titleSizeMax) size = titleSizeMax + this.selector.largeTitleView.font = $font("bold", size) + } } } #navigationBarScrollAction(contentOffset) { - if (contentOffset > 0) { - let trigger = this.navigationBar.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever - ? 5 - : this.largeTitleScrollTrigger - if (contentOffset > trigger) { - // 隐藏遮罩 - this.selector.largeTitleMaskView.hidden = true - $ui.animate({ - duration: 0.2, - animation: () => { - // 显示下划线和背景 - this.selector.underlineView.alpha = 1 - this.selector.backgroundView.hidden = false - } - }) + if (this.navigationBar?.navigationItem?.isPinTitleView) { + // titleView 背景 + if (this.navigationBar.navigationBarNormalHeight - contentOffset > 0) { + this.selector.titleViewBackgroundView.hidden = true } else { - const contentViewBackgroundColor = this.selector.largeTitleView?.prev.bgcolor - this.selector.largeTitleMaskView.bgcolor = contentViewBackgroundColor - this.selector.largeTitleMaskView.hidden = false - // 隐藏背景 - this.selector.underlineView.alpha = 0 - this.selector.backgroundView.hidden = true + this.selector.titleViewBackgroundView.hidden = false } + } + + let trigger = this.navigationBar.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever + ? 5 + : this.largeTitleScrollTrigger + if (contentOffset > trigger) { + // 隐藏遮罩 + this.selector.largeTitleMaskView.hidden = true + $ui.animate({ + duration: 0.2, + animation: () => { + // 显示下划线和背景 + this.selector.underlineView.alpha = 1 + this.selector.backgroundView.hidden = false + } + }) } else { - // 隐藏背景 滑动过快时, contentOffset > 0 内的隐藏背景可能失效 + const contentViewBackgroundColor = this.selector.largeTitleView?.prev.bgcolor + this.selector.largeTitleMaskView.bgcolor = contentViewBackgroundColor + this.selector.largeTitleMaskView.hidden = false + // 隐藏背景 this.selector.underlineView.alpha = 0 this.selector.backgroundView.hidden = true } @@ -1406,18 +1450,24 @@ class NavigationController extends Controller { didScroll(contentOffset) { if (!this.navigationBar.prefersLargeTitles) return + const largeTitleDisplayMode = this.navigationBar?.navigationItem.largeTitleDisplayMode if (largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeAlways) return + this.updateSelector() + if (largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeAutomatic) { - // titleView didScroll - this.navigationBar?.navigationItem?.titleView?.controller.didScroll(contentOffset) - // 在 titleView 折叠前锁住主要视图 - if (contentOffset > 0) { - const height = this.navigationBar?.navigationItem?.titleView?.height ?? 0 - contentOffset -= height - if (contentOffset < 0) contentOffset = 0 + if (!this.navigationBar?.navigationItem?.isPinTitleView) { + // titleView didScroll + this.navigationBar?.navigationItem?.titleView?.controller.didScroll(contentOffset) + // 在 titleView 折叠前锁住主要视图 + if (contentOffset > 0) { + const height = this.navigationBar?.navigationItem?.titleView?.height ?? 0 + contentOffset -= height + if (contentOffset < 0) contentOffset = 0 + } } + this.#largeTitleScrollAction(contentOffset) this.#navigationBarScrollAction(contentOffset) } else if (largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever) { @@ -1425,19 +1475,21 @@ class NavigationController extends Controller { } } - didEndDragging(contentOffset, decelerate, scrollToOffset) { + didEndDragging(contentOffset, decelerate, scrollToOffset, zeroOffset) { if (!this.navigationBar.prefersLargeTitles) return const largeTitleDisplayMode = this.navigationBar?.navigationItem.largeTitleDisplayMode if (largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeAlways) return this.updateSelector() if (largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeAutomatic) { - // titleView didEndDragging - const zeroOffset = (!UIKit.isHorizontal || UIKit.isLargeScreen) && this.navigationBar.addStatusBarHeight - ? UIKit.statusBarHeight - : 0 - this.navigationBar?.navigationItem?.titleView?.controller.didEndDragging(contentOffset, decelerate, scrollToOffset, zeroOffset) - const titleViewHeight = this.navigationBar?.navigationItem?.titleView?.height ?? 0 - contentOffset -= titleViewHeight + let titleViewHeight = 0 + if (!this.navigationBar?.navigationItem?.isPinTitleView) { + // titleView didEndDragging + this.navigationBar?.navigationItem?.titleView?.controller.didEndDragging( + contentOffset, decelerate, scrollToOffset, zeroOffset + ) + titleViewHeight = this.navigationBar?.navigationItem?.titleView?.height ?? 0 + contentOffset -= titleViewHeight + } if ( contentOffset >= 0 && contentOffset <= this.navigationBar.largeTitleFontSize @@ -1453,6 +1505,32 @@ class NavigationController extends Controller { } } +class FixedFooterView extends View { + height = 60 + + getView() { + this.type = "view" + this.setProp("bgcolor", UIKit.primaryViewBackgroundColor) + this.layout = (make, view) => { + make.left.right.bottom.equalTo(view.super) + make.top.equalTo(view.super.safeAreaBottom).offset(-this.height) + } + + this.views = [ + View.create({ + props: this.props, + views: this.views, + layout: (make, view) => { + make.left.right.top.equalTo(view.super) + make.height.equalTo(this.height) + } + }) + ] + + return this + } +} + class PageView extends View { constructor(args = {}) { super(args) @@ -1534,18 +1612,47 @@ class PageController extends Controller { // 计算偏移高度 let height = this.navigationController.navigationBar.contentViewHeightOffset if (this.navigationItem.titleView) { + height += this.navigationItem.titleView.topOffset height += this.navigationItem.titleView.height + height += this.navigationItem.titleView.bottomOffset } - if (this.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever) { - height += this.navigationController.navigationBar.navigationBarNormalHeight + if (this.view.props.stickyHeader) { + height += this.navigationController.navigationBar.largeTitleFontSize + height += this.navigationController.navigationBar.largeTitleLabelHeightOffset } else { - height += this.navigationController.navigationBar.navigationBarLargeTitleHeight + if (this.navigationItem.largeTitleDisplayMode === NavigationItem.largeTitleDisplayModeNever) { + height += this.navigationController.navigationBar.navigationBarNormalHeight + } else { + height += this.navigationController.navigationBar.navigationBarLargeTitleHeight + } } // 修饰视图顶部偏移 - if (!this.view.props.header) this.view.props.header = {} - this.view.props.header.props = Object.assign(this.view.props.header.props ?? {}, { - height: height + if (this.view.props.header) { + this.view.props.header = { + type: "view", + props: { + height: height + (this.view.props.header?.props?.height ?? 0) + }, + views: [{ + type: "view", + props: { clipsToBounds: true }, + views: [this.view.props.header], + layout: (make, view) => { + make.top.inset(height) + make.height.equalTo(this.view.props.header?.props?.height ?? 0) + make.width.equalTo(view.super) + } + }] + } + } else { + this.view.props.header = { props: { height: height } } + } + + // 修饰视图底部偏移 + if (!this.view.props.footer) this.view.props.footer = {} + this.view.props.footer.props = Object.assign(this.view.props.footer.props ?? {}, { + height: (this.navigationItem.fixedFooterView?.height ?? 0) + (this.view.props.footer.props?.height ?? 0) }) // 重写布局 @@ -1558,6 +1665,9 @@ class PageController extends Controller { if (this.navigationItem.largeTitleDisplayMode !== NavigationItem.largeTitleDisplayModeNever) { topOffset += this.navigationController.navigationBar.largeTitleFontSize } + if (this.navigationItem.titleView) { + topOffset += this.navigationItem.titleView.topOffset + this.navigationItem.titleView.bottomOffset + } if ((!UIKit.isHorizontal || UIKit.isLargeScreen) && this.navigationController.navigationBar.addStatusBarHeight) { topOffset += UIKit.statusBarHeight } @@ -1565,41 +1675,71 @@ class PageController extends Controller { } } else { // indicatorInsets + const pinTitleViewOffset = this.navigationItem.isPinTitleView + ? this.navigationItem.titleView.height + + this.navigationItem.titleView.bottomOffset + + this.navigationController.navigationBar.contentViewHeightOffset + - this.navigationController.navigationBar.largeTitleLabelHeightOffset / 2 // 大标题中有额外空间用以完整显示 g y 等字符 + : 0 if (this.view.props.indicatorInsets) { const old = this.view.props.indicatorInsets this.view.props.indicatorInsets = $insets( - old.top + this.navigationController.navigationBar.navigationBarNormalHeight, + old.top + this.navigationController.navigationBar.navigationBarNormalHeight + pinTitleViewOffset, old.left, - old.bottom, + old.bottom + (this.navigationItem.fixedFooterView?.height ?? 0), old.right ) } else { - this.view.props.indicatorInsets = $insets(this.navigationController.navigationBar.navigationBarNormalHeight, 0, 0, 0) + this.view.props.indicatorInsets = $insets( + this.navigationController.navigationBar.navigationBarNormalHeight + pinTitleViewOffset, + 0, + this.navigationItem.fixedFooterView?.height ?? 0, + 0 + ) } // layout this.view.layout = (make, view) => { + if (this.view.props.stickyHeader) { + make.top.equalTo(view.super.safeArea).offset(this.navigationController.navigationBar.navigationBarNormalHeight) + } else { + make.top.equalTo(view.super) + } make.left.right.equalTo(view.super.safeArea) - make.top.bottom.equalTo(view.super) + make.bottom.equalTo(view.super) } // 重写滚动事件 this.view .assignEvent("didScroll", sender => { let contentOffset = sender.contentOffset.y - if ((!UIKit.isHorizontal || UIKit.isLargeScreen) && this.navigationController.navigationBar.addStatusBarHeight) { + if ( + (!UIKit.isHorizontal || UIKit.isLargeScreen) + && this.navigationController.navigationBar.addStatusBarHeight + && !this.view.props.stickyHeader + ) { contentOffset += UIKit.statusBarHeight } this.navigationController.didScroll(contentOffset) }) .assignEvent("didEndDragging", (sender, decelerate) => { let contentOffset = sender.contentOffset.y - if ((!UIKit.isHorizontal || UIKit.isLargeScreen) && this.navigationController.navigationBar.addStatusBarHeight) { + let zeroOffset = 0 + if ( + (!UIKit.isHorizontal || UIKit.isLargeScreen) + && this.navigationController.navigationBar.addStatusBarHeight + && !this.view.props.stickyHeader + ) { contentOffset += UIKit.statusBarHeight + zeroOffset = UIKit.statusBarHeight } - this.navigationController.didEndDragging(contentOffset, decelerate, (...args) => sender.scrollToOffset(...args)) + this.navigationController.didEndDragging( + contentOffset, decelerate, + (...args) => sender.scrollToOffset(...args), + zeroOffset + ) }) - .assignEvent("didEndDecelerating", (...args) => this.view.events?.didEndDragging(...args)) + .assignEvent("willBeginDecelerating", (...args) => this.view.events?.didEndDragging(...args)) } } @@ -1607,13 +1747,49 @@ class PageController extends Controller { if (this.navigationController.navigationBar.prefersLargeTitles) { this.bindScrollEvents() + let titleView = {} + if (this.navigationItem.titleView) { + // 修改 titleView 背景与 navigationBar 相同 + const isHideBackground = this.navigationController.navigationBar.prefersLargeTitles + titleView = View.create({ + views: [ + this.navigationController.navigationBar.backgroundColor ? { + type: "view", + props: { + hidden: isHideBackground, + bgcolor: this.navigationController.navigationBar.backgroundColor, + id: this.navigationController.navigationBar.id + "-title-view-background" + }, + layout: $layout.fill + } : UIKit.blurBox({ + hidden: isHideBackground, + id: this.navigationController.navigationBar.id + "-title-view-background" + }), + UIKit.separatorLine({ + id: this.navigationController.navigationBar.id + "-title-view-underline", + alpha: isHideBackground ? 0 : 1 + }), + this.navigationItem.titleView.definition + ], + layout: (make, view) => { + make.top.equalTo(view.prev.bottom) + make.width.equalTo(view.super) + make.height.equalTo( + this.navigationItem.titleView.topOffset + + this.navigationItem.titleView.height + + this.navigationItem.titleView.bottomOffset + ) + } + }) + } + // 初始化 PageView this.page = PageView.createByViews([ this.view, this.navigationController.navigationBar.getLargeTitleView(), - // titleView - this.navigationItem.titleView?.definition ?? {}, - this.navigationController.navigationBar.getNavigationBarView() + titleView, + this.navigationController.navigationBar.getNavigationBarView(), + this.navigationItem.fixedFooterView?.definition ?? {} ]) } else { this.page = PageView.createByViews([this.view]) @@ -1637,7 +1813,6 @@ class PageController extends Controller { class TabBarCellView extends View { constructor(args = {}) { super(args) - this.props.id = this.id this.setIcon(args.icon) this.setTitle(args.title) if (args.activeStatus !== undefined) { @@ -1705,7 +1880,33 @@ class TabBarCellView extends View { } } ] - return super.getView() + return this + } +} + +class TabBarHeaderView extends View { + height = 60 + + getView() { + this.type = "view" + this.setProp("bgcolor", this.props.bgcolor ?? UIKit.primaryViewBackgroundColor) + this.layout = (make, view) => { + make.left.right.bottom.equalTo(view.super) + make.top.equalTo(view.super.safeAreaBottom).offset(-this.height - TabBarController.tabBarHeight) + } + + this.views = [ + View.create({ + props: this.props, + views: this.views, + layout: (make, view) => { + make.left.right.top.equalTo(view.super) + make.height.equalTo(this.height) + } + }) + ] + + return this } } @@ -1714,6 +1915,7 @@ class TabBarController extends Controller { #pages = {} #cells = {} + #header #selected get selected() { @@ -1724,6 +1926,10 @@ class TabBarController extends Controller { this.switchPageTo(selected) } + get contentOffset() { + return TabBarController.tabBarHeight + (this.#header?.height ?? 0) + } + /** * * @param {Object} pages @@ -1790,6 +1996,11 @@ class TabBarController extends Controller { return this } + setHeader(view) { + this.#header = view + return this + } + #cellViews() { const views = [] Object.values(this.#cells).forEach(cell => { @@ -1816,23 +2027,22 @@ class TabBarController extends Controller { view.views[0].props.indicatorInsets = $insets( old.top, old.left, - old.bottom + TabBarController.tabBarHeight, + old.bottom + this.contentOffset, old.right ) } else { - view.views[0].props.indicatorInsets = $insets(0, 0, 0, TabBarController.tabBarHeight) + view.views[0].props.indicatorInsets = $insets(0, 0, 0, this.contentOffset) } // footer - if (view.views[0].props.footer) { - view.views[0].props.footer.height += TabBarController.tabBarHeight + if (view.views[0].footer === undefined) { + view.views[0].footer = { props: {} } + } else if (view.views[0].footer.props === undefined) { + view.views[0].footer.props = {} + } + if (view.views[0].props.footer.props.height) { + view.views[0].props.footer.props.height += this.contentOffset } else { - view.views[0].props.footer = Object.assign( - view.views[0].props.footer = { - props: { - height: TabBarController.tabBarHeight - } - } - ) + view.views[0].props.footer.props.height = this.contentOffset } } return view @@ -1845,7 +2055,7 @@ class TabBarController extends Controller { layout: (make, view) => { make.centerX.equalTo(view.super) make.width.equalTo(view.super) - make.top.equalTo(view.super.safeAreaBottom).offset(-50) + make.top.equalTo(view.super.safeAreaBottom).offset(-TabBarController.tabBarHeight) make.bottom.equalTo(view.super) }, views: [ @@ -1864,7 +2074,7 @@ class TabBarController extends Controller { UIKit.separatorLine({}, UIKit.align.top) ] } - return View.createByViews(this.#pageViews().concat(tabBarView)) + return View.createByViews(this.#pageViews().concat(this.#header?.definition ?? [], tabBarView)) } } @@ -1923,27 +2133,31 @@ class Kernel { } UIRender(view) { - view.props = Object.assign({ - title: this.title, - navBarHidden: !this.isUseJsboxNav, - navButtons: this.navButtons ?? [], - statusBarStyle: 0 - }, view.props) - if (!view.events) { - view.events = {} - } - const oldLayoutSubviews = view.events.layoutSubviews - view.events.layoutSubviews = () => { - $app.notify({ - name: "interfaceOrientationEvent", - object: { - statusBarOrientation: UIKit.statusBarOrientation, - isHorizontal: UIKit.isHorizontal - } - }) - if (typeof oldLayoutSubviews === "function") oldLayoutSubviews() + try { + view.props = Object.assign({ + title: this.title, + navBarHidden: !this.isUseJsboxNav, + navButtons: this.navButtons ?? [], + statusBarStyle: 0 + }, view.props) + if (!view.events) { + view.events = {} + } + const oldLayoutSubviews = view.events.layoutSubviews + view.events.layoutSubviews = () => { + $app.notify({ + name: "interfaceOrientationEvent", + object: { + statusBarOrientation: UIKit.statusBarOrientation, + isHorizontal: UIKit.isHorizontal + } + }) + if (typeof oldLayoutSubviews === "function") oldLayoutSubviews() + } + $ui.render(view) + } catch (error) { + this.print(error) } - $ui.render(view) } async checkUpdate(callback) { @@ -2025,6 +2239,19 @@ class FileStorage { }) } + exists(path = "", fileName) { + if (!fileName) { + throw new FileStorageParameterError("fileName") + } + path = this.#filePath(path, fileName) + + if ($file.exists(path)) { + return path + } + + return false + } + read(path = "", fileName) { if (!fileName) { throw new FileStorageParameterError("fileName") @@ -2100,7 +2327,7 @@ class FileStorage { } } - delete(path = "", fileName) { + delete(path = "", fileName = "") { return $file.delete(this.#filePath(path, fileName)) } } @@ -3248,9 +3475,7 @@ class Setting extends Controller { .addPopButton() .setLargeTitleDisplayMode(NavigationItem.largeTitleDisplayModeNever) if (this.hasSectionTitle(children)) { - pageController.navigationController.navigationBar.setContentViewHeightOffset(-5) - } else { - pageController.navigationController.navigationBar.setContentViewHeightOffset(30) + pageController.navigationController.navigationBar.setContentViewHeightOffset(-10) } this.viewController.push(pageController) } @@ -3433,9 +3658,7 @@ class Setting extends Controller { .navigationItem .setTitle($l10n("SETTING")) if (this.hasSectionTitle(this.structure)) { - pageController.navigationController.navigationBar.setContentViewHeightOffset(-5) - } else { - pageController.navigationController.navigationBar.setContentViewHeightOffset(30) + pageController.navigationController.navigationBar.setContentViewHeightOffset(-10) } this.viewController.setRootPageController(pageController) } @@ -3454,6 +3677,7 @@ module.exports = { Sheet, NavigationBar, BarButtonItem, + FixedFooterView, SearchBar, SearchBarController, NavigationItem, @@ -3461,6 +3685,7 @@ module.exports = { PageView, PageController, TabBarCellView, + TabBarHeaderView, TabBarController, Kernel, FileStorage, From 38274920b0ae123b08cf18184cc263f6c41922f3 Mon Sep 17 00:00:00 2001 From: ipuppet Date: Wed, 15 Jun 2022 11:41:54 +0800 Subject: [PATCH 2/3] update --- scripts/app.js | 2 +- scripts/{lib => libs}/easy-jsbox.js | 69 +++++++++++++++++++++++++++ scripts/{lib => libs}/sloarToLunar.js | 0 scripts/ui/home.js | 2 +- scripts/widget/Album/album.js | 2 +- scripts/widget/Album/setting.js | 2 +- scripts/widget/Calendar/calendar.js | 2 +- scripts/widget/setting.js | 2 +- scripts/widget/widget.js | 2 +- setting.json | 9 ---- strings/en.strings | 1 - strings/zh-Hans.strings | 1 - 12 files changed, 76 insertions(+), 18 deletions(-) rename scripts/{lib => libs}/easy-jsbox.js (98%) rename scripts/{lib => libs}/sloarToLunar.js (100%) diff --git a/scripts/app.js b/scripts/app.js index 83e88cd..e85ad1b 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -6,7 +6,7 @@ const { TabBarController, FileStorage, Setting -} = require("./lib/easy-jsbox") +} = require("./libs/easy-jsbox") const HomeUI = require("./ui/home") // path diff --git a/scripts/lib/easy-jsbox.js b/scripts/libs/easy-jsbox.js similarity index 98% rename from scripts/lib/easy-jsbox.js rename to scripts/libs/easy-jsbox.js index 7cd9169..5f5ff2a 100644 --- a/scripts/lib/easy-jsbox.js +++ b/scripts/libs/easy-jsbox.js @@ -2174,6 +2174,73 @@ class Kernel { } } +class UILoading { + #labelId + text = "" + interval + fullScreen = false + #loop = () => { } + + constructor() { + this.#labelId = uuid() + } + + updateText(text) { + $(this.#labelId).text = text + } + + setLoop(loop) { + if (typeof loop !== "function") { + throw "loop must be a function" + } + this.#loop = loop + } + + done() { + clearInterval(this.interval) + } + + load() { + $ui.render({ + props: { + navBarHidden: this.fullScreen + }, + views: [ + { + type: "spinner", + props: { + loading: true + }, + layout: (make, view) => { + make.centerY.equalTo(view.super).offset(-15) + make.width.equalTo(view.super) + } + }, + { + type: "label", + props: { + id: this.#labelId, + align: $align.center, + text: "" + }, + layout: (make, view) => { + make.top.equalTo(view.prev.bottom).offset(10) + make.left.right.equalTo(view.super) + } + } + ], + layout: $layout.fill, + events: { + appeared: () => { + this.interval = setInterval(() => { + this.#loop() + }, 100) + } + } + }) + } +} + class FileStorageParameterError extends Error { constructor(parameter) { super(`Parameter [${parameter}] is required.`) @@ -3671,6 +3738,7 @@ module.exports = { versionCompare, compressImage, // class + View, UIKit, ViewController, Matrix, @@ -3688,6 +3756,7 @@ module.exports = { TabBarHeaderView, TabBarController, Kernel, + UILoading, FileStorage, Setting } \ No newline at end of file diff --git a/scripts/lib/sloarToLunar.js b/scripts/libs/sloarToLunar.js similarity index 100% rename from scripts/lib/sloarToLunar.js rename to scripts/libs/sloarToLunar.js diff --git a/scripts/ui/home.js b/scripts/ui/home.js index b7ab9b3..f173a8d 100644 --- a/scripts/ui/home.js +++ b/scripts/ui/home.js @@ -3,7 +3,7 @@ const { ViewController, PageController, SearchBar -} = require("../lib/easy-jsbox") +} = require("../libs/easy-jsbox") class HomeUI { constructor(kernel) { diff --git a/scripts/widget/Album/album.js b/scripts/widget/Album/album.js index 63d39c7..5e82e0b 100644 --- a/scripts/widget/Album/album.js +++ b/scripts/widget/Album/album.js @@ -1,4 +1,4 @@ -const { UIKit } = require("../../lib/easy-jsbox") +const { UIKit } = require("../../libs/easy-jsbox") class Album { constructor(kernel, setting) { diff --git a/scripts/widget/Album/setting.js b/scripts/widget/Album/setting.js index 7e04e27..76729cb 100644 --- a/scripts/widget/Album/setting.js +++ b/scripts/widget/Album/setting.js @@ -1,7 +1,7 @@ const NAME = "Album" const BaseSetting = require("../setting") const Album = require("./album") -const { UIKit } = require("../../lib/easy-jsbox") +const { UIKit } = require("../../libs/easy-jsbox") class PictureSetting extends BaseSetting { constructor(kernel) { diff --git a/scripts/widget/Calendar/calendar.js b/scripts/widget/Calendar/calendar.js index ddbf4b7..75d8c64 100644 --- a/scripts/widget/Calendar/calendar.js +++ b/scripts/widget/Calendar/calendar.js @@ -1,4 +1,4 @@ -const { SloarToLunar } = require('../../lib/sloarToLunar') +const { SloarToLunar } = require('../../libs/sloarToLunar') const s2l = new SloarToLunar() diff --git a/scripts/widget/setting.js b/scripts/widget/setting.js index 3374b1d..0c05945 100644 --- a/scripts/widget/setting.js +++ b/scripts/widget/setting.js @@ -5,7 +5,7 @@ const { PageController, FileStorage, Setting -} = require("../lib/easy-jsbox") +} = require("../libs/easy-jsbox") class BaseSetting { constructor(kernel, widget) { diff --git a/scripts/widget/widget.js b/scripts/widget/widget.js index 0d99219..5f20056 100644 --- a/scripts/widget/widget.js +++ b/scripts/widget/widget.js @@ -17,7 +17,7 @@ class Widget { } printTimeConsuming() { - if (!this.kernel.inWidgetEnv && this.kernel.setting.get("debugMode")) + if (!this.kernel.inWidgetEnv) this.kernel.print(`Use ${Date.now() - this.startTime} ms`) } diff --git a/setting.json b/setting.json index aab79bb..f62b528 100644 --- a/setting.json +++ b/setting.json @@ -2,15 +2,6 @@ { "title": "GENERAL", "items": [ - { - "icon": [ - "clock.fill" - ], - "title": "DEBUG_MODE", - "type": "switch", - "key": "debugMode", - "value": false - }, { "icon": [ "arrow.2.circlepath", diff --git a/strings/en.strings b/strings/en.strings index 3a8ef62..45ff59d 100644 --- a/strings/en.strings +++ b/strings/en.strings @@ -23,7 +23,6 @@ "DELETE_SUCCESS" = "Delete success"; "DELETE_ERROR" = "Delete failed"; -"DEBUG_MODE" = "Debug Mode"; "UPDATE_HOME_SCREEN_WIDGET_OPTIONS" = "Update Home Screen Widget Options"; "BACKUP" = "Backup"; diff --git a/strings/zh-Hans.strings b/strings/zh-Hans.strings index 5676aed..5e51b6a 100644 --- a/strings/zh-Hans.strings +++ b/strings/zh-Hans.strings @@ -23,7 +23,6 @@ "DELETE_SUCCESS" = "删除成功"; "DELETE_ERROR" = "删除失败"; -"DEBUG_MODE" = "Debug模式"; "UPDATE_HOME_SCREEN_WIDGET_OPTIONS" = "更新主屏幕widget参数"; "BACKUP" = "备份"; From 38173036d9e735b28fc4d96941e24c3690c369e7 Mon Sep 17 00:00:00 2001 From: ipuppet Date: Wed, 15 Jun 2022 14:19:39 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=97=A5=E5=8E=86?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.json | 2 +- scripts/app.js | 1 + scripts/widget/Calendar/calendar.js | 221 ++++++++-------------------- scripts/widget/Calendar/index.js | 4 +- 4 files changed, 69 insertions(+), 159 deletions(-) diff --git a/config.json b/config.json index b5f6e4e..ae19a8c 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "info": { "name": "WAIO", - "version": "1.6.5", + "version": "1.6.6", "author": "ipuppet", "module": false }, diff --git a/scripts/app.js b/scripts/app.js index e85ad1b..cda83af 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -404,6 +404,7 @@ class Widget { module.exports = { run: () => { + //Widget.render("Calendar"); return if ($app.env === $env.widget) { Widget.render() } else if ($app.env === $env.app) { diff --git a/scripts/widget/Calendar/calendar.js b/scripts/widget/Calendar/calendar.js index 75d8c64..b94a775 100644 --- a/scripts/widget/Calendar/calendar.js +++ b/scripts/widget/Calendar/calendar.js @@ -185,7 +185,7 @@ class Calendar { } if (weekOnly) { // 是否只获取一周 if (date > dateNow) { // 当循环日期大于当前日期时,说明本周已经循环完毕 - calendar = week + calendar = [week] break } } @@ -264,56 +264,46 @@ class Calendar { /** * 复杂内容视图模板 * @param {*} props - * @param {*} family * @returns */ - multipleContentDayTemplate(props = {}, family) { - $widget.family = family - let lineHeight = Infinity - if (family === this.setting.family.small) { - lineHeight = ($widget.displaySize.height - 20) / 7 - } else if (family === this.setting.family.large) { - lineHeight = ($widget.displaySize.height - 20) / 13 - } + multipleContentDayTemplate(props = {}) { const views = [ { type: "text", props: Object.assign({ - font: $font(12), lineLimit: 1, - minimumScaleFactor: 0.5, frame: { - maxWidth: Infinity, - maxHeight: lineHeight + maxWidth: Infinity } }, props.text) }, { type: "text", props: Object.assign({ - font: $font(12), - minimumScaleFactor: 0.5, + minimumScaleFactor: 0.8, frame: { - maxWidth: Infinity, - maxHeight: lineHeight + maxWidth: Infinity } }, props.ext) } ] return { - type: "vstack", + type: "hgrid", + props: { + rows: Array(2).fill({ + flexible: { + maximum: Infinity + }, + spacing: 10 + }) + }, modifiers: [ Object.assign({ background: $color("clear"), color: $color("primaryText"), - spacing: 0, - padding: 2 + padding: 8, }, props.box), { - frame: { - maxWidth: Infinity, - maxHeight: Infinity - }, cornerRadius: 5 } ], @@ -381,35 +371,38 @@ class Calendar { * @returns */ singleContentDayTemplate(props = {}) { + const views = [{ + type: "text", + props: Object.assign({ + font: $font(13), + lineLimit: 1, + frame: { + maxWidth: Infinity, + maxHeight: Infinity + } + }, props.text) + }] return { - type: "vstack", + type: "hgrid", + props: { + rows: [{ + flexible: { + maximum: Infinity + }, + spacing: 0 + }] + }, modifiers: [ Object.assign({ background: $color("clear"), color: $color("primaryText"), - spacing: 0, - padding: 2 + padding: 3, }, props.box), { - frame: { - maxWidth: Infinity, - maxHeight: Infinity - }, cornerRadius: 5 } ], - views: [{ - type: "text", - props: Object.assign({ - font: $font(12), - lineLimit: 1, - minimumScaleFactor: 0.5, - frame: { - maxWidth: Infinity, - maxHeight: Infinity - } - }, props.text) - }] + views: views } } @@ -421,6 +414,7 @@ class Calendar { for (let i = 0; i < 7; i++) { title.push(this.singleContentDayTemplate({ text: { + font: $font(14), text: this.localizedWeek(i), color: this.colorTone } @@ -431,14 +425,12 @@ class Calendar { /** * 标题模板 - * @param {*} family * @param {*} calendarInfo * @returns */ - titleBarTemplate(family, calendarInfo) { + titleBarTemplate(calendarInfo) { // 标题栏文字内容 - let leftText, views = [], - size = family === this.setting.family.small ? 12 : 18 + let leftText, views = [] if (this.titleYearMode !== 0) { const year = this.titleYearMode === 1 ? String(calendarInfo.year).slice(-2) : calendarInfo.year leftText = year + this.localizedMonth(calendarInfo.month) @@ -452,7 +444,7 @@ class Calendar { text: leftText, lineLimit: 1, color: this.colorTone, - font: $font("bold", size), + bold: true, frame: { alignment: $widget.alignment.leading, maxWidth: Infinity, @@ -469,7 +461,7 @@ class Calendar { text: rightText, lineLimit: 1, color: this.colorTone, - font: $font("bold", size), + bold: true, frame: { alignment: $widget.alignment.trailing, maxWidth: Infinity, @@ -484,42 +476,31 @@ class Calendar { frame: { maxWidth: Infinity, maxHeight: Infinity - }, - padding: (() => { - switch (family) { - case this.setting.family.small: - return $insets(0, 3, 0, 3) - case this.setting.family.meduim: - return $insets(0, 10, 0, 10) - case this.setting.family.large: - return $insets(0, 10, 0, 10) - } - })() + } }, views: views } } - smallCalendarView() { - const calendarInfo = this.getCalendar(false) + calendarTemplate(calendarInfo, dayStyleModifier, dayTemplate, vSpacing = 5) { const days = [] for (let line of calendarInfo.calendar) { // 设置不同日期显示不同样式 for (let dayInfo of line) { - const props = this.singleContentDayStyleModifier(dayInfo, calendarInfo) - days.push(this.singleContentDayTemplate(props)) + const props = dayStyleModifier(dayInfo, calendarInfo) + days.push(dayTemplate(props)) } } + const calendar = { type: "vgrid", props: { columns: Array(7).fill({ flexible: { - minimum: 0, maximum: Infinity }, spacing: 0 }), - spacing: 0, + spacing: vSpacing, frame: { maxWidth: Infinity, maxHeight: Infinity @@ -527,7 +508,8 @@ class Calendar { }, views: this.weekIndexTemplate().concat(days) } - const titleBar = this.titleBarTemplate(this.setting.family.small, calendarInfo) + const titleBar = this.titleBarTemplate(calendarInfo) + return { type: "vstack", props: { @@ -549,96 +531,23 @@ class Calendar { } } - weekView() { - const calendarInfo = this.getCalendar(true, true) - const days = [] - for (let dayInfo of calendarInfo.calendar) { - const props = this.multipleContentDayStyleModifier(dayInfo, calendarInfo) - days.push(this.multipleContentDayTemplate(props, this.setting.family.meduim)) - } - const calendar = { - type: "vgrid", - props: { - columns: Array(7).fill({ - flexible: { - minimum: 0, - maximum: Infinity - }, - spacing: 0 - }), - spacing: 5, - frame: { - maxWidth: Infinity, - maxHeight: Infinity - }, - padding: $insets(0, 3, 0, 3) - }, - views: this.weekIndexTemplate().concat(days) - } - const titleBar = this.titleBarTemplate(this.setting.family.meduim, calendarInfo) - return { - type: "vstack", - props: { - background: this.getBackground(), - frame: { - maxWidth: Infinity, - maxHeight: Infinity - }, - spacing: 0, - padding: 10, - widgetURL: this.setting.settingUrlScheme, - link: this.setting.settingUrlScheme - }, - views: [{ type: "spacer" }, titleBar, { type: "spacer" }, calendar, { type: "spacer" }] - } + smallCalendarView() { + const calendarInfo = this.getCalendar(false) + return this.calendarTemplate( + calendarInfo, + (dayInfo, calendarInfo) => this.singleContentDayStyleModifier(dayInfo, calendarInfo), + props => this.singleContentDayTemplate(props), + 0 + ) } - largeCalendarView() { - const calendarInfo = this.getCalendar(true) - const days = [] - for (let line of calendarInfo.calendar) { // 设置不同日期显示不同样式 - for (let dayInfo of line) { - const props = this.multipleContentDayStyleModifier(dayInfo, calendarInfo) - days.push(this.multipleContentDayTemplate(props)) - } - } - const calendar = { - type: "vgrid", - props: { - columns: Array(7).fill({ - flexible: { - minimum: 0, - maximum: Infinity - }, - spacing: 0 - }), - spacing: 0, - frame: { - maxWidth: Infinity, - maxHeight: Infinity - } - }, - views: this.weekIndexTemplate().concat(days) - } - const titleBar = this.titleBarTemplate(this.setting.family.large, calendarInfo) - return { - type: "vstack", - props: { - background: this.getBackground(), - frame: { - maxWidth: Infinity, - maxHeight: Infinity - }, - spacing: 0, - padding: 10, - widgetURL: this.setting.settingUrlScheme - }, - views: this.titleAddSpacer ? [ - { type: "spacer" }, titleBar, { type: "spacer" }, calendar, { type: "spacer" } - ] : [ - { type: "spacer" }, titleBar, calendar, { type: "spacer" } - ] - } + calendarView(family) { + const calendarInfo = this.getCalendar(true, family === this.setting.family.medium) + return this.calendarTemplate( + calendarInfo, + (dayInfo, calendarInfo) => this.multipleContentDayStyleModifier(dayInfo, calendarInfo), + props => this.multipleContentDayTemplate(props) + ) } } diff --git a/scripts/widget/Calendar/index.js b/scripts/widget/Calendar/index.js index 58f287d..f43b3bf 100644 --- a/scripts/widget/Calendar/index.js +++ b/scripts/widget/Calendar/index.js @@ -15,11 +15,11 @@ class CalendarWidget extends Widget { } view2x4() { - return this.calendar.weekView() + return this.calendar.calendarView(this.setting.family.medium) } view4x4() { - return this.calendar.largeCalendarView() + return this.calendar.calendarView(this.setting.family.large) } render() {