From ae82ce4c92e35221903d7973cc81fb281d573a6d Mon Sep 17 00:00:00 2001
From: Joe Stein <569991+jas14@users.noreply.github.com>
Date: Sun, 29 Jan 2023 09:22:04 -0500
Subject: [PATCH 1/3] Add deeplink support for 12-character game IDs
---
deepLinkTest.html | 2 ++
src/deepLinks.ts | 24 +++++++++++------------
src/utils/__tests__/gameId.ts | 22 +++++++++++++++++++++
src/utils/gameId.ts | 37 +++++++++++++++++++++++++++++++++++
4 files changed, 72 insertions(+), 13 deletions(-)
create mode 100644 src/utils/__tests__/gameId.ts
create mode 100644 src/utils/gameId.ts
diff --git a/deepLinkTest.html b/deepLinkTest.html
index f5a9a7a710..ec92dad3c0 100644
--- a/deepLinkTest.html
+++ b/deepLinkTest.html
@@ -14,6 +14,8 @@
Prod
https://lichess.org/2360tJXP/black#50
https://lichess.org/2360tJXP/black#500
https://lichess.org/2360tJXP/black#asdf
+ https://lichess.org/2360tJXP000Z#50
+ https://lichess.org/2360tJXP000z#50
https://lichess.org/analysis
https://lichess.org/analysis/rn1qkbnr/pppb1ppp/4p3/3p4/3PP3/2N2N2/PPP2PPP/R1BQKB1R_b_KQkq_-_0_1
https://lichess.org/editor
diff --git a/src/deepLinks.ts b/src/deepLinks.ts
index 19f1a48b9f..f31c5faa51 100644
--- a/src/deepLinks.ts
+++ b/src/deepLinks.ts
@@ -4,6 +4,7 @@ import router from './router'
import session, { Session } from './session'
import signupModal from './ui/signupModal'
import { handleXhrError } from './utils'
+import { extractGameReference } from './utils/gameId'
import { buildQueryString } from './utils/querystring'
const fenParams = ':r1/:r2/:r3/:r4/:r5/:r6/:r7/:r8'
@@ -15,28 +16,27 @@ function fenFromParams(params: any): string {
export default {
init() {
- App.addListener('appUrlOpen', ({ url }) => {
+ void App.addListener('appUrlOpen', ({ url }) => {
setTimeout(() => {
const urlObject = new URL(url)
const path = urlObject.pathname
const matched = links.run(path)
if (!matched) {
// it can be a game or challenge but we want to do an exact regex match
- const found = gamePattern.exec(path)
- if (found) {
- const color = found[2]
- const plyMatch = plyHashPattern.exec(urlObject.hash)
-
+ const gameIdParts = extractGameReference(urlObject)
+ if (gameIdParts !== null) {
+ const {color, gameId, ply} = gameIdParts
const queryParams = {} as Record
- if (color) {
- queryParams['color'] = color.substring(1)
+
+ if (color !== undefined) {
+ queryParams['color'] = color
}
- if (plyMatch) {
- queryParams['ply'] = plyMatch[1]
+ if (ply !== undefined) {
+ queryParams['ply'] = ply
}
const queryString = buildQueryString(queryParams)
- router.set(`/game/${found[1]}?${queryString}`)
+ router.set(`/game/${gameId}?${queryString}`)
} else {
console.warn('Could not handle deep link', path)
}
@@ -47,8 +47,6 @@ export default {
}
const links = new Rlite()
-const gamePattern = /^\/(\w{8})(\/black|\/white)?$/
-const plyHashPattern = /^#(\d+)$/
links.add('analysis', () => router.set('/analyse'))
links.add(`analysis/${fenParams}`, ({ params }) => {
diff --git a/src/utils/__tests__/gameId.ts b/src/utils/__tests__/gameId.ts
new file mode 100644
index 0000000000..cdeec886a1
--- /dev/null
+++ b/src/utils/__tests__/gameId.ts
@@ -0,0 +1,22 @@
+import * as gameId from '../gameId'
+
+describe.each([
+ {url: 'https://lichess.org/DABBAD00yyya', id: 'DABBAD00', color: 'black', ply: undefined},
+ {url: 'https://lichess.org/DABBAD00yyy0', id: 'DABBAD00', color: 'white', ply: undefined},
+ {url: 'https://lichess.org/DABBAD00yyyB#123', id: 'DABBAD00', color: 'white', ply: '123'},
+ {url: 'https://lichess.org/DABBAD00', id: 'DABBAD00', color: undefined, ply: undefined},
+ {url: 'https://lichess.org/DABBAD00/black', id: 'DABBAD00', color: 'black', ply: undefined},
+ {url: 'https://lichess.org/DABBAD00/white', id: 'DABBAD00', color: 'white', ply: undefined},
+ {url: 'https://lichess.org/DABBAD00#123', id: 'DABBAD00', color: undefined, ply: '123'},
+ {url: 'https://lichess.org/DABBAD00/black#123', id: 'DABBAD00', color: 'black', ply: '123'},
+])('extractGameIdParts', ({url, id, color, ply}) => {
+ it(`extracts correctly from ${url}`, () => {
+ const urlObject = new URL(url)
+ const gamePointer = gameId.extractGameReference(urlObject)
+ expect(gamePointer).toEqual({
+ gameId: id,
+ color: color,
+ ply: ply,
+ })
+ })
+})
\ No newline at end of file
diff --git a/src/utils/gameId.ts b/src/utils/gameId.ts
new file mode 100644
index 0000000000..8d44097b97
--- /dev/null
+++ b/src/utils/gameId.ts
@@ -0,0 +1,37 @@
+const blackSuffixPattern = /[5-9a-z]/
+const gamePattern = /^\/(\w{8})(\/black|\/white)?$/
+const fullGamePattern = /^\/(\w{8})(\w{3}[0-9a-zA-Z])$/
+const plyHashPattern = /^#(\d+)$/
+
+export type GameReference = {
+ color: string | undefined,
+ gameId: string,
+ ply: string | undefined,
+}
+
+export function extractGameReference(urlObject: URL): GameReference | null {
+ const path = urlObject.pathname
+ const gameFound = gamePattern.exec(path)
+ const ply = plyHashPattern.exec(urlObject.hash)?.[1]
+
+ if (gameFound) {
+ return {
+ gameId: gameFound[1],
+ color: gameFound[2]?.substring(1),
+ ply: ply,
+ }
+ }
+
+ const fullGameFound = fullGamePattern.exec(path)
+ if (fullGameFound) {
+ const gameId = fullGameFound[1]
+ const color = blackSuffixPattern.test(fullGameFound[2].charAt(3)) ? 'black' : 'white'
+ return {
+ gameId: gameId,
+ color: color,
+ ply: ply,
+ }
+ }
+
+ return null
+}
\ No newline at end of file
From 7ce9972e807ffe1b24609440754767f63546f819 Mon Sep 17 00:00:00 2001
From: Joe Stein <569991+jas14@users.noreply.github.com>
Date: Sun, 29 Jan 2023 09:26:30 -0500
Subject: [PATCH 2/3] Declare 12-character game ID support for Android
---
android/app/src/main/AndroidManifest.xml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f9ae8d7f0c..d5ab749bf5 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -77,6 +77,9 @@
+
From 1c98d47ce4c639690ca14ec43428a3db965ab86f Mon Sep 17 00:00:00 2001
From: Joe Stein <569991+jas14@users.noreply.github.com>
Date: Sun, 29 Jan 2023 09:32:14 -0500
Subject: [PATCH 3/3] Update apple-app-site-association
---
apple-app-site-association | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/apple-app-site-association b/apple-app-site-association
index 36485e0e4c..f3da309a96 100644
--- a/apple-app-site-association
+++ b/apple-app-site-association
@@ -21,11 +21,14 @@
"/": "/????????"
},
{
- "/": "/????????/black"
+ "/": "/????????/white"
},
{
"/": "/????????/black"
},
+ {
+ "/": "/????????????"
+ },
{
"/": "/analysis"
},
@@ -76,6 +79,7 @@
"/????????",
"/????????/black",
"/????????/white",
+ "/????????????",
"/analysis",
"/analysis/*",
"/editor",