Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SSBookMinigames
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
SSBookMinigames
Commits
8c93fe7b
Commit
8c93fe7b
authored
Apr 13, 2026
by
Yousef Sameh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
deeplink and password reset
parent
de16be72
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
289 additions
and
109 deletions
+289
-109
DeepLinkManager.cs
My project/Assets/App/Core/DeepLinkManager.cs
+75
-0
DeepLinkManager.cs.meta
My project/Assets/App/Core/DeepLinkManager.cs.meta
+2
-0
SupabaseAuthentication.cs
.../Assets/App/Infrastructure/Auth/SupabaseAuthentication.cs
+108
-3
Login.unity
My project/Assets/AppUI/NewAppUI/Scene/Login.unity
+46
-106
LoginPageAnimation.cs
My project/Assets/AppUI/Scripts/LoginPageAnimation.cs
+1
-0
Android.meta
My project/Assets/Plugins/Android.meta
+8
-0
AndroidManifest.xml
My project/Assets/Plugins/Android/AndroidManifest.xml
+42
-0
AndroidManifest.xml.meta
My project/Assets/Plugins/Android/AndroidManifest.xml.meta
+7
-0
No files found.
My project/Assets/App/Core/DeepLinkManager.cs
0 → 100644
View file @
8c93fe7b
using
UnityEngine
;
using
System
;
using
UnityEngine.Events
;
public
sealed
class
DeepLinkManager
:
MonoBehaviour
{
public
static
DeepLinkManager
Instance
{
get
;
private
set
;
}
public
string
lastProcessedUrl
;
public
UnityEvent
OnDeepLinkReceived
;
private
void
Awake
()
{
if
(
Instance
==
null
)
{
Instance
=
this
;
DontDestroyOnLoad
(
gameObject
);
// 1. WARM START: Listen for links while the app is already running
Application
.
deepLinkActivated
+=
OnDeepLinkActivated
;
// 2. COLD START: Check if the app was opened via a link
if
(!
string
.
IsNullOrEmpty
(
Application
.
absoluteURL
))
{
OnDeepLinkActivated
(
Application
.
absoluteURL
);
}
}
else
{
Destroy
(
gameObject
);
}
}
private
void
OnDeepLinkActivated
(
string
url
)
{
lastProcessedUrl
=
url
;
Debug
.
Log
(
$"[شارح] Deep Link Received:
{
url
}
"
);
// Logic to route the user
ProcessDeepLink
(
url
);
}
private
async
void
ProcessDeepLink
(
string
url
)
{
try
{
OnDeepLinkReceived
?.
Invoke
();
Uri
uri
=
new
Uri
(
url
);
// Check if it's our password reset host
if
(
uri
.
Host
==
"reset-password"
)
{
var
resetSessionOrError
=
await
SupabaseAuthentication
.
Instance
.
UpdateSessionFromURl
(
uri
);
resetSessionOrError
.
Switch
(
resetSession
=>
{
},
error
=>
{
Debug
.
LogError
(
$"Failed to process password reset link:
{
error
}
"
);
}
);
}
}
catch
(
Exception
ex
)
{
Debug
.
LogError
(
$"Deep Link Error:
{
ex
.
Message
}
"
);
}
}
}
My project/Assets/App/Core/DeepLinkManager.cs.meta
0 → 100644
View file @
8c93fe7b
fileFormatVersion: 2
guid: 55400cde731761ca3943099c02f27902
\ No newline at end of file
My project/Assets/App/Infrastructure/Auth/SupabaseAuthentication.cs
View file @
8c93fe7b
...
@@ -2,6 +2,7 @@ using System;
...
@@ -2,6 +2,7 @@ using System;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
Cysharp.Threading.Tasks
;
using
Cysharp.Threading.Tasks
;
using
OneOf
;
using
OneOf
;
using
Supabase.Gotrue
;
using
Supabase.Gotrue.Exceptions
;
using
Supabase.Gotrue.Exceptions
;
using
UnityEngine
;
using
UnityEngine
;
...
@@ -243,6 +244,108 @@ public class SupabaseAuthentication
...
@@ -243,6 +244,108 @@ public class SupabaseAuthentication
}
}
}
}
public
async
UniTask
<
OneOf
<
Success
,
string
>>
UpdateSessionFromURl
(
Uri
url
)
{
try
{
var
client
=
SupabaseManager
.
Instance
.
Supabase
();
await
client
.
Auth
.
GetSessionFromUrl
(
url
);
return
new
Success
();
}
catch
(
GotrueException
ex
)
{
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
ex
.
Message
;
}
catch
(
Exception
ex
)
{
// If the function returns a 400 or 500, it often lands here
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
"Server error during deletion. Please try again later."
;
}
finally
{
IsLoading
=
false
;
}
}
public
async
UniTask
<
OneOf
<
Success
,
string
>>
UpdatePassword
(
string
newPassword
)
{
try
{
var
client
=
SupabaseManager
.
Instance
.
Supabase
();
await
client
.
Auth
.
Update
(
new
UserAttributes
{
Password
=
newPassword
}
);
return
new
Success
();
}
catch
(
GotrueException
ex
)
{
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
ex
.
Message
;
}
catch
(
Exception
ex
)
{
// If the function returns a 400 or 500, it often lands here
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
"Server error during deletion. Please try again later."
;
}
finally
{
IsLoading
=
false
;
}
}
public
async
UniTask
<
OneOf
<
Success
,
string
>>
ResetPasswordRequest
(
string
email
)
{
try
{
var
client
=
SupabaseManager
.
Instance
.
Supabase
();
var
options
=
new
ResetPasswordForEmailOptions
(
email
)
{
RedirectTo
=
"sharh://reset-password"
};
await
client
.
Auth
.
ResetPasswordForEmail
(
options
);
// client.Auth.GetSessionFromUrl("supabaseauth://callback#access_token);
//
// var atr = new UserAttributes
// {
// Password = "newpassword123"
// };
//
// await client.Auth.Update(atr);
return
new
Success
();
}
catch
(
GotrueException
ex
)
{
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
ex
.
Message
;
}
catch
(
Exception
ex
)
{
// If the function returns a 400 or 500, it often lands here
Debug
.
LogError
(
$"[Auth Delete]
{
ex
.
Message
}
"
);
return
"Server error during deletion. Please try again later."
;
}
finally
{
IsLoading
=
false
;
}
}
public
async
UniTask
<
OneOf
<
Success
,
string
>>
DeleteAccount
()
public
async
UniTask
<
OneOf
<
Success
,
string
>>
DeleteAccount
()
{
{
try
try
...
@@ -274,8 +377,10 @@ public class SupabaseAuthentication
...
@@ -274,8 +377,10 @@ public class SupabaseAuthentication
};
};
var
options
=
new
Supabase
.
Functions
.
Client
.
InvokeFunctionOptions
();
var
options
=
new
Supabase
.
Functions
.
Client
.
InvokeFunctionOptions
options
.
Headers
=
headers
;
{
Headers
=
headers
};
// 4. Call the Edge Function with explicit headers
// 4. Call the Edge Function with explicit headers
// Pass 'null' for the body if you don't need to send extra data
// Pass 'null' for the body if you don't need to send extra data
await
client
.
Functions
.
Invoke
(
"delete-self"
,
client
.
Auth
.
CurrentSession
.
AccessToken
,
options
);
await
client
.
Functions
.
Invoke
(
"delete-self"
,
client
.
Auth
.
CurrentSession
.
AccessToken
,
options
);
...
...
My project/Assets/AppUI/NewAppUI/Scene/Login.unity
View file @
8c93fe7b
...
@@ -380,51 +380,6 @@ Camera:
...
@@ -380,51 +380,6 @@ Camera:
m_OcclusionCulling
:
1
m_OcclusionCulling
:
1
m_StereoConvergence
:
10
m_StereoConvergence
:
10
m_StereoSeparation
:
0.022
m_StereoSeparation
:
0.022
---
!u!1
&1093642340
GameObject
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
m_Component
:
-
component
:
{
fileID
:
1093642342
}
-
component
:
{
fileID
:
1093642341
}
m_Layer
:
0
m_Name
:
LoginController
m_TagString
:
Untagged
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
0
---
!u!114
&1093642341
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
1093642340
}
m_Enabled
:
1
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
15584a60abf537c4fb863ba3aeb3ee6d
,
type
:
3
}
m_Name
:
m_EditorClassIdentifier
:
Assembly-CSharp::LoginController
uIDocument
:
{
fileID
:
1971829438
}
---
!u!4
&1093642342
Transform
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
1093642340
}
serializedVersion
:
2
m_LocalRotation
:
{
x
:
-0
,
y
:
-0
,
z
:
-0
,
w
:
1
}
m_LocalPosition
:
{
x
:
95.29111
,
y
:
1207.8973
,
z
:
0
}
m_LocalScale
:
{
x
:
1
,
y
:
1
,
z
:
1
}
m_ConstrainProportionsScale
:
0
m_Children
:
[]
m_Father
:
{
fileID
:
0
}
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
---
!u!1
&1311728067
---
!u!1
&1311728067
GameObject
:
GameObject
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
...
@@ -549,6 +504,51 @@ MonoBehaviour:
...
@@ -549,6 +504,51 @@ MonoBehaviour:
m_FirstSelected
:
{
fileID
:
0
}
m_FirstSelected
:
{
fileID
:
0
}
m_sendNavigationEvents
:
1
m_sendNavigationEvents
:
1
m_DragThreshold
:
10
m_DragThreshold
:
10
---
!u!1
&1627471396
GameObject
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
m_Component
:
-
component
:
{
fileID
:
1627471398
}
-
component
:
{
fileID
:
1627471397
}
m_Layer
:
0
m_Name
:
DeepLinkListener
m_TagString
:
Untagged
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
---
!u!114
&1627471397
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
1627471396
}
m_Enabled
:
1
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
55400cde731761ca3943099c02f27902
,
type
:
3
}
m_Name
:
m_EditorClassIdentifier
:
Assembly-CSharp::DeepLinkManager
lastProcessedUrl
:
---
!u!4
&1627471398
Transform
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
1627471396
}
serializedVersion
:
2
m_LocalRotation
:
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
1
}
m_LocalPosition
:
{
x
:
13.23337
,
y
:
10.52223
,
z
:
0.38014
}
m_LocalScale
:
{
x
:
1
,
y
:
1
,
z
:
1
}
m_ConstrainProportionsScale
:
0
m_Children
:
[]
m_Father
:
{
fileID
:
0
}
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
---
!u!1
&1628372280
---
!u!1
&1628372280
GameObject
:
GameObject
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
...
@@ -720,70 +720,10 @@ MonoBehaviour:
...
@@ -720,70 +720,10 @@ MonoBehaviour:
m_PivotReferenceSize
:
0
m_PivotReferenceSize
:
0
m_Pivot
:
0
m_Pivot
:
0
m_WorldSpaceCollider
:
{
fileID
:
0
}
m_WorldSpaceCollider
:
{
fileID
:
0
}
---
!u!1
&2142479135
GameObject
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
m_Component
:
-
component
:
{
fileID
:
2142479138
}
-
component
:
{
fileID
:
2142479137
}
-
component
:
{
fileID
:
2142479136
}
m_Layer
:
0
m_Name
:
SupabaseListener
m_TagString
:
Untagged
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
---
!u!114
&2142479136
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
2142479135
}
m_Enabled
:
1
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
e8c8bd5f339c3203d84f2c7279a64eb0
,
type
:
3
}
m_Name
:
m_EditorClassIdentifier
:
Assembly-CSharp::SceneSwitcherHelpers
---
!u!114
&2142479137
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
2142479135
}
m_Enabled
:
0
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
14bbed8449713f51db869aa6dba9c6fa
,
type
:
3
}
m_Name
:
m_EditorClassIdentifier
:
Assembly-CSharp::SessionListener
splash
:
{
fileID
:
0
}
LoginPageAnimation
:
{
fileID
:
545920731
}
---
!u!4
&2142479138
Transform
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
2142479135
}
serializedVersion
:
2
m_LocalRotation
:
{
x
:
-0
,
y
:
-0
,
z
:
-0
,
w
:
1
}
m_LocalPosition
:
{
x
:
616.9188
,
y
:
1194.7426
,
z
:
0
}
m_LocalScale
:
{
x
:
1
,
y
:
1
,
z
:
1
}
m_ConstrainProportionsScale
:
0
m_Children
:
[]
m_Father
:
{
fileID
:
0
}
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
---
!u!1660057539
&9223372036854775807
---
!u!1660057539
&9223372036854775807
SceneRoots
:
SceneRoots
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_Roots
:
m_Roots
:
-
{
fileID
:
1628372281
}
-
{
fileID
:
1628372281
}
-
{
fileID
:
1093642342
}
-
{
fileID
:
2142479138
}
-
{
fileID
:
668896142
}
-
{
fileID
:
668896142
}
-
{
fileID
:
1627471398
}
My project/Assets/AppUI/Scripts/LoginPageAnimation.cs
View file @
8c93fe7b
...
@@ -150,6 +150,7 @@ public class LoginPageAnimation : MonoBehaviour
...
@@ -150,6 +150,7 @@ public class LoginPageAnimation : MonoBehaviour
Button
registerButton
=
loginPage
.
rootVisualElement
.
Q
<
Button
>(
"RegisterButton"
);
Button
registerButton
=
loginPage
.
rootVisualElement
.
Q
<
Button
>(
"RegisterButton"
);
registerButton
.
clicked
+=
async
()
=>
registerButton
.
clicked
+=
async
()
=>
{
{
registerButton
.
SetEnabled
(
false
);
registerButton
.
SetEnabled
(
false
);
registerButton
.
text
=
"جاري التسجيل..."
;
registerButton
.
text
=
"جاري التسجيل..."
;
...
...
My project/Assets/Plugins/Android.meta
0 → 100644
View file @
8c93fe7b
fileFormatVersion: 2
guid: 5835013930be8e0f59b9e2cbd966db17
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
My project/Assets/Plugins/Android/AndroidManifest.xml
0 → 100644
View file @
8c93fe7b
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<application>
<activity
android:name=
"com.unity3d.player.UnityPlayerActivity"
android:theme=
"@style/UnityThemeSelector"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter
android:label=
"فتح شارح"
>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<data
android:scheme=
"sharh"
android:host=
"reset-password"
/>
</intent-filter>
<meta-data
android:name=
"unityplayer.UnityActivity"
android:value=
"true"
/>
</activity>
<activity
android:name=
"com.unity3d.player.UnityPlayerGameActivity"
android:theme=
"@style/BaseUnityGameActivityTheme"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter
android:label=
"فتح شارح"
>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<data
android:scheme=
"sharh"
android:host=
"reset-password"
/>
</intent-filter>
<meta-data
android:name=
"unityplayer.UnityActivity"
android:value=
"true"
/>
<meta-data
android:name=
"android.app.lib_name"
android:value=
"game"
/>
</activity>
</application>
</manifest>
My project/Assets/Plugins/Android/AndroidManifest.xml.meta
0 → 100644
View file @
8c93fe7b
fileFormatVersion: 2
guid: 45f902060a0d727d2ab0d1f121f0e058
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment