Skip to content

Commit

Permalink
Merge pull request #40 from sarmadka/main
Browse files Browse the repository at this point in the history
Enable app updates plus other minor changes.
  • Loading branch information
sarmadka committed Aug 22, 2023
2 parents 93a3aee + 2585303 commit a0eafcd
Show file tree
Hide file tree
Showing 16 changed files with 358 additions and 70 deletions.
92 changes: 92 additions & 0 deletions Doc/global_funcs.ar.md
Original file line number Diff line number Diff line change
Expand Up @@ -892,3 +892,95 @@ function matchRegex (str: ptr[array[Char]], regexId: ArchInt): Array[String];
* `نص` (`str`) النص المراد مطابقة نمط معه.
* `دليل_نمط` (`regexId`) معرف النمط المراد مطابقة نمط معه.


### أيوجد_تحديث_للتطبيق (isAppUpdateAvailable)

<div dir=rtl>

```
عرف أيوجد_تحديث_للتطبيق(): ثـنائي؛
```

</div>

```
function isAppUpdateAvailable (): Bool;
```

ترجع 1 إن توفر تحديث لتطبيق الويب، أي عندما تُنشر نسخة جديدة منه على الخادم برقم إصدار مختلف في
معطيات مبدل `@تطبيق_ويب` (`@webApp`).


### حدث_التطبيق (updateApp)

<div dir=rtl>

```
عرف حدث_التطبيق()؛
```

</div>

```
function updateApp();
```

يُحدث التطبيق إلى النسخة التي تم تحميلها في المتصفح. يؤدي استدعاؤها إلى إعادة تحميل الصفحة.


### هات_نمط_عرض_التطبيق (getAppDisplayMode)

<div dir=rtl>

```
عرف هات_نمط_عرض_التطبيق(): مؤشر[مـحرف]؛
```

</div>

```
function getAppDisplayMode(): ptr[Char];
```

ترجع النمط الحالي لعرض التطبيق. قيم الإرجاع المحتملة:
*`browser`: التطبيق يعمل في المتصفح.
*`twa`: التطبيق يعمل في نمط Trusted Web Activity.
*`standalone`: التطبيق منصّب على الجهاز.


### أتوجد_واجهة_تنصيب_للتطبيق (isAppInstallPromptAvailable)

<div dir=rtl>

```
عرف أتوجد_واجهة_تنصيب_للتطبيق(): ثـنائي؛
```

</div>

```
function isAppInstallPromptAvailable (): Bool;
```

ترجع 1 إن توفرت إمكانية تنصيب التطبيق على الجهاز. تتحقق هذه الحالة إذا كان المنفذ المرئي
معلما بالمبدل `@تطبيق_ويب` (`@webApp`) وكان يعمل ببروتوكول HTTPS وكان المتصفح يدعم
تطبيقات PWA ولم يكن التطبيق منصبًا مسبقًا.


### اعرض_اجهة_تنصيب_التطبيق (showAppInstallPrompt)

<div dir=rtl>

```
عرف اعرض_اجهة_تنصيب_التطبيق(): ثـنائي؛
```

</div>

```
function showAppInstallPrompt(): Bool;
```

تُعلم النظام بإظهار واجهة تنصيب التطبيق. تُرجع 1 عند نجاح العملية و0 إن لم تكن واجهة التنصيب
متوفرة.

55 changes: 55 additions & 0 deletions Doc/global_funcs.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,58 @@ Version 4 parameters:
* `str` the text we want to match it with the pattern.
* `regexId` the pattern id used for matching.


### isAppUpdateAvailable

```
function isAppUpdateAvailable (): Bool;
```

Returns true if an update is available for the app, which is when the version number is updated in
the args of `@webApp` modifier.


### updateApp

```
function updateApp();
```

Updates the web app to the version that has been loaded into the browser and is awaiting activation.


### getAppDisplayMode

```
function getAppDisplayMode(): ptr[Char];
```

Returns the current mode of the web app. The return value can be one of the following:
* `browser`: The app is running in the browser.
* `twa`: The app is running as a Trusted Web Activity.
* `standalone`: The app is running as a standalone app.


### isAppInstallPromptAvailable

```
function isAppInstallPromptAvailable (): Bool;
```

Returns 1 if the app can be installed to the device. This happens when all the followings
conditions are met:
* The UI endpoint has the `@webApp` modifier.
* The site is running in HTTPS.
* The browser supports Progressive Web Apps.
* The app is not already installed.


### showAppInstallPrompt

```
function showAppInstallPrompt(): Bool;
```

Triggers the system's app installation prompt. Returns 1 if successful, and 0 if no install
prompt is available.

1 change: 1 addition & 0 deletions Doc/styling.ar.md
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ class Shadow {

صنف يحمل قيم الإظهار الممكنة على شكل تعدادات.
* `_ضمني_` (`INLINE`)
* `_كتلة_ضمنية_ (`INLINE_BLOCK`)
* `_كتلة_` (`BLOCK`)
* `_مرن_` (`FLEX`)
* `_شبكة_` (`GRID`)
Expand Down
1 change: 1 addition & 0 deletions Doc/styling.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ An enum class that holds possible values for overflow as enum.

An enum class that holds possible values for display as enum.
* `INLINE`
* `INLINE_BLOCK`
* `BLOCK`
* `FLEX`
* `GRID`
Expand Down
13 changes: 13 additions & 0 deletions Doc/ui_endpoints.ar.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,18 @@ func about {
وفي نهاية الدالة نقوم دائماً باستدعاء الدالة `نفذ_حلقة_معالجة_الأحداث` والتي تقوم بتشغيل حلقة
الأحداث.

### رسائل النظام

ترسل مـنصة_ويب إشعارًا للمستخدم في بعض الحالات ويمكن للمستخدم استلامها عبر حدث
`عند_استلام_رسالة` (`onMessage`). حمولة هذه الرسائل (من صنف جـيسون) تحتوي على قيمة نصية
باسم `type` يمكن للمستخدم التحقق منها لمعرفة نوع الرسالة. تتوفر الرسائل التالية:

*`app_update_available`: تُرسل عندما يتوفر تحديث لتطبيق الويب. يمكن للمستخدم الاستجابة
لهذه الرسالة عبر إظهار إشعار للمستخدم بوجود تحديث، ومن ثم استدعاء `حدث_التطبيق` (`updateApp`).

*`app_install_prompt`: تُرسل عندما تتوفر واجهة تنصيب التطبيق على الجهاز. يمكن للمستخدم الاستجابة
لهذه الرسالة بإظهار إشعار للمستخدم بإمكانية تنصيب تطبيقه، ومن ثم استدعاء
`اعرض_واجهة_تنصيب_التطبيق` (`showAppInstallPrompt`).

</div>

14 changes: 14 additions & 0 deletions Doc/ui_endpoints.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,17 @@ styles.

At the end of the function we always execute the function `runEventLoop` that runs the event loop.

### System Messages

WebPlatform sends messages in some cases in response to system events. The user can subscribe to
`onMessage` to listen to these messages. These messages have a payload (a JSON type) that contains
a `type` property that the user can check to know the message type. The following message types
are available:

* `app_update_available`: Sent when an update is available for the web app. The user can respond
to this message by notifying the user of the update, and then calling `updateApp` to perform
the update.

* `app_install_prompt`: Sent when an install prompt is available for the web app. The user can
respond to this message by notifying the user and then calling `showAppInstallPrompt`.

16 changes: 16 additions & 0 deletions Doc/widgets.ar.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,22 @@ handler this.removeChildren (count: Int, children: ...temp_ref[SrdRef[Widget]]);

* `فروع` (`children`): الفروع التي نريد إزالتها و التي هي عبارة عن ودجات.

##### أزل_كل_الفروع (removeAllChildren)

```
عملية هذا.أزل_كل_الفروع()؛
```

<div dir=ltr>

```
handler this.removeAllChildren ();
```

</div>

تزيل كل الفروع المضافة لهذا الصندوق.


### مـرسم (Canvas)

Expand Down
8 changes: 8 additions & 0 deletions Doc/widgets.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ parameters:

* `children` the children we want to remove, which are widgets.

##### removeAllChildren

```
handler this.removeAllChildren ();
```

Removes all children of this box.


### Canvas

Expand Down
20 changes: 13 additions & 7 deletions WebPlatform/Components/Stack.alusus
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
}

handler this~init(child: SrdRef[Widget]) {
this.innerView.addChildren({ child });
this.push(child);
}

handler this.setTransition(name: String, transition: StackTransition) {
Expand Down Expand Up @@ -138,14 +138,20 @@
//==========================================================================
// Default Transitions

func createSlideStackTransition (duration: Float, vertical: Bool, backward: Bool): StackTransition {
func createSlideStackTransition (duration: Float, vertical: Bool, exiting: Bool): StackTransition {
return createSlideStackTransition(duration, vertical, exiting, 0);
}

func createSlideStackTransition (duration: Float, vertical: Bool, exiting: Bool, reverse: Bool): StackTransition {
def start: SrdRef[Length];
def end: SrdRef[Length];
if backward {
if exiting {
start = Length.pt(0);
end = Length.percent(100);
if reverse end = Length.percent(-100)
else end = Length.percent(100);
} else {
start = Length.percent(100);
if reverse start = Length.percent(-100)
else start = Length.percent(100);
end = Length.pt(0);
}
return StackTransition().{
Expand All @@ -160,10 +166,10 @@
}
}

func createFadeStackTransition (duration: Float, backward: Bool): StackTransition {
func createFadeStackTransition (duration: Float, exiting: Bool): StackTransition {
def start: Float;
def end: Float;
if backward {
if exiting {
start = 1.0;
end = 0.0;
} else {
Expand Down
3 changes: 2 additions & 1 deletion WebPlatform/Styling/enums.alusus
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@

class Display {
setupStringEnum[];
enumStringValue[INLINE, "INLINE"];
enumStringValue[INLINE, "inline"];
enumStringValue[BLOCK, "block"];
enumStringValue[INLINE_BLOCK, "inline-block"];
enumStringValue[FLEX, "flex"];
enumStringValue[GRID, "grid"];
enumStringValue[NONE, "none"];
Expand Down
8 changes: 8 additions & 0 deletions WebPlatform/Widgets/Box.alusus
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
}
}

handler this.removeAllChildren() {
def i: Int;
for i = this.children.getLength() - 1, i >= 0, --i {
this.children(i).unbuild();
this.children.remove(i);
}
}

//-------------------
// Function Overrides

Expand Down
8 changes: 6 additions & 2 deletions WebPlatform/browser_api.alusus
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,13 @@
@expname[callCustomAsyncJsFn] function _callCustomAsyncJsFn (fnName: ptr[Char], arg: ptr[Char], cbId: ArchInt);
@expname[getUserLanguages] function _getUserLanguages (): ptr[Char];
@expname[isDarkColorSchemePreferred] function isDarkColorSchemePreferred (): Bool;
@expname[getPwaDisplayMode] function getPwaDisplayMode(): ptr[Char];
@expname[resizeWindow] function resizeWindow(width: Int, height: Int);
@expname[showInstallPrompt] function showInstallPrompt(): Bool;
// PWA
@expname[isAppUpdateAvailable] function isAppUpdateAvailable(): Bool;
@expname[updateApp] function updateApp();
@expname[getAppDisplayMode] function getAppDisplayMode(): ptr[Char];
@expname[isAppInstallPromptAvailable] function isAppInstallPromptAvailable(): Bool;
@expname[showAppInstallPrompt] function showAppInstallPrompt(): Bool;
// String
@expname[createRegex] function createRegex (regexStr: ptr[Char]): ArchInt;
@expname[matchRegex] function _matchRegex (
Expand Down
23 changes: 16 additions & 7 deletions WebPlatform/server.alusus
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,21 @@
def appParams: Array[String] = getModifierParams(elements(i), "webApp", "تطبيق_ويب");
def appManifest: String;
if appParams.getLength() > 0 appManifest = appParams(0);
def appVersion: String;
if appParams.getLength() > 1 appVersion = appParams(1) else appVersion = "v1";

def preCacheFilenames: Array[String] = getModifierParams(elements(i), "preCache", "خزن_مسبق");
def dynCacheFilenames: Array[String] = getModifierParams(elements(i), "dynCache", "خزن_تفاعلي");

addUiEndpoint(elements(i), uriParams(0), title, icon, appManifest, preCacheFilenames, dynCacheFilenames);
addUiEndpoint(
elements(i), uriParams(0), title, icon, appManifest, appVersion, preCacheFilenames, dynCacheFilenames
);
}
}

func addUiEndpoint (
fn: ref[Core.Basic.TiObject], uri: String, title: String, iconFilename: String,
manifestFilename: String, preCacheFilenames: Array[String], dynCacheFilenames: Array[String]
fn: ref[Core.Basic.TiObject], uri: String, title: String, iconFilename: String, manifestFilename: String,
version: String, preCacheFilenames: Array[String], dynCacheFilenames: Array[String]
) {
def fnName: String = generateWasm(fn);
if iconFilename != "" {
Expand All @@ -107,7 +111,7 @@
String.format("/%s-manifest.json", fnName.buf),
});
if iconFilename != "" preCacheFilenames.add(String.format("/") + iconFilename);
generateServiceWorker(fnName, preCacheFilenames, dynCacheFilenames);
generateServiceWorker(fnName, preCacheFilenames, dynCacheFilenames, version);
}
generateHtml(fnName, title, iconFilename, manifestFilename != "");
Spp.astMgr.insertAst(
Expand Down Expand Up @@ -135,10 +139,15 @@
return fnName;
}

func generateServiceWorker(fnName: String, preCacheFilenames: Array[String], dynCacheFilenames: Array[String]) {
func generateServiceWorker(
fnName: String, preCacheFilenames: Array[String], dynCacheFilenames: Array[String], version: String
) {
def workerTemplate: String = Fs.readFile(webPlatformPath + "service-worker.js");
def content: String = String.format(
workerTemplate, createJsStringArray(preCacheFilenames).buf, createJsStringArray(dynCacheFilenames).buf
workerTemplate,
createJsStringArray(preCacheFilenames).buf,
createJsStringArray(dynCacheFilenames).buf,
(String("\"") + version.replace("\\", "\\\\").replace("\"", "\\\"") + "\"").buf
);
Fs.createFile(
String.format("%s%s-service-worker.js", uiEndpointsPath.buf, fnName.buf),
Expand Down Expand Up @@ -166,7 +175,7 @@
def extraScript: String;
if webApp {
extraHeaders += String.format("<link rel=\"manifest\" href=\"/%s-manifest.json\" />", fnName.buf);
extraScript += String.format("initWebApp(\"/%s-service-worker.js\", \"/\");", fnName.buf);
extraScript += String.format("initializeWebApp(\"/%s-service-worker.js\", \"/\");", fnName.buf);
}
def content: String = String.format(
htmlTemplate, title.buf, extraHeaders.buf, extraScript.buf, String.format("/%s.wasm", fnName.buf).buf
Expand Down

0 comments on commit a0eafcd

Please sign in to comment.