2月 21, 2025
### First

Remember the key settings `otherPortsAttributes`

### Setup

Open your vscode and go to File > Preference > Settings.

![](https://blogger.googleusercontent.com/img/a/AVvXsEgftK4lPx4CE-V-uRBiF7BsaE36LJFdkigH7s9JnEEiUW8RWF_o-_y5exTwKYFFDtYIMiFNAKEqw2mOwuaA2SS49iXRH4br9Mcgz79l4aYkGOFm9qomKzZzFSm6FOubhZHSb8DUcmGSeMh8n9vILkPJ6v-sDloXD0lPJxyKA_erhhUybhcErISZyneVMBo)

Then paste the word `otherPortsAttributes` into the filter in settings panel.

![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZZMjXMB_wLK8FZUwkjGP3fm5mGWg8RDrwytxe9tTUgjPo9rpBHBAL4bRlx6m34DNpdPLTricpnbpJJpPKUK6vUzDDGcX1WZo-KxBE5iVD_SvksKzgud3asgJZM-7nd_dYBTqZzxdUHNw20nagMFR_M3vLieYALPypwa6MFPUDgwAkO9XtZSSx2OHiue4/s1600/%E8%9E%A2%E5%B9%95%E6%93%B7%E5%8F%96%E7%95%AB%E9%9D%A2%20%281%29.png)

Press `Add Item` button, then select `onAutoForward` in item and set the value to `ignore`.

![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsEiz7lnmIe2YoXlOgI-F8Ghn4hJNX9W9Djrs-d4eikOHpsbtxfJcheG0s1gXcyIQiN4cdFnNfcsydjrBTSdYJk450YUXXmk0sWfM5_amglF9DkP2HdyDymoWvDuKHnT2puz_OmE7_3R5VUwasUpkmcbWGiyKO7NA3mGpKYXQHNiwMQV2vmJ1GpPtwjWo/s1600/%E8%9E%A2%E5%B9%95%E6%93%B7%E5%8F%96%E7%95%AB%E9%9D%A2%20%282%29.png)

No more `Auto Forwarded` ports.

Finished ~
2月 07, 2025
如果安裝時出現 network settings 但又不可能即時處理得到,其實是可以 bypass 的:

1. 按下 SHIFT + F10 叫出 cmd

2. 輸入 OOBE\BYPASSNRO

之後個安裝就會自已 restart,入返去後就可以 bypass network setting 同埋登入 microsoft account 兩個流程了
11月 03, 2024 Dart Flutter


### 從 pubspec.yaml 中讀取 version 資料

用呢個 package https://pub.dev/packages/package_info_plus

version 個格式係 1.0.0+1

前面係 semantic versioning (Android 個 versionName),後面個 + 1 就係 versionCode (Android 個 versionCode)

所以個 versionCode 只可以愈來愈大,不可以向後退,如果唔係會變成 downgrade 個 app。

### DropdownMenu 防止使用者可以輸入文字

只要加入呢個 `requestFocusOnTap: false` 參數就可以了。係 window 入面個 cursor 仲會變埋 pointer 添。

```dart
DropdownMenu(
  requestFocusOnTap: false,
  ...,
);
```

11月 03, 2024 Dart Flutter


如果想要在 Widget 一開始時就執行想要的動作,最好就係 `initState` 時加入你要想的東西。

```dart
@override
void initState() {
  super.initState();

  // your action here
}
```

但後多時候我們是需要等到 widget tree 整個畫好晒一次先可以做後續動作。例如 setState 等,可以通過使用 `WidgetsBinding.instance.addPostFrameCallback` 來達成。

```dart
@override
void initState() {
  super.initState();

  // post callback (do after build widget tree)
  WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {

    // set state
    setState(() {
      _foo = 'bar';
    });
  });
}
```

咁樣就可以了。
11月 02, 2024 Dart Flutter


### Dart 對於 JS 的 reduce

Dart 同樣有 reduce,不過 reduce 有少少唔同,最相似係用 fold。

```dart
// create list
final list = ['a', 'bb', 'ccc'];

// compute the sum of all length
list.fold(0, (t, e) => t + e.length); // result is 6
```

### Dart double ceil

double force 進位

```dart
print(1.99999.ceil()); // 2
print(2.0.ceil()); // 2
print(2.00001.ceil()); // 3
print((-1.99999).ceil()); // -1
print((-2.0).ceil()); // -2
print((-2.00001).ceil()); // -2
```

### Flutter container add border

幫 Container 加入 border

```dart
Container(
  margin: const EdgeInsets.all(15.0),
  padding: const EdgeInsets.all(3.0),
  decoration: BoxDecoration(
    border: Border.all(color: Colors.blueAccent),
  ),
  child: Text('My Awesome Border'),
)
```

### 設定一個 FocusNode 用來自動畫面中 Focus 的目標

先在 class 入面設定一個 `FocusNode`。

```dart
final _myField = FocusNode();
```

然後在 TextField 入面加入 focusNode 參數。

```dart
TextFormField(
  focusNode: _myField,
  ...,
);
```

之後就可以通過使用 `_myField` 去選定現在的 focus 目標。

```dart
_myField.requestFocus();
```

得記用完之後要 `dispose` 返佢。

```dart
@override
void dispose() {
  _myField.dispose();
}
```

### Flutter TextField 輸入完成後 focus 下一個 TextField

最普通情況,可以自動移到下一個 TextField:

`TextInputAction.next` 移到下一個 TextField。
`TextInputAction.done` 輸入完成,關上 Keyboard。

```dart
TextField(
  decoration: InputDecoration(hintText: 'TextField A'),
  textInputAction: TextInputAction.next, // Moves focus to next.
);
```

也可以通過 `onFieldSubmitted` 自訂你想要 Focus 的目標。

```dart
Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    TextFormField(
      textInputAction: TextInputAction.next,
      autofocus: true,
      decoration: InputDecoration(labelText: "Input 1"),
      onFieldSubmitted: (v){
        FocusScope.of(context).requestFocus(focus);
      },
    ),
    TextFormField(
      focusNode: focus,
      decoration: InputDecoration(labelText: "Input 2"),
    ),
  ],
);
``` 
    
### Flutter Scrollbar 及 SingleChildScrollView 設定 controller
    
要令到 `Scrollbar` 及 `SingleChildScrollView` 可以運作正常,必需要設定好 controller 才行。設定的方法如下:

設先要係 class 入面整返個 `ScrollController` 先
    
```dart
final _pageScrollController = ScrollController();
```

之後係 `Scrollbar` 同埋 `SingleChildScrollView` 入面都設定返 controller。
    
```dart
Scrollbar(
  controller: _pageScrollController,
  child: SingleChildScrollView(
    controller: _pageScrollController,
    ...,
  ),
);
```
    
可以用以下方法直接 scroll 去最頭或者最尾。
    
```dart
// scroll to top
_pageScrollController.jumpTo(0);

// scroll to end
_pageScrollController.jumpTo(_pageScrollController.position.maxScrollExtent);
```
    
最後就可以係任何地方使用 `jump()` 方法去 Scroll 去頁面不同地方。
    
```dart
_pageScrollController.jumpTo(0);
```
    
    


今日又係要講返 ExtJS 既野,話說 Webpack 已經流行左一大段時間,好多野都變得容易管理左好多。但係如果要將一個 Framework 搬去 Webpack 度用就實在係有啲困難,因為 Framework 通常都會用到好多好底層的功能。而呢啲功能本身既前題係運行個 Scope 有自己本身固定既 Context,運單啲講 Webpack 當 Bundle 完個 package 之後,入面所運行既 JS 係有自己個 Context,係同 Browser 入面 html embed 的 Javascript Context 唔一樣,會有可能引起 Webpack 打包後的 JS 運行唔到。

### 自訂 ExtJS Component

如果你要自訂一個 Component,最起碼都要設定佢最基本既行為,例如當個 Component 建立時需要係 runtime 拎一啲 condition 來決定佢畫出來個樣。或者在建立後修改一下 child component 的數值等等。呢個時候如果睇官方個 Guide 係會教你可以用 `initComponent()` 去改寫 Component 生成時的行為,當中有一個 statement 係 `this.callParent()`。佢係類似 Java 入面 `super()` 的 method,用來叫返 override 左既 super class 個 method。正常用係無問題既,但係如果當你係魔改配合 Webpack 使用的話,就會出 Error。

睇下呢段 Code:

```js
// 定義一個 component
Ext.define('MyApp.view.YourComponent', {
	
	// extend 'Ext.window.Window' 呢個 component
	extend: 'Ext.window.Window',
	
	// 原本個 title
	title: 'foo',
	
	// 自動顯示
	autoShow: true,
	
	// 用 initComponent 來改寫
	initComponent: function(...args) {
		
		// 生成 component
		this.callParent(...args);
		
		// 改下個 title
		this.setTitle('bar');
	},
});

// 生成 class
Ext.create('MyApp.view.YourComponent');
```

之後就會出 Error :

```js
Uncaught TypeError: Cannot read properties of null (reading '$owner') at constructor.callParent
```

### 用 beforerender event 

上網找左好耐好耐都找唔到有效既方法,後來用左 beforerender event 暫時頂住先,後來又改用 added event 來頂住,但係都只係治標不治本既方法。

使用 beforerender 來 workaround:

```js
// 定義一個 component
Ext.define('MyApp.view.YourComponent', {
	
	// extend 'Ext.window.Window' 呢個 component
	extend: 'Ext.window.Window',
	
	// 原本個 title
	title: 'foo',
	
	// 自動顯示
	autoShow: true,
	
	// 設定 listeners
	listeners: {
		
		// beforerender 係生命週期比較早的 event
		beforerender: view => {
			
			// 改下個 title
			view.setTitle('bar')
		},
	},
});

// 生成 class
Ext.create('MyApp.view.YourComponent');
```

### Strict Mode 問題

其實 this.callParent() 係會用到 arguments.callee 同埋 arguments.caller 來配合達成到 call 返 override 的 method。

所以在 Strict Mode 底下會有機會用唔到 this.callParent()...

### Workaround 方法

之後睇到有一篇大神講 ExtJS + Webpack 的使用方法,入面提到如果要用 this.callParent() 的話需要使用到 class prototype 去完成,我再測試一下法現成功了!

實現方法如下:

```js
// 定義一個 component
Ext.define('MyApp.view.YourComponent', {
	
	// extend 'Ext.window.Window' 呢個 component
	extend: 'Ext.window.Window',
	
	// 原本個 title
	title: 'foo',
	
	// 自動顯示
	autoShow: true,
	
	// 用 initComponent 來改寫
	initComponent: function(...args) {

		// 生成 component
		// this.callParent(...args); // 會出 Error

		// workaround 方法, 主要係 call 返 extend component prototype 個 method, 再放返現在 context 個 this 入去
		Ext.window.Window.prototype.initComponent.call(this, ...args);
		
		// 改下個 title
		this.setTitle('bar');
	},
});

// 生成 class
Ext.create('MyApp.view.YourComponent');
```

咁就可以成功啦 !
10月 06, 2024 Docker


Docker 點用就唔係度講了,可以去睇其他文章都得。

今日主要講下點可以係 docker compose 入面淨係 rebuild 一個 container,話說今日要 update docker compose 入面其中一個 image 既 version。雖然 rebuild 晒成個 docker compose 都其實係安全,但係為左安全起見,最好都係可以動最少既野係最安全,所以就好快咁找左一陣 solution。

可以睇下下面呢條:

https://stackoverflow.com/questions/31466428/how-to-restart-a-single-container-with-docker-compose

其實就係用

```sh
$ docker compose up -d --build workername
```

就咁可以解決到了,但係要注意如果有 dependance 的話,佢既 dependance worker 都可能會 rebuild 埋。
過去文章
2025 (9)
4 (5)
3 (1)
2 (3)
2024 (25)
11 (3)
10 (3)
9 (1)
3 (18)
2022 (6)
10 (1)
6 (2)
5 (1)
3 (1)
1 (1)
2021 (21)
11 (7)
7 (1)
6 (2)
5 (2)
4 (6)
3 (2)
2 (1)
2020 (92)
12 (1)
11 (2)
10 (4)
9 (10)
8 (5)
7 (1)
6 (3)
5 (1)
4 (4)
3 (25)
2 (7)
1 (29)
2019 (57)
12 (25)
11 (7)
9 (25)