@qusaieilouti99/call-manager 0.1.99 → 0.1.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ // File: CallActivity.kt
1
2
  package com.margelo.nitro.qusaieilouti99.callmanager
2
3
 
3
4
  import android.app.Activity
@@ -49,31 +50,23 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
49
50
 
50
51
  override fun onCreate(savedInstanceState: Bundle?) {
51
52
  super.onCreate(savedInstanceState)
52
- // Samsung lock‐screen bypass flag
53
53
  val isSamsungBypass = intent.getBooleanExtra(
54
54
  "SAMSUNG_LOCK_SCREEN_BYPASS", false
55
55
  )
56
56
  setupLockScreenBypass(isSamsungBypass)
57
57
 
58
- // Read params
59
- callId = intent.getStringExtra("callId") ?: ""
60
- callType = intent.getStringExtra("callType") ?: "Audio"
58
+ callId = intent.getStringExtra("callId") ?: ""
59
+ callType = intent.getStringExtra("callType") ?: "Audio"
61
60
  val callerName = intent.getStringExtra("callerName") ?: "Unknown"
62
61
  val avatarUrl = intent.getStringExtra("callerAvatar")
63
62
 
64
- // Register for external hang‐up
65
63
  CallEngine.registerCallEndListener(this)
66
-
67
- // Build all‐code UI
68
64
  buildUi(callerName, avatarUrl)
69
-
70
- // Auto‐timeout
71
65
  uiHandler.postDelayed(timeoutRunnable, timeoutMs)
72
66
  Log.d(TAG, "CallActivity setup complete for callId=$callId")
73
67
  }
74
68
 
75
69
  private fun buildUi(name: String, avatarUrl: String?) {
76
- // Root container
77
70
  val root = FrameLayout(this).apply {
78
71
  layoutParams = ViewGroup.LayoutParams(
79
72
  ViewGroup.LayoutParams.MATCH_PARENT,
@@ -81,20 +74,17 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
81
74
  )
82
75
  }
83
76
 
84
- //
85
- // 1) Background ImageView + blur
86
- //
77
+ // 1) Full-screen background + blur
87
78
  val bg = ImageView(this).apply {
88
79
  layoutParams = FrameLayout.LayoutParams(
89
80
  ViewGroup.LayoutParams.MATCH_PARENT,
90
81
  ViewGroup.LayoutParams.MATCH_PARENT
91
82
  )
92
83
  scaleType = ImageView.ScaleType.CENTER_CROP
93
- // On API 31+ apply live RenderEffect blur
94
84
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
95
85
  setRenderEffect(
96
86
  RenderEffect.createBlurEffect(
97
- 25f, 25f, Shader.TileMode.CLAMP
87
+ 50f, 50f, Shader.TileMode.CLAMP
98
88
  )
99
89
  )
100
90
  }
@@ -102,9 +92,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
102
92
  root.addView(bg)
103
93
  loadAndBlurBackground(bg, avatarUrl)
104
94
 
105
- //
106
- // 2) Semi-transparent scrim
107
- //
95
+ // 2) Dark scrim
108
96
  root.addView(View(this).apply {
109
97
  layoutParams = FrameLayout.LayoutParams(
110
98
  ViewGroup.LayoutParams.MATCH_PARENT,
@@ -113,9 +101,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
113
101
  setBackgroundColor(Color.parseColor("#80000000"))
114
102
  })
115
103
 
116
- //
117
- // 3) Top “Incoming … call” label
118
- //
104
+ // 3) “Incoming ... call” with extra top padding (48dp)
119
105
  val typeLabel = TextView(this).apply {
120
106
  text = if (callType.equals("video", true))
121
107
  "Incoming video call"
@@ -129,14 +115,12 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
129
115
  ViewGroup.LayoutParams.WRAP_CONTENT
130
116
  ).apply {
131
117
  gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
132
- topMargin = dp(32)
118
+ topMargin = dp(48)
133
119
  }
134
120
  }
135
121
  root.addView(typeLabel)
136
122
 
137
- //
138
- // 4) Avatar + Name (in top half)
139
- //
123
+ // 4) Avatar + name in top half
140
124
  val avatarSection = LinearLayout(this).apply {
141
125
  orientation = LinearLayout.VERTICAL
142
126
  gravity = Gravity.CENTER_HORIZONTAL
@@ -162,9 +146,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
162
146
  })
163
147
  root.addView(avatarSection)
164
148
 
165
- //
166
- // 5) Bottom Answer/Decline Buttons
167
- //
149
+ // 5) Bottom buttons with extra bottom padding (64dp)
168
150
  val actions = LinearLayout(this).apply {
169
151
  orientation = LinearLayout.HORIZONTAL
170
152
  gravity = Gravity.CENTER
@@ -173,7 +155,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
173
155
  ViewGroup.LayoutParams.WRAP_CONTENT
174
156
  ).apply {
175
157
  gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
176
- bottomMargin = dp(48)
158
+ bottomMargin = dp(64)
177
159
  }
178
160
  }
179
161
  actions.addView(
@@ -196,22 +178,24 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
196
178
  setContentView(root)
197
179
  }
198
180
 
199
- /** Creates the top avatar circle: remote image or default + initials. */
200
- private fun createAvatarView(
201
- name: String,
202
- url: String?
203
- ): FrameLayout {
181
+ private fun createAvatarView(name: String, url: String?): FrameLayout {
204
182
  val size = dp(140)
183
+ // Gradient purple background
184
+ val gradientBg = GradientDrawable(
185
+ GradientDrawable.Orientation.TL_BR,
186
+ intArrayOf(
187
+ Color.parseColor("#8E24AA"),
188
+ Color.parseColor("#CE93D8")
189
+ )
190
+ ).apply { shape = GradientDrawable.OVAL }
191
+
205
192
  val container = FrameLayout(this).apply {
206
193
  layoutParams = LinearLayout.LayoutParams(size, size)
207
- background = GradientDrawable().apply {
208
- shape = GradientDrawable.OVAL
209
- setColor(Color.parseColor("#DDFFFFFF"))
210
- }
194
+ background = gradientBg
211
195
  clipToOutline = true
212
196
  }
213
197
 
214
- // ImageView for remote or default avatar
198
+ // ImageView (only visible when URL != null)
215
199
  val iv = ImageView(this).apply {
216
200
  layoutParams = FrameLayout.LayoutParams(
217
201
  ViewGroup.LayoutParams.MATCH_PARENT,
@@ -221,7 +205,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
221
205
  }
222
206
  container.addView(iv)
223
207
 
224
- // Initials overlay
208
+ // Initials TextView
225
209
  val initials = TextView(this).apply {
226
210
  layoutParams = FrameLayout.LayoutParams(
227
211
  ViewGroup.LayoutParams.MATCH_PARENT,
@@ -236,14 +220,14 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
236
220
  container.addView(initials)
237
221
 
238
222
  if (url.isNullOrEmpty()) {
239
- // No remote → show default vector + initials
240
- iv.setImageResource(R.drawable.ic_default_avatar)
223
+ iv.visibility = View.GONE
241
224
  initials.visibility = View.VISIBLE
242
225
  } else {
243
- // Remote → load + hide initials
226
+ iv.visibility = View.VISIBLE
244
227
  initials.visibility = View.GONE
245
228
  loadAvatar(iv, url)
246
229
  }
230
+
247
231
  return container
248
232
  }
249
233
 
@@ -251,13 +235,11 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
251
235
  val parts = fullName.trim().split("\\s+".toRegex())
252
236
  return when (parts.size) {
253
237
  0 -> ""
254
- 1 -> parts[0].substring(0,1).uppercase()
255
- else -> (parts[0][0].toString() + parts[1][0].toString())
256
- .uppercase()
238
+ 1 -> parts[0].substring(0, 1).uppercase()
239
+ else -> (parts[0][0].toString() + parts[1][0].toString()).uppercase()
257
240
  }
258
241
  }
259
242
 
260
- /** Downloads an image + sets it on the ImageView. */
261
243
  private fun loadAvatar(iv: ImageView, url: String) {
262
244
  Thread {
263
245
  try {
@@ -265,11 +247,10 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
265
247
  conn.doInput = true; conn.connect()
266
248
  val bmp = BitmapFactory.decodeStream(conn.inputStream)
267
249
  runOnUiThread { iv.setImageBitmap(bmp) }
268
- } catch (_: Exception) { /* ignore */ }
250
+ } catch (_: Exception) { }
269
251
  }.start()
270
252
  }
271
253
 
272
- /** Downloads bg image (remote or fallback), applies blur if needed. */
273
254
  private fun loadAndBlurBackground(iv: ImageView, url: String?) {
274
255
  Thread {
275
256
  val bmp: Bitmap? = try {
@@ -278,19 +259,16 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
278
259
  c.doInput = true; c.connect()
279
260
  BitmapFactory.decodeStream(c.inputStream)
280
261
  } else {
281
- // your fallback background
282
262
  BitmapFactory.decodeResource(
283
263
  resources, R.drawable.default_call_bg
284
264
  )
285
265
  }
286
- } catch (_: Exception) {
287
- null
288
- }
266
+ } catch (_: Exception) { null }
289
267
  bmp ?: return@Thread
290
268
 
291
269
  val finalBmp = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
292
- // quick blur: down/up-scale
293
- val factor = 8
270
+ // heavier blur via 16× down/up-scale
271
+ val factor = 16
294
272
  val w = bmp.width / factor
295
273
  val h = bmp.height / factor
296
274
  val small = Bitmap.createScaledBitmap(bmp, w, h, true)
@@ -303,18 +281,15 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
303
281
  }.start()
304
282
  }
305
283
 
306
- /** Big round button with circular ripple. */
307
- private fun createCircleButton(
308
- iconRes: Int,
309
- bgColor: Int
310
- ): FrameLayout {
284
+ private fun createCircleButton(iconRes: Int, bgColor: Int): FrameLayout {
311
285
  val size = dp(70)
312
286
  return FrameLayout(this).apply {
313
287
  layoutParams = LinearLayout.LayoutParams(size, size)
314
288
  isClickable = true
315
289
  isFocusable = true
316
290
  foreground = makeCircleRipple()
317
- // colored circle
291
+
292
+ // circular background
318
293
  addView(View(context).apply {
319
294
  layoutParams = FrameLayout.LayoutParams(
320
295
  ViewGroup.LayoutParams.MATCH_PARENT,
@@ -325,6 +300,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
325
300
  setColor(bgColor)
326
301
  }
327
302
  })
303
+
328
304
  // icon
329
305
  addView(ImageView(context).apply {
330
306
  layoutParams = FrameLayout.LayoutParams(dp(36), dp(36))
@@ -335,18 +311,15 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
335
311
  }
336
312
  }
337
313
 
338
- /** Circular RippleDrawable. */
339
314
  private fun makeCircleRipple(): RippleDrawable {
340
315
  val mask = GradientDrawable().apply {
341
316
  shape = GradientDrawable.OVAL
342
317
  setColor(Color.WHITE)
343
318
  }
344
- val clr = Color.parseColor("#33FFFFFF")
345
- return RippleDrawable(
346
- android.content.res.ColorStateList.valueOf(clr),
347
- null,
348
- mask
319
+ val color = android.content.res.ColorStateList.valueOf(
320
+ Color.parseColor("#33FFFFFF")
349
321
  )
322
+ return RippleDrawable(color, null, mask)
350
323
  }
351
324
 
352
325
  private fun onAnswer() {
@@ -356,6 +329,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
356
329
  CallEngine.answerCall(callId)
357
330
  finishCallActivity()
358
331
  }
332
+
359
333
  private fun onDecline() {
360
334
  finishReason = FinishReason.DECLINE
361
335
  CallEngine.stopRingtone()
@@ -391,8 +365,7 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
391
365
  override fun onDismissError() {
392
366
  Log.w(TAG, "Keyguard dismiss error")
393
367
  }
394
- }
395
- )
368
+ })
396
369
  }
397
370
  }
398
371
 
@@ -431,7 +404,8 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
431
404
  }
432
405
 
433
406
  private fun dp(v: Int): Int = TypedValue.applyDimension(
434
- TypedValue.COMPLEX_UNIT_DIP, v.toFloat(),
407
+ TypedValue.COMPLEX_UNIT_DIP,
408
+ v.toFloat(),
435
409
  resources.displayMetrics
436
410
  ).toInt()
437
411
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qusaieilouti99/call-manager",
3
- "version": "0.1.99",
3
+ "version": "0.1.100",
4
4
  "description": "Call manager",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -1,18 +0,0 @@
1
- <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
- android:width="24dp"
3
- android:height="24dp"
4
- android:viewportWidth="24"
5
- android:viewportHeight="24">
6
- <path
7
- android:fillColor="#BDBDBD"
8
- android:pathData="
9
- M12,12c2.21,0 4,-1.79 4,-4
10
- s-1.79,-4 -4,-4
11
- s-4,1.79 -4,4
12
- s1.79,4 4,4z
13
- M6,20
14
- c0,-3.31 2.69,-6 6,-6
15
- s6,2.69 6,6
16
- v1
17
- H6v-1z"/>
18
- </vector>