diff --git a/README.en.md b/README.en.md
index a207e899e041b565c587c9676023409c3bdb467d..894d6d8afa71323707a6ab50ded444ba5ed101ae 100644
--- a/README.en.md
+++ b/README.en.md
@@ -6,9 +6,9 @@ This sample describes three typical scenarios of ArkUI component encapsulation:
### Preview
-| Home page | Common component | Dialog component | Component factory |
-|-------------------------------------------------------|-----------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
-|
|
|
|
|
+| Home page | Attribute Style | Common component | Dialog component | Component factory |
+|-------------------------------------------------------|-------------------------------------------------------|-----------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
+|
|
|
|
|
|
### How to Use
@@ -27,6 +27,7 @@ On the home page, tap the corresponding button to access the page for common com
│ │ ├──GetResourceString.ets // Resource-to-string conversion function
│ │ └──PopViewUtils.ets // Custom pop-up window
│ ├──pages
+│ │ ├──AttributeStylePage.ets // Attribute Style
│ │ ├──CommonComponent.ets // Common component
│ │ ├──ComponentFactory.ets // Component factory
│ │ ├──DialogComponent.ets // Dialog component
diff --git a/README.md b/README.md
index d2f784a75dafd1a3f2b168a5bb9c5642204a5cbb..04c217c9648c70afe16562b8d466de6a0c1527b5 100644
--- a/README.md
+++ b/README.md
@@ -2,17 +2,17 @@
### 介绍
-本示例通过系统组件的attributeModifier属性、PromptAction对象、wrapBuilder函数,实现公共组件的封装、弹窗组件的封装、全局@Builder。帮助开发者掌握如何优化重复性的组件、布局,使代码简洁,易维护。
+本示例通过系统组件的attributeModifier属性、PromptAction对象、wrapBuilder函数等,实现组件公共样式封装、自定义组件的封装、弹窗组件的封装、全局@Builder。帮助开发者掌握如何优化重复性的组件、布局,使代码简洁,易维护。
### 效果图预览
-| 首页 | 公用组件封装场景 | 弹窗组件封装场景 | 组件工厂类封装场景 |
-|----------------------------------------|-----------------------------------------|-----------------------------------------|------------------------------------------|
-|  |  |  |  |
+| 首页 | 组件公共样式封装 | 自定义组件封装场景 | 组件工厂类封装场景 | 弹窗组件封装场景 |
+|----------------------------------------------------|----------------------------------------|-----------------------------------------|------------------------------------------|-----------------------------------------|
+|
|
|  |  |  |
##### 使用说明
-进入首面,会看到公用组件封装、弹窗组件封装和组件工厂类封装三个按钮,点击按钮会进入对应的封装场景实现的页面,查看效果。
+进入首面,会看到各封装场景的按钮,点击按钮会进入对应的封装场景实现的页面,查看效果。
### 工程目录
@@ -27,7 +27,8 @@
│ │ ├──GetResourceString.ets // Resource转换String函数
│ │ └──PopViewUtils.ets // 自定义弹窗类
│ ├──pages
-│ │ ├──CommonComponent.ets // 公共组件封装
+│ │ ├──AttributeStylePage.ets // 组件公共样式封装
+│ │ ├──CommonComponent.ets // 自定义组件封装
│ │ ├──ComponentFactory.ets // 组件工厂类封装
│ │ ├──DialogComponent.ets // 弹窗组件封装
│ │ └──Index.ets // 首页
@@ -39,7 +40,7 @@
### 具体实现
-1. 公用组件封装:系统组件提供了attributeModifier属性方法,通过自定义Class类实现AttributeModifier接口对系统组件属性进行扩展。
+1. 自定义组件封装:系统组件提供了attributeModifier属性方法,通过自定义Class类实现AttributeModifier接口对系统组件属性进行扩展。
2. 弹窗组件封装:通过使用UIContext中获取到的PromptAction对象来实现自定义弹窗封装,使用PromptAction对象中openCustomDialog接口打开弹窗,closeCustomDialog接口关闭弹窗。
diff --git a/entry/src/main/ets/model/AttributeModifier.ets b/entry/src/main/ets/model/AttributeModifier.ets
deleted file mode 100644
index 51c59c911e77b587ae02c188026f02210c289d0e..0000000000000000000000000000000000000000
--- a/entry/src/main/ets/model/AttributeModifier.ets
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2024 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 { MyButton } from '../pages/CommonComponent';
-
-// [Start image_modifier]
-// The AttributeModifier interface implementation class for the Image component.
-export class ImageModifier implements AttributeModifier {
- private imageWidth: Length = 0;
- private imageHeight: Length = 0;
-
- constructor(width: Length, height: Length) {
- this.imageWidth = width;
- this.imageHeight = height;
- }
-
- width(width: Length) {
- this.imageWidth = width;
- return this;
- }
-
- height(height: Length) {
- this.imageHeight = height;
- return this;
- }
-
- applyNormalAttribute(instance: ImageAttribute): void {
- instance.width(this.imageWidth);
- instance.height(this.imageHeight);
- instance.borderRadius($r('app.float.padding_l'))
- }
-}
-
-// Text component's AttributeModifier interface implementation class.
-export class TextModifier implements AttributeModifier {
- constructor() {
- }
-
- applyNormalAttribute(instance: TextAttribute): void {
- instance.fontSize($r('app.float.font_size_l'));
- }
-}
-// [End image_modifier]
-
-// [Start my_button_modifier]
-// src/main/ets/model/AttributeModifier.ets
-// The client implements the AttributeModifier interface with custom class.
-class MyButtonModifier implements AttributeModifier {
- // Define private properties specific to the Button component
- private stateEffectValue: boolean = false;
- private buttonType: ButtonType = ButtonType.Normal;
-
- constructor() {
- }
- // The system provides styling methods for components in their normal state, along with additional methods for hover and other states.
- applyNormalAttribute(instance: ButtonAttribute): void {
- instance.stateEffect(this.stateEffectValue);
- instance.type(this.buttonType);
- }
-
- stateEffect(enable: boolean): MyButtonModifier {
- this.stateEffectValue = enable
- return this;
- }
- // Custom attribute names align with system component property names to ensure consistency during chained calls.
- type(buttonType: ButtonType): MyButtonModifier {
- this.buttonType = buttonType;
- return this;
- }
-}
-
-//The user utilizes the provider's public component MyButton.
-@Component
-struct Index {
- capsuleButtonModifier: MyButtonModifier = new MyButtonModifier().stateEffect(true).type(ButtonType.Capsule)
- circleButtonModifier: MyButtonModifier = new MyButtonModifier().stateEffect(true).type(ButtonType.Circle)
- build() {
- Row() {
- MyButton({ modifier: this.capsuleButtonModifier, text: 'Capsule Button' })
- .margin({ right: 20 })
- MyButton({ modifier: this.circleButtonModifier, text: 'Circle Button' })
- }
- .justifyContent(FlexAlign.Center)
- .width('100%')
- .height('100%')
- }
-}
-// [End my_button_modifier]
\ No newline at end of file
diff --git a/entry/src/main/ets/model/PopViewUtils.ets b/entry/src/main/ets/model/PopViewUtils.ets
index a69602761e6ba44929034efd799a0f750ebd1159..f67b140bcb099fd4ec7dcfcbd3fa26cdccda7037 100644
--- a/entry/src/main/ets/model/PopViewUtils.ets
+++ b/entry/src/main/ets/model/PopViewUtils.ets
@@ -71,7 +71,7 @@ export class PopViewUtils {
return model.popType === type;
})
let info = sameTypeList[sameTypeList.length - 1];
- if (info.com) {
+ if (info && info.com) {
PopViewUtils.shareInstance().infoList = PopViewUtils.shareInstance().infoList.filter((model) => {
return model.com !== info.com;
})
diff --git a/entry/src/main/ets/pages/AttributeStylePage.ets b/entry/src/main/ets/pages/AttributeStylePage.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4399d5d53f789a6f967eed6a9b462c7194ccacfe
--- /dev/null
+++ b/entry/src/main/ets/pages/AttributeStylePage.ets
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2024 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 { getResourceString } from "../model/GetResourceString";
+
+// [Start my_button_modifier1]
+// src/main/ets/pages/CommonComponent.ets
+// The provider creates a custom Class that implements the system's AttributeModifier interface.
+export class MyButtonModifier implements AttributeModifier {
+ private buttonType: ButtonType = ButtonType.Normal;
+
+ constructor() {
+ }
+
+ applyNormalAttribute(instance: ButtonAttribute): void {
+ instance.type(this.buttonType);
+ instance.width(200);
+ instance.height(50);
+ instance.fontSize(20);
+ instance.fontColor('#0A59F7')
+ instance.backgroundColor('#0D000000')
+ }
+
+ applyPressedAttribute(instance: ButtonAttribute): void {
+ instance.fontColor('#0A59F7')
+ instance.backgroundColor('#26000000')
+ }
+
+ type(type: ButtonType): MyButtonModifier {
+ this.buttonType = type;
+ return this;
+ }
+}
+// [End my_button_modifier1]
+
+@Builder
+export function AttributeStylePageBuilder() {
+ AttributeStylePage()
+}
+
+// [Start use_modifier]
+@Entry
+@Component
+struct AttributeStylePage {
+ modifier = new MyButtonModifier()
+ .type(ButtonType.Capsule)
+
+ build() {
+ NavDestination() {
+ Column() {
+ Button('Capsule Button')
+ .attributeModifier(this.modifier)
+ }
+ .margin({ top: $r('app.float.margin_top') })
+ .justifyContent(FlexAlign.Start)
+ .alignItems(HorizontalAlign.Center)
+ .width('100%')
+ .height('100%')
+ }
+ .title(getResourceString($r('app.string.common_style_extract'), this))
+ }
+}
+// [End use_modifier]
\ No newline at end of file
diff --git a/entry/src/main/ets/pages/CommonComponent.ets b/entry/src/main/ets/pages/CommonComponent.ets
index cf194370d4fd3c33ff8e3816595b03610f894a7f..2d0b16cd9e3d02c01afa4f78b2a75d378372b959 100644
--- a/entry/src/main/ets/pages/CommonComponent.ets
+++ b/entry/src/main/ets/pages/CommonComponent.ets
@@ -12,10 +12,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { CommonConstants } from '../common/CommonConstants';
-import { ImageModifier, TextModifier } from '../model/AttributeModifier';
+
import { getResourceString } from '../model/GetResourceString';
-import { CustomImageText } from '../view/CustomImageText';
+import { CustomImageModifier, CustomImageText } from '../view/CustomImageText';
@Builder
export function CommonComponentBuilder() {
@@ -26,17 +25,18 @@ export function CommonComponentBuilder() {
// [Start common_component1]
@Component
struct CommonComponent {
- imageAttribute: ImageModifier = new ImageModifier(330, 330);
- textAttribute: TextModifier = new TextModifier();
+ imageAttribute: CustomImageModifier = new CustomImageModifier(330, 330);
build() {
NavDestination() {
Column() {
CustomImageText({
imageAttribute: this.imageAttribute,
- textAttribute: this.textAttribute,
imageSrc: $r('app.media.image'),
- text: 'Scenery'
+ text: 'Scenery',
+ onClickEvent: () => {
+ this.getUIContext().getPromptAction().showToast({ message: 'Clicked' })
+ }
})
}
.margin({ top: $r('app.float.margin_top') })
@@ -49,72 +49,3 @@ struct CommonComponent {
}
}
// [End common_component1]
-
-// [Start my_button1]
-//Provider customizes and exports components
-@Component
-export struct MyButton {
- @Prop text: string = '';
- // Accept externally passed AttributeModifier class instances
- @Prop modifier: AttributeModifier | null = null;
-
- build() {
- // AttributeModifier does not support properties with CustomBuilder or Lambda expressions as parameters, and it does
- // not support events or gestures. Here, the text can only be passed separately through parameters.
- Button(this.text)
- // Bind the input AttributeModifier class instance to the system component.
- .attributeModifier(this.modifier)
- .fontSize(20)
- .width(200)
- .height(50)
- }
-}
-// [End my_button1]
-
-// [Start my_button_modifier1]
-// src/main/ets/pages/CommonComponent.ets
-// The provider creates a custom Class that implements the system's AttributeModifier interface.
-export class MyButtonModifier implements AttributeModifier {
- private buttonType: ButtonType = ButtonType.Normal;
- private stateEffectValue: boolean = false;
-
- constructor() {
- }
-
- applyNormalAttribute(instance: ButtonAttribute): void {
- instance.stateEffect(this.stateEffectValue);
- instance.type(this.buttonType);
- instance.width(200);
- instance.height(50);
- instance.fontSize(20)
- }
-
- stateEffect(enable: boolean): MyButtonModifier {
- this.stateEffectValue = enable;
- return this;
- }
-
- type(type: ButtonType): MyButtonModifier {
- this.buttonType = type;
- return this;
- }
-}
-// [End my_button_modifier1]
-// [Start index]
-// src/main/ets/pages/CommonComponent.ets
-@Component
-struct Index {
- modifier = new MyButtonModifier()
- .stateEffect(true)
- .type(ButtonType.Capsule)
-
- build() {
- Row() {
- Button('Capsule Button')
- .attributeModifier(this.modifier)
- }
- .width('100%')
- .height('100%')
- }
-}
-// [End index]
\ No newline at end of file
diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets
index bac07162d247bcfcc8cef073ef17757d7dca4582..783c6fdbf5c14a9aee8a9b8dbb2d137327dfe291 100644
--- a/entry/src/main/ets/pages/Index.ets
+++ b/entry/src/main/ets/pages/Index.ets
@@ -22,21 +22,26 @@ struct Index {
build() {
Navigation(this.pageStack) {
Column({ space: CommonConstants.BUTTON_SPACING }) {
- Button($r('app.string.common'))
+ Button($r('app.string.common_style_extract'))
.width(CommonConstants.ONE_HUNDRED_PERCENT)
.onClick(() => {
- this.pageStack.pushPathByName('CommonComponent', null, true);
+ this.pageStack.pushPathByName('AttributeStylePage', null, true);
})
- Button($r('app.string.dialog'))
+ Button($r('app.string.common'))
.width(CommonConstants.ONE_HUNDRED_PERCENT)
.onClick(() => {
- this.pageStack.pushPathByName('DialogComponent', null, true);
+ this.pageStack.pushPathByName('CommonComponent', null, true);
})
Button($r('app.string.factory'))
.width(CommonConstants.ONE_HUNDRED_PERCENT)
.onClick(() => {
this.pageStack.pushPathByName('ComponentFactory', null, true);
})
+ Button($r('app.string.dialog'))
+ .width(CommonConstants.ONE_HUNDRED_PERCENT)
+ .onClick(() => {
+ this.pageStack.pushPathByName('DialogComponent', null, true);
+ })
}
.padding($r('app.float.padding'))
.justifyContent(FlexAlign.End)
diff --git a/entry/src/main/ets/view/CustomImageText.ets b/entry/src/main/ets/view/CustomImageText.ets
index 7e6c4000e4cfb4dcacf4d7709fbf4eaf96a8d07b..c80fafb1d1c929b50c0d47e7937638f0e29885bb 100644
--- a/entry/src/main/ets/view/CustomImageText.ets
+++ b/entry/src/main/ets/view/CustomImageText.ets
@@ -12,14 +12,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { CommonConstants } from '../common/CommonConstants';
+
+
+// [Start image_modifier]
+// The AttributeModifier interface implementation class for the Image component.
+export class CustomImageModifier implements AttributeModifier {
+ private imageWidth: Length = 0;
+ private imageHeight: Length = 0;
+
+ constructor(width: Length, height: Length) {
+ this.imageWidth = width;
+ this.imageHeight = height;
+ }
+
+ width(width: Length) {
+ this.imageWidth = width;
+ return this;
+ }
+
+ height(height: Length) {
+ this.imageHeight = height;
+ return this;
+ }
+
+ applyNormalAttribute(instance: ImageAttribute): void {
+ instance.width(this.imageWidth);
+ instance.height(this.imageHeight);
+ instance.borderRadius($r('app.float.border_radius'))
+
+ }
+}
+
+// Text component's AttributeModifier interface implementation class.
+export class CustomTextModifier implements AttributeModifier {
+ constructor() {
+ }
+
+ applyNormalAttribute(instance: TextAttribute): void {
+ instance.fontSize($r('app.float.font_size_l'));
+ }
+}
+// [End image_modifier]
+
// [Start custom_image_text]
@Component
export struct CustomImageText {
- @Prop imageAttribute: AttributeModifier;
- @Prop textAttribute: AttributeModifier;
+ @Prop imageAttribute: AttributeModifier = new CustomImageModifier(100, 100);
+ @Prop textAttribute: AttributeModifier = new CustomTextModifier();
@Prop imageSrc: PixelMap | ResourceStr | DrawableDescriptor;
@Prop text: string;
+ onClickEvent?: () => void;
build() {
Column({ space: 12 }) {
@@ -27,7 +69,11 @@ export struct CustomImageText {
.attributeModifier(this.imageAttribute)
Text('Scenery')
.attributeModifier(this.textAttribute)
- }
+ }.onClick(() => {
+ if (this.onClickEvent !== undefined) {
+ this.onClickEvent();
+ }
+ })
}
}
// [End custom_image_text]
diff --git a/entry/src/main/ets/view/FactoryMap.ets b/entry/src/main/ets/view/FactoryMap.ets
index 6a992efc5edeabfc21473ac6fc8604d2db75c141..930727df162f56813ce198d38538ed3438494f44 100644
--- a/entry/src/main/ets/view/FactoryMap.ets
+++ b/entry/src/main/ets/view/FactoryMap.ets
@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { CommonConstants } from '../common/CommonConstants';
+
// [Start my_radio]
@Builder
function myRadio() {
diff --git a/entry/src/main/resources/base/element/float.json b/entry/src/main/resources/base/element/float.json
index aef0b511aed93d3e5ac4505555dd28d0572d1e6b..5658c976982ba13ac2a6024d3a235cc858c6c20b 100644
--- a/entry/src/main/resources/base/element/float.json
+++ b/entry/src/main/resources/base/element/float.json
@@ -31,6 +31,10 @@
{
"name": "margin_top",
"value": "56vp"
+ },
+ {
+ "name": "page_text_font_size",
+ "value": "50fp"
}
]
}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
index 86e9f1d40676f06de03ab90a2ff75a2a51e1edb3..5ff0bbb1fc12fbdaa37bc8be4a0c08dca60b5745 100644
--- a/entry/src/main/resources/base/element/string.json
+++ b/entry/src/main/resources/base/element/string.json
@@ -18,7 +18,7 @@
},
{
"name": "common",
- "value": "Common component encapsulation"
+ "value": "Custom component encapsulation"
},
{
"name": "dialog",
@@ -53,8 +53,8 @@
"value": "CheckBox"
},
{
- "name": "click",
- "value": "CheckBox"
+ "name": "common_style_extract",
+ "value": "Common style encapsulation"
}
]
}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json
index 1898d94f58d6128ab712be2c68acc7c98e9ab9ce..55c3f007f87b7ce5206d325f968cc56f2f79441f 100644
--- a/entry/src/main/resources/base/profile/main_pages.json
+++ b/entry/src/main/resources/base/profile/main_pages.json
@@ -2,4 +2,4 @@
"src": [
"pages/Index"
]
-}
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/profile/route_map.json b/entry/src/main/resources/base/profile/route_map.json
index 7e8f26a009aeddb1fa857523ac071963af8fa6cd..0e5db57923037e86ea05bcb22438150419d67568 100644
--- a/entry/src/main/resources/base/profile/route_map.json
+++ b/entry/src/main/resources/base/profile/route_map.json
@@ -8,6 +8,14 @@
"description" : "this is CommonComponent"
}
},
+ {
+ "name": "AttributeStylePage",
+ "pageSourceFile": "src/main/ets/pages/AttributeStylePage.ets",
+ "buildFunction": "AttributeStylePageBuilder",
+ "data": {
+ "description" : "this is AttributeStylePage"
+ }
+ },
{
"name": "DialogComponent",
"pageSourceFile": "src/main/ets/pages/DialogComponent.ets",
diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json
index 8d61c21208448bd1a4ac7084d90329b01e4d3e94..5ff0bbb1fc12fbdaa37bc8be4a0c08dca60b5745 100644
--- a/entry/src/main/resources/en_US/element/string.json
+++ b/entry/src/main/resources/en_US/element/string.json
@@ -18,7 +18,7 @@
},
{
"name": "common",
- "value": "Common component encapsulation"
+ "value": "Custom component encapsulation"
},
{
"name": "dialog",
@@ -51,6 +51,10 @@
{
"name": "checkbox",
"value": "CheckBox"
+ },
+ {
+ "name": "common_style_extract",
+ "value": "Common style encapsulation"
}
]
}
\ No newline at end of file
diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json
index 82248c13665c88dd60a4b283762bbed0608e7821..0314928c3c885adb55f1d1c7cbce1c94f13e775e 100644
--- a/entry/src/main/resources/zh_CN/element/string.json
+++ b/entry/src/main/resources/zh_CN/element/string.json
@@ -18,7 +18,7 @@
},
{
"name": "common",
- "value": "公用组件封装"
+ "value": "自定义组件封装"
},
{
"name": "dialog",
@@ -51,6 +51,10 @@
{
"name": "checkbox",
"value": "复选框"
+ },
+ {
+ "name": "common_style_extract",
+ "value": "组件公共样式封装"
}
]
}
\ No newline at end of file
diff --git a/screenshots/device/index.en.png b/screenshots/device/index.en.png
index 40901d1ec68094ff6862a3df97f630f3511ef0f6..0b31811aecf4854ed564ada8d09856587ee4918a 100644
Binary files a/screenshots/device/index.en.png and b/screenshots/device/index.en.png differ
diff --git a/screenshots/device/index.png b/screenshots/device/index.png
index 06a5ab4189fb023c2335f00c0f7b3f6455cc654a..95f1b0aa4974092397b9934d1e4457728f0560ec 100644
Binary files a/screenshots/device/index.png and b/screenshots/device/index.png differ
diff --git a/screenshots/device/style.en.png b/screenshots/device/style.en.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2fdcb69d0d726d998a761c55e193718adc970f9
Binary files /dev/null and b/screenshots/device/style.en.png differ
diff --git a/screenshots/device/style.png b/screenshots/device/style.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc798d7c21eb90724216b383382ad2770240d741
Binary files /dev/null and b/screenshots/device/style.png differ