Skip to content

Commit 1adfe5c

Browse files
committed
feat: the socialLink UI component
1 parent 45ecce4 commit 1adfe5c

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

src/gui/src/IPC.js

+76-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import path from "./lib/path.js";
3030
import UIContextMenu from './UI/UIContextMenu.js';
3131
import update_mouse_position from './helpers/update_mouse_position.js';
3232
import item_icon from './helpers/item_icon.js';
33+
import UIPopover from './UI/UIPopover.js';
34+
import socialLink from './helpers/socialLink.js';
35+
3336
import { PROCESS_IPC_ATTACHED } from './definitions.js';
3437

3538
window.ipc_handlers = {};
@@ -46,7 +49,7 @@ window.ipc_handlers = {};
4649
*/
4750
const ipc_listener = async (event, handled) => {
4851
const app_env = event.data?.env ?? 'app';
49-
52+
5053
// Only process messages from apps
5154
if(app_env !== 'app')
5255
return handled.resolve(false);
@@ -192,6 +195,78 @@ const ipc_listener = async (event, handled) => {
192195
response: prompt_resp,
193196
}, '*');
194197
}
198+
//--------------------------------------------------------
199+
// socialShare
200+
//--------------------------------------------------------
201+
else if(event.data.msg === 'socialShare' && event.data.url !== undefined){
202+
const window_position = $el_parent_window.position();
203+
204+
// left position provided
205+
if(event.data.options.left !== undefined){
206+
event.data.options.left = Math.abs(event.data.options.left);
207+
event.data.options.left += window_position.left;
208+
}
209+
// left position not provided
210+
else{
211+
// use top left of the window
212+
event.data.options.left = window_position.left;
213+
}
214+
if(event.data.options.top !== undefined){
215+
event.data.options.top = Math.abs(event.data.options.top);
216+
event.data.options.top += window_position.top + 30;
217+
}else{
218+
// use top left of the window
219+
event.data.options.top = window_position.top + 30;
220+
}
221+
222+
// top and left must be numbers
223+
event.data.options.top = parseFloat(event.data.options.top);
224+
event.data.options.left = parseFloat(event.data.options.left);
225+
226+
const social_links = socialLink({url: event.data.url, title: event.data.message, description: event.data.message});
227+
228+
let h = ``;
229+
let copy_icon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-copy" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"/> </svg>`;
230+
231+
// create html
232+
h += `<div style="padding: 10px 10px 2px;">`;
233+
h += `<div style="display:flex;">`;
234+
h += `<input type="text" style="margin-bottom:10px;" class="social-url" readonly value="${html_encode(event.data.url)}"/>`;
235+
h += `<button class="button copy-link" style="white-space:nowrap; text-align:center; white-space: nowrap; text-align: center; padding-left: 10px; padding-right: 10px; height: 33px; box-shadow: none; margin-left: 4px;">${(copy_icon)}</button>`;
236+
h += `</div>`;
237+
238+
h += `<p style="margin: 0; text-align: center; margin-bottom: 0px; color: #484a57; font-weight: 500; font-size: 14px;">${i18n('share_to')}</p>`
239+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links.twitter}" style=""><svg viewBox="0 0 24 24" aria-hidden="true" style="opacity: 0.7;"><g><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></g></svg></a>`
240+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links.whatsapp}" style=""><img src="${window.icons['logo-whatsapp.svg']}"></a>`
241+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links.facebook}" style=""><img src="${window.icons['logo-facebook.svg']}"></a>`
242+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links.linkedin}" style=""><img src="${window.icons['logo-linkedin.svg']}"></a>`
243+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links.reddit}" style=""><img src="${window.icons['logo-reddit.svg']}"></a>`
244+
h += `<a class="copy-link-social-btn" target="_blank" href="${social_links['telegram.me']}" style=""><img src="${window.icons['logo-telegram.svg']}"></a>`
245+
h += '</div>';
246+
247+
let po = await UIPopover({
248+
content: h,
249+
// snapToElement: this,
250+
// parent_element: this,
251+
// width: 300,
252+
height: 100,
253+
left: event.data.options.left,
254+
top: event.data.options.top,
255+
position: 'bottom',
256+
});
257+
258+
$(po).find('.copy-link').on('click', function(e){
259+
const url = $(po).find('.social-url').val();
260+
navigator.clipboard.writeText(url);
261+
// set checkmark
262+
$(po).find('.copy-link').html(`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2" viewBox="0 0 16 16"> <path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0"/> </svg>`);
263+
// reset checkmark
264+
setTimeout(function(){
265+
$(po).find('.copy-link').html(copy_icon)
266+
}, 1000);
267+
})
268+
}
269+
195270
//--------------------------------------------------------
196271
// env
197272
//--------------------------------------------------------

src/puter-js/src/modules/UI.js

+6
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,12 @@ class UI extends EventListener {
608608
})
609609
}
610610

611+
socialShare = function(url, message, options, callback) {
612+
return new Promise((resolve) => {
613+
this.#postMessageWithCallback('socialShare', resolve, { url, message, options });
614+
})
615+
}
616+
611617
prompt = function(message, placeholder, options, callback) {
612618
return new Promise((resolve) => {
613619
this.#postMessageWithCallback('PROMPT', resolve, { message, placeholder, options });

0 commit comments

Comments
 (0)