diff --git a/apps/frontend/src/components/post-url-selector/post.url.selector.tsx b/apps/frontend/src/components/post-url-selector/post.url.selector.tsx
index 58843ed8..0370a31f 100644
--- a/apps/frontend/src/components/post-url-selector/post.url.selector.tsx
+++ b/apps/frontend/src/components/post-url-selector/post.url.selector.tsx
@@ -189,11 +189,11 @@ export const postSelector = (date: dayjs.Dayjs): ICommand => ({
width="13"
height="13"
viewBox="0 0 32 32"
- fill="none"
+ fill="currentColor"
>
),
@@ -205,8 +205,7 @@ export const postSelector = (date: dayjs.Dayjs): ICommand => ({
suffix: state.command.suffix,
});
- let state1 = api.setSelectionRange(newSelectionRange);
- state1 = api.setSelectionRange(newSelectionRange);
+ const state1 = api.setSelectionRange(newSelectionRange);
const media = await showPostSelector(date);
executeCommand({
api,
diff --git a/libraries/helpers/src/utils/remove.markdown.ts b/libraries/helpers/src/utils/remove.markdown.ts
new file mode 100644
index 00000000..7387cff0
--- /dev/null
+++ b/libraries/helpers/src/utils/remove.markdown.ts
@@ -0,0 +1,28 @@
+import removeMd from 'remove-markdown';
+import { makeId } from '../../../nestjs-libraries/src/services/make.is';
+
+export const removeMarkdown = (params: { text: string; except?: RegExp[] }) => {
+ let modifiedText = params.text;
+ const except = params.except || [];
+ const placeholders: { [key: string]: string } = {};
+
+ // Step 2: Replace exceptions with placeholders
+ except.forEach((regexp, index) => {
+ modifiedText = modifiedText.replace(regexp, (match) => {
+ const placeholder = `[[EXCEPT_PLACEHOLDER_${makeId(5)}]]`;
+ placeholders[placeholder] = match;
+ return placeholder;
+ });
+ });
+
+ // Step 3: Remove markdown from modified text
+ // Assuming removeMd is the function that removes markdown
+ const cleanedText = removeMd(modifiedText);
+
+ // Step 4: Replace placeholders with original text
+ const finalText = Object.keys(placeholders).reduce((text, placeholder) => {
+ return text.replace(placeholder, placeholders[placeholder]);
+ }, cleanedText);
+
+ return finalText;
+};
diff --git a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts
index e43179bc..458f32b2 100644
--- a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts
+++ b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts
@@ -9,6 +9,7 @@ import sharp from 'sharp';
import { lookup } from 'mime-types';
import { readOrFetch } from '@gitroom/helpers/utils/read.or.fetch';
import removeMd from 'remove-markdown';
+import { removeMarkdown } from '@gitroom/helpers/utils/remove.markdown';
export class LinkedinProvider implements SocialProvider {
identifier = 'linkedin';
@@ -114,6 +115,38 @@ export class LinkedinProvider implements SocialProvider {
};
}
+ async company(token: string, data: { url: string }) {
+ const { url } = data;
+ const getCompanyVanity = url.match(
+ /^https?:\/\/?www\.?linkedin\.com\/company\/([^/]+)\/$/
+ );
+ if (!getCompanyVanity || !getCompanyVanity?.length) {
+ throw new Error('Invalid LinkedIn company URL');
+ }
+
+ const { elements } = await (
+ await fetch(
+ `https://api.linkedin.com/rest/organizations?q=vanityName&vanityName=${getCompanyVanity[1]}`,
+ {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Restli-Protocol-Version': '2.0.0',
+ 'LinkedIn-Version': '202402',
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ )
+ ).json();
+
+ return {
+ options: elements.map((e: { localizedName: string; id: string }) => ({
+ label: e.localizedName,
+ value: `@[${e.localizedName}](urn:li:organization:${e.id})`,
+ }))?.[0],
+ };
+ }
+
private async uploadPicture(
accessToken: string,
personId: string,
@@ -203,9 +236,10 @@ export class LinkedinProvider implements SocialProvider {
},
body: JSON.stringify({
author: `urn:li:person:${id}`,
- commentary: removeMd(
- firstPost.message.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢')
- ).replace('𝔫𝔢𝔴𝔩𝔦𝔫𝔢', '\n'),
+ commentary: removeMarkdown({
+ text: firstPost.message.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢'),
+ except: [/@\[(.*?)]\(urn:li:organization:(\d+)\)/g],
+ }).replace('𝔫𝔢𝔴𝔩𝔦𝔫𝔢', '\n'),
visibility: 'PUBLIC',
distribution: {
feedDistribution: 'MAIN_FEED',
@@ -238,6 +272,10 @@ export class LinkedinProvider implements SocialProvider {
}),
});
+ if (data.status !== 201 && data.status !== 200) {
+ throw new Error('Error posting to LinkedIn');
+ }
+
const topPostId = data.headers.get('x-restli-id')!;
const ids = [
{
@@ -263,10 +301,10 @@ export class LinkedinProvider implements SocialProvider {
actor: `urn:li:person:${id}`,
object: topPostId,
message: {
- text: removeMd(post.message.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢')).replace(
- '𝔫𝔢𝔴𝔩𝔦𝔫𝔢',
- '\n'
- ),
+ text: removeMarkdown({
+ text: post.message.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢'),
+ except: [/@\[(.*?)]\(urn:li:organization:(\d+)\)/g],
+ }).replace('𝔫𝔢𝔴𝔩𝔦𝔫𝔢', '\n'),
},
}),
}