- Sorry the tweet data is not available on yup! -
+Sorry the tweet data is not available on yup!
Preview for this tweet is missing.
Do you want to try to load an embed?
@@ -287,7 +297,7 @@ + + diff --git a/packages/icons/src/mastodon.vue b/packages/icons/src/mastodon.vue new file mode 100644 index 0000000..e48bc78 --- /dev/null +++ b/packages/icons/src/mastodon.vue @@ -0,0 +1,27 @@ + + + + + + + diff --git a/packages/shared/src/types/account.ts b/packages/shared/src/types/account.ts index e733365..93a937e 100644 --- a/packages/shared/src/types/account.ts +++ b/packages/shared/src/types/account.ts @@ -13,6 +13,7 @@ export interface IUserData { evmAddress: string fullname: string isPro: boolean + isTwitterBlue: boolean connected: { farcaster: boolean twitter: boolean diff --git a/packages/shared/src/types/store.ts b/packages/shared/src/types/store.ts index 4d11ad3..36317aa 100644 --- a/packages/shared/src/types/store.ts +++ b/packages/shared/src/types/store.ts @@ -14,10 +14,12 @@ export interface IStoreUserData { lens: boolean bsky: boolean threads: boolean + mastodon: boolean } bio?: string fullname?: string isOwner?: boolean + isTwitterBlue: boolean } export interface IMainStore { diff --git a/packages/shared/src/types/web2/twitter.ts b/packages/shared/src/types/web2/twitter.ts index 66ef76d..6fd3c73 100644 --- a/packages/shared/src/types/web2/twitter.ts +++ b/packages/shared/src/types/web2/twitter.ts @@ -33,8 +33,19 @@ export interface TweetRaw { url: string }> } + url?: string type?: string media_url_https?: string }> } + media?: Array<{ + video_info?: { + variants: Array<{ + url: string + }> + } + type?: string + url?: string + media_url_https?: string + }> } diff --git a/packages/shared/src/types/web3-posting.ts b/packages/shared/src/types/web3-posting.ts index 8ee097f..491f251 100644 --- a/packages/shared/src/types/web3-posting.ts +++ b/packages/shared/src/types/web3-posting.ts @@ -1,4 +1,4 @@ -export type TPlatform = 'farcaster' | 'twitter' | 'lens' | 'bsky' | 'threads' +export type TPlatform = 'farcaster' | 'twitter' | 'lens' | 'bsky' | 'threads' | 'mastodon' export type TMedia = { farcaster: string diff --git a/packages/shared/src/utils/changeLog.ts b/packages/shared/src/utils/changeLog.ts index 8a5ba83..536bf81 100644 --- a/packages/shared/src/utils/changeLog.ts +++ b/packages/shared/src/utils/changeLog.ts @@ -1,4 +1,14 @@ export const recentChanges = [ + { + date: "08 August - 2024", + title: "Changes", + changes: [ + 'added mastodon integration on web app', + 'removed threads integration', + 'minor display changes', + 'added character count based on Twitter blue check for Twitter' + ] + }, { date: "22 Sept - 2024", title: "Changes", diff --git a/packages/shared/src/utils/evmTxs.ts b/packages/shared/src/utils/evmTxs.ts index bba0b7e..112ab48 100644 --- a/packages/shared/src/utils/evmTxs.ts +++ b/packages/shared/src/utils/evmTxs.ts @@ -272,7 +272,6 @@ export const checkNetwork = async ({ wgamiLib, stackAlertWarning, switchTo }: return false } const neededChains = [...wgamiLib.wgConfig.wagmiConfig.chains, newChain] - console.log(neededChains) newWgami = await prepareForTransaction({ stackAlertWarning, localWeb3Libs: web3Libs(), neededChains }) as typeof wgamiLib if (!newWgami) { stackAlertWarning && stackAlertWarning('Failed to intialize new chain') @@ -280,7 +279,6 @@ export const checkNetwork = async ({ wgamiLib, stackAlertWarning, switchTo }: } wgamiLib = newWgami } - console.log('Switching to chain: ', switchTo, ' from: ', chainId, newWgami) await wgamiLib.wgamiCore.switchChain(wgamiLib.wgConfig.wagmiConfig, { chainId: switchTo }) chainId = await wgamiLib.wgamiCore.getChainId(wgamiLib.wgConfig.wagmiConfig) diff --git a/packages/shared/src/utils/login-signup.ts b/packages/shared/src/utils/login-signup.ts index 736ba90..b7ccac6 100644 --- a/packages/shared/src/utils/login-signup.ts +++ b/packages/shared/src/utils/login-signup.ts @@ -20,12 +20,14 @@ type TloginMap = { isOwner: boolean bio: string, fullname: string + isTwitterBlue: boolean connected: { farcaster: boolean twitter: boolean lens: boolean bsky: boolean threads: boolean + mastodon: boolean } } @@ -427,6 +429,7 @@ export const onLogin = async ({ authToken: item.jwt, account: item.accountId, isOwner: item.isOwner, + isTwitterBlue: item.isTwitterBlue, bio: item.bio, fullname: item.fullname, fid: item?.fid || '' diff --git a/packages/shared/src/utils/post.ts b/packages/shared/src/utils/post.ts index a450c45..c4a63ca 100644 --- a/packages/shared/src/utils/post.ts +++ b/packages/shared/src/utils/post.ts @@ -79,12 +79,9 @@ const parseBodyMentionsAndChannels = (text: string, platform: string) => { } } if (platform === 'farcaster') { - console.log('farcaster, parsing channels') - console.log(text) const channelRegex = /(?!<.*?>)(^| |\n|\t|\r)+(\/.*?)(:|’|!|\*|"|'|`|\||\\|\&|\|\^|\%|\$|\#|\@|\(|\)|\[|\]| |,|\n|\t|\r|$)+?/gms const channel = text.matchAll(channelRegex) for (const match of channel) { - console.log('match[1]', match) if (match[2]) { const e = match[2] const channelHandle = `${e}` @@ -131,7 +128,6 @@ const parseMedia = (mediaObject: Web3Media, linkPreviews: linkPreviewTypeEx[], e return } if (isImage(e.url, e?.images ?? [])) { - console.log('H1') retArr.push({ type: 'image', url: parseIpfs(e.url) }) return } else if (isVideo(e.url)) { diff --git a/packages/shared/src/utils/requests/accounts.ts b/packages/shared/src/utils/requests/accounts.ts index 4ff89be..60680ad 100644 --- a/packages/shared/src/utils/requests/accounts.ts +++ b/packages/shared/src/utils/requests/accounts.ts @@ -77,7 +77,8 @@ export const createUserData = async (userId: string, refreshWeight = false) => { ethInfo, web3Handles, connected, - isPro + isPro, + isTwitterBlue } = d.data const returnData = { userData: { @@ -94,6 +95,7 @@ export const createUserData = async (userId: string, refreshWeight = false) => { web3Handles, twitterInfo, isPro: isPro, + isTwitterBlue: isTwitterBlue, connected: connected || { farcaster: false, twitter: false, @@ -298,6 +300,7 @@ export const getConnected = async (store: IMainStore, account: string, address?: if (!uD.error) { connected = uD.data.userData.connected localStorage.setItem('connected', JSON.stringify(connected)) + store.userData.isTwitterBlue = uD.data.userData.isTwitterBlue } else { connected = { farcaster: false, @@ -333,7 +336,8 @@ export const setConnected = (store: IMainStore, platform: TPlatform, value: bool twitter: false, lens: false, bsky: false, - threads: false + threads: false, + mastodon: false } } store.userData.connected[platform] = value diff --git a/packages/shared/src/utils/requests/bsky.ts b/packages/shared/src/utils/requests/bsky.ts index d705f10..7b95567 100644 --- a/packages/shared/src/utils/requests/bsky.ts +++ b/packages/shared/src/utils/requests/bsky.ts @@ -2,7 +2,9 @@ import type { IMainStore } from 'shared/src/types/store' import type { Ref } from 'vue' import { fetchWAuth } from '../auth' -const API_BASE = import.meta.env.VITE_YUP_API_BASE; +export const API_BASE = import.meta.env.VITE_YUP_API_BASE; +// export const API_BASE = import.meta.env.VITE_YUP_API_BASE.replace('api.yup.io', 'fstun.flashsoft.eu'); + export const BLUESKY_SERVICE_URL = 'https://bsky.social'; @@ -12,7 +14,6 @@ export const disconnectBlueSky = async ({ stackAlertSuccess, isDisconnectFromBlueSky, isConnectedToBsky, - apiBase = API_BASE, }: { store: IMainStore stackAlertError: (msg: string) => void @@ -24,7 +25,7 @@ export const disconnectBlueSky = async ({ if (isDisconnectFromBlueSky.value) return isDisconnectFromBlueSky.value = true - const req = await fetchWAuth(store, `${apiBase}/web3-auth`, { + const req = await fetchWAuth(store, `${API_BASE}/web3-auth`, { method: 'DELETE', body: JSON.stringify({ platforms: ['bsky'] @@ -54,7 +55,6 @@ export const connectBlueSky = async ({ stackAlertSuccess, isConnectedToBsky, isConnectToBsky, - apiBase = API_BASE, settingsModal }: { store: IMainStore @@ -87,11 +87,17 @@ export const connectBlueSky = async ({ const data = { auth: { - bsky + bsky: { + session: bsky, + credentials: { + identity: bskyUser, + appPass: bskyAppPassword + } + } } } - const reqSave = await fetchWAuth(store, `${apiBase}/web3-auth`, { + const reqSave = await fetchWAuth(store, `${API_BASE}/web3-auth`, { method: 'POST', body: JSON.stringify(data) }) diff --git a/packages/shared/src/utils/requests/crossPost.ts b/packages/shared/src/utils/requests/crossPost.ts index ef05d88..894bbcf 100644 --- a/packages/shared/src/utils/requests/crossPost.ts +++ b/packages/shared/src/utils/requests/crossPost.ts @@ -2,12 +2,13 @@ import type { TPlatform } from "shared/src/types/web3-posting"; import type { IMainStore } from "shared/src/types/store"; -export const getMaxCharCount = (platforms: TPlatform[]) => { - if (platforms.includes('twitter')) return 280 +export const getMaxCharCount = (platforms: TPlatform[], isTwitterBlue = false) => { + if (platforms.includes('twitter')) return isTwitterBlue ? 2000 : 280 else if (platforms.includes('bsky')) return 300 else if (platforms.includes('farcaster')) return 1024 else if (platforms.includes('lens')) return 1024 else if (platforms.includes('threads')) return 500 + else if (platforms.includes('mastodon')) return 500 return 1000 } diff --git a/packages/shared/src/utils/requests/farcaster.ts b/packages/shared/src/utils/requests/farcaster.ts index 3327c5f..97698ff 100644 --- a/packages/shared/src/utils/requests/farcaster.ts +++ b/packages/shared/src/utils/requests/farcaster.ts @@ -2,7 +2,7 @@ import { fetchWAuth } from '../auth' import type { IMainStore } from 'shared/src/types/store' import { ref, Ref } from 'vue' import { prepareForTransaction, TWeb3Libs } from '../evmTxs' -import { getFidByToken, getFidByAddress } from 'shared/src/utils/farcaster'; +import { getFidByAddress } from 'shared/src/utils/farcaster'; // import { FCSendCast } from "shared/src/utils/farcaster"; // import { digestSha256 } from "shared/src/utils/misc"; import { wait } from '../time' diff --git a/packages/shared/src/utils/requests/mastodon.ts b/packages/shared/src/utils/requests/mastodon.ts index 569c14e..e99e1c6 100644 --- a/packages/shared/src/utils/requests/mastodon.ts +++ b/packages/shared/src/utils/requests/mastodon.ts @@ -1,43 +1,168 @@ -function dec2hex (dec: any) { - return ('0' + dec.toString(16)).slice(-2); -} -export function verifier () { - var array = new Uint32Array(56 / 2); - window.crypto.getRandomValues(array); - return Array.from(array, dec2hex).join(''); -} -function sha256 (plain: string) { - // returns promise ArrayBuffer - const encoder = new TextEncoder(); - const data = encoder.encode(plain); - return window.crypto.subtle.digest('SHA-256', data); +import type { IMainStore } from 'shared/src/types/store' +import type { Ref } from 'vue' +import { fetchWAuth } from '../auth' +import { wait } from '../time'; + +export const API_BASE = import.meta.env.VITE_YUP_API_BASE; +// export const API_BASE = import.meta.env.VITE_YUP_API_BASE.replace('api.yup.io', 'fstun.flashsoft.eu'); + +export const getMastodonAuthUrl = async ({ + store, + instanceURL +}: { + store: IMainStore + instanceURL: string +}) => { + const req = await fetchWAuth(store, `${API_BASE}/mastodon/get-auth-url?instanceURL=${instanceURL}`, { + method: 'GET', + }) + + if (!req.ok) { + return '' + } + + const url = await req.json() + + return url.url as string } -function base64urlencode (a: any) { - let str = ''; - const bytes = new Uint8Array(a); - const len = bytes.byteLength; - for (var i = 0; i < len; i++) { - str += String.fromCharCode(bytes[i]); + +export const isMastodonConfirmed = async () => { + const req = await fetch(`${API_BASE}/mastodon/is-confirmed`, { + method: 'GET', + }) + + if (!req.ok) { + return false } - return btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); + + const data = await req.json() + + return !!data?.confirmed as boolean } -export async function generateCodeChallenge (v: string) { - const hashed = await sha256(v); - return base64urlencode(hashed); + +export const connectToMastodon = async ({ + store, + instanceURL, + isConnectedToMastodon, + isConnectToMastodon, + stackAlertError, + stackAlertSuccess, + settingsModal, + cancelWaiting +}: { + store: IMainStore + instanceURL: string + isConnectedToMastodon: Ref