mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 01:01:31 +00:00
ADD - share own contact from Control Center
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
Pause,
|
||||
Plane,
|
||||
Play,
|
||||
RadioTower,
|
||||
Signal,
|
||||
SkipBack,
|
||||
SkipForward,
|
||||
@@ -30,6 +31,8 @@ import { useRouter } from 'vue-router'
|
||||
|
||||
import { usePhoneStore } from '@/stores/phone'
|
||||
import { useMusicStore } from '@/stores/music'
|
||||
import { useEasyShareStore } from '@/stores/easyshare'
|
||||
import type { EasySharePayload } from '@/types/easyshare'
|
||||
import { nuiCall } from '@/utils/nui'
|
||||
|
||||
const props = defineProps<{ opened: boolean }>()
|
||||
@@ -44,6 +47,7 @@ type ConnectivityPreference =
|
||||
|
||||
const phone = usePhoneStore()
|
||||
const music = useMusicStore()
|
||||
const easyShare = useEasyShareStore()
|
||||
const router = useRouter()
|
||||
const panel = ref<HTMLElement | null>(null)
|
||||
const brightness = ref(phone.preferences.settings.screenBrightness)
|
||||
@@ -56,6 +60,7 @@ const volume = ref(
|
||||
)
|
||||
const flashlightActive = ref(false)
|
||||
const flashlightPending = ref(false)
|
||||
const easySharePending = ref(false)
|
||||
const previousAlertVolume = ref(volume.value || 75)
|
||||
|
||||
const inactiveGlassColors = {
|
||||
@@ -87,6 +92,10 @@ const flashlightColors = computed(() =>
|
||||
}
|
||||
: inactiveGlassColors,
|
||||
)
|
||||
const easyShareColors = {
|
||||
bgIos: 'bg-[#0a84ff]',
|
||||
shadowIos: 'shadow-ios-dark-glass',
|
||||
}
|
||||
const brightnessStyle = computed<CSSProperties>(() => ({
|
||||
'--control-level': `${brightness.value}%`,
|
||||
}))
|
||||
@@ -202,6 +211,23 @@ async function toggleFlashlight(): Promise<void> {
|
||||
flashlightPending.value = false
|
||||
}
|
||||
|
||||
async function shareOwnContact(): Promise<void> {
|
||||
if (easySharePending.value) return
|
||||
easySharePending.value = true
|
||||
const response = await nuiCall<EasySharePayload>('easyshare:own-contact')
|
||||
easySharePending.value = false
|
||||
if (!response.success || !response.data) {
|
||||
console.error(
|
||||
'[ControlCenter] Could not load own EasyShare contact.',
|
||||
response.error,
|
||||
)
|
||||
return
|
||||
}
|
||||
emit('close')
|
||||
easyShare.open(response.data)
|
||||
await easyShare.showNearby()
|
||||
}
|
||||
|
||||
function openApp(path: string): void {
|
||||
emit('close')
|
||||
void router.push(path)
|
||||
@@ -360,9 +386,7 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="control-center__middle-grid">
|
||||
<div
|
||||
class="control-center__round-control control-center__round-control--wide"
|
||||
>
|
||||
<div class="control-center__round-control">
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
@@ -385,6 +409,20 @@ onBeforeUnmount(() => {
|
||||
</k-glass>
|
||||
</div>
|
||||
|
||||
<div class="control-center__round-control">
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
class="control-center__round-button control-center__round-button--easyshare"
|
||||
:colors="easyShareColors"
|
||||
:disabled="easySharePending || !phone.device?.sim"
|
||||
:aria-label="phone.t('ControlCenter.easyShareContact')"
|
||||
@click="shareOwnContact"
|
||||
>
|
||||
<RadioTower aria-hidden="true" />
|
||||
</k-glass>
|
||||
</div>
|
||||
|
||||
<k-glass
|
||||
class="control-center__slider control-center__slider--brightness"
|
||||
:colors="inactiveGlassColors"
|
||||
@@ -712,10 +750,6 @@ onBeforeUnmount(() => {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.control-center__round-control--wide {
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
|
||||
.control-center__round-control > span,
|
||||
.control-center__quick-action > span {
|
||||
width: 100%;
|
||||
@@ -746,6 +780,11 @@ onBeforeUnmount(() => {
|
||||
color: #ff453a;
|
||||
}
|
||||
|
||||
.control-center__round-button--easyshare {
|
||||
background: #0a84ff !important;
|
||||
box-shadow: 0 8px 22px rgb(10 132 255 / 34%) !important;
|
||||
}
|
||||
|
||||
.control-center__focus-button {
|
||||
display: flex;
|
||||
grid-column: 1 / span 2;
|
||||
|
||||
@@ -3375,6 +3375,7 @@ const defaultLocales: LocaleTree = {
|
||||
camera: 'Camera',
|
||||
cellular: 'Cellular Data',
|
||||
close: 'Close Control Center',
|
||||
easyShareContact: 'Share my contact with nearby players',
|
||||
flashlight: 'Flashlight',
|
||||
focus: 'Focus',
|
||||
label: 'Control Center',
|
||||
|
||||
@@ -6868,6 +6868,21 @@ app.post('/api/:endpoint', (request, response) => {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (endpoint === 'easyshare:own-contact') {
|
||||
response.json({
|
||||
success: true,
|
||||
data: {
|
||||
appId: 'phone',
|
||||
copyText: 'Alex Morgan\n5551234567',
|
||||
id: 'self',
|
||||
kind: 'contact',
|
||||
meta: { name: 'Alex Morgan', phoneNumber: '5551234567' },
|
||||
subtitle: '5551234567',
|
||||
title: 'Alex Morgan',
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
if (endpoint === 'easyshare:set-visibility') {
|
||||
easyShareVisibility = request.body.visibility
|
||||
response.json({ success: true, data: { visibility: easyShareVisibility } })
|
||||
|
||||
@@ -72,7 +72,7 @@ Locales["en"] = {
|
||||
},
|
||||
ControlCenter = {
|
||||
airplaneMode = "Airplane Mode", bluetooth = "Bluetooth", brightness = "Brightness", calculator = "Calculator",
|
||||
camera = "Camera", cellular = "Cellular Data", close = "Close Control Center", flashlight = "Flashlight",
|
||||
camera = "Camera", cellular = "Cellular Data", close = "Close Control Center", easyShareContact = "Share my contact with nearby players", flashlight = "Flashlight",
|
||||
focus = "Focus", label = "Control Center", media = "Media", muteRingtone = "Mute ringtone and notifications", next = "Next track", notPlaying = "Not Playing",
|
||||
open = "Open Control Center", play = "Play", previous = "Previous track", quickActions = "Quick actions",
|
||||
timer = "Timer", unmuteRingtone = "Unmute ringtone and notifications", volume = "Volume", wifi = "Wi-Fi",
|
||||
|
||||
@@ -217,6 +217,7 @@ local server_callbacks = {
|
||||
"messages:delete",
|
||||
"messages:gifs",
|
||||
"easyshare:bootstrap",
|
||||
"easyshare:own-contact",
|
||||
"easyshare:set-visibility",
|
||||
"easyshare:request",
|
||||
"easyshare:respond",
|
||||
|
||||
@@ -604,25 +604,36 @@ local function sanitize_payload(source, device, data)
|
||||
|
||||
local condition, owner_params = owner_condition(device)
|
||||
if data.kind == "contact" and type(payload.id) == "string" then
|
||||
local params = { payload.id }
|
||||
append_params(params, owner_params)
|
||||
local rows = Bridge.Database.Query(([[
|
||||
SELECT `name`, `phone_number`, `organization`, `notes`
|
||||
FROM `sky_phone_contacts` WHERE `contact_id` = ? AND %s LIMIT 1
|
||||
]]):format(condition), params)
|
||||
local contact = rows[1]
|
||||
if not contact then
|
||||
return nil, "not_owned"
|
||||
if app_id == "phone" and payload.id == "self" then
|
||||
local contact = canonical_own_contact(source, device)
|
||||
if not contact then
|
||||
return nil, "sim_required"
|
||||
end
|
||||
payload.title = contact.title
|
||||
payload.subtitle = contact.subtitle
|
||||
payload.copyText = contact.copyText
|
||||
payload.meta = contact.meta
|
||||
else
|
||||
local params = { payload.id }
|
||||
append_params(params, owner_params)
|
||||
local rows = Bridge.Database.Query(([[
|
||||
SELECT `name`, `phone_number`, `organization`, `notes`
|
||||
FROM `sky_phone_contacts` WHERE `contact_id` = ? AND %s LIMIT 1
|
||||
]]):format(condition), params)
|
||||
local contact = rows[1]
|
||||
if not contact then
|
||||
return nil, "not_owned"
|
||||
end
|
||||
payload.title = contact.name
|
||||
payload.subtitle = contact.phone_number
|
||||
payload.copyText = ("%s\n%s"):format(contact.name, contact.phone_number)
|
||||
payload.meta = {
|
||||
name = contact.name,
|
||||
notes = contact.notes,
|
||||
organization = contact.organization,
|
||||
phoneNumber = contact.phone_number,
|
||||
}
|
||||
end
|
||||
payload.title = contact.name
|
||||
payload.subtitle = contact.phone_number
|
||||
payload.copyText = ("%s\n%s"):format(contact.name, contact.phone_number)
|
||||
payload.meta = {
|
||||
name = contact.name,
|
||||
notes = contact.notes,
|
||||
organization = contact.organization,
|
||||
phoneNumber = contact.phone_number,
|
||||
}
|
||||
elseif data.kind == "note" and type(payload.id) == "string" then
|
||||
local params = { payload.id }
|
||||
append_params(params, owner_params)
|
||||
@@ -808,6 +819,25 @@ local function apply_received_payload(transfer)
|
||||
return true
|
||||
end
|
||||
|
||||
local function canonical_own_contact(source, device)
|
||||
if not device.phone_number then
|
||||
return nil
|
||||
end
|
||||
local name = display_name(source)
|
||||
return {
|
||||
appId = "phone",
|
||||
kind = "contact",
|
||||
id = "self",
|
||||
title = name,
|
||||
subtitle = device.phone_number,
|
||||
copyText = ("%s\n%s"):format(name, device.phone_number),
|
||||
meta = {
|
||||
name = name,
|
||||
phoneNumber = device.phone_number,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local function advance_transfer(id)
|
||||
local transfer = active_transfers[id]
|
||||
if not transfer or transfer.status ~= "transferring" then
|
||||
@@ -890,6 +920,24 @@ Bridge.Callbacks.Register("sky_phone:easyshare:bootstrap", function(source)
|
||||
}
|
||||
end)
|
||||
|
||||
Bridge.Callbacks.Register("sky_phone:easyshare:own-contact", function(source)
|
||||
if not Config.EasyShare.Enabled then
|
||||
return { success = false, error = "disabled" }
|
||||
end
|
||||
if not SkyPhone.AllowOperation(source, "easyshare_own_contact", Config.EasyShare.BootstrapRequestsPerMinute, 60) then
|
||||
return { success = false, error = "rate_limited" }
|
||||
end
|
||||
local device, error_response = current_device(source)
|
||||
if not device then
|
||||
return error_response
|
||||
end
|
||||
local payload = canonical_own_contact(source, device)
|
||||
if not payload then
|
||||
return { success = false, error = "sim_required" }
|
||||
end
|
||||
return { success = true, data = payload }
|
||||
end)
|
||||
|
||||
Bridge.Callbacks.Register("sky_phone:easyshare:set-visibility", function(source, data)
|
||||
if not Config.EasyShare.Enabled then
|
||||
return { success = false, error = "disabled" }
|
||||
|
||||
Reference in New Issue
Block a user