Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/dappforce/polkaverse into d…
Browse files Browse the repository at this point in the history
…eploy/qr
  • Loading branch information
teodorus-nathaniel committed Mar 20, 2024
2 parents 4f48c10 + 531fd1e commit e235814
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 55 deletions.
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ updates:
reviewers:
- 'oap75'
- 'olehmell'
- "iv1310"
schedule:
interval: 'weekly'
commit-message:
Expand Down
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,61 @@ PolkaVerse is a niche social site built on the Subsocial network. It focuses on

Visit Subsocial's [website](https://subsocial.network) to learn more about the project.

## Guide to build and deploy polkaverse

### Build the docker images
1. Prepare the [dockerfile](./docker/Dockerfile) and adjust the config if needed.
2. Build the image in local with this command and please ensure to add build argument.
```bash
$ docker build --build-arg GH_GA_ID=valueREDACTED --build-arg GH_APP_KIND=valueREDACTED --build-arg GH_HCAPTCHA_SITE_KEY=valueREDACTED --build-arg GH_AMP_ID=valueREDACTED --build-arg GH_OFFCHAIN_SIGNER_URL=valueREDACTED --build-arg GH_CONNECTION_KIND=valueREDACTED --build-arg GH_SELLER_CLIENT_ID=valueREDACTED --build-arg GH_SERVER_MNEMONIC==valueREDACTED --build-arg GH_SELLER_TOKEN_SIGNER=valueREDACTED --build-arg GH_NEXT_PUBLIC_DATAHUB_QUERY_URL=valueREDACTED --build-arg GH_NEXT_PUBLIC_DATAHUB_SUBSCRIPTION_URL=valueREDACTED --build-arg GH_DATAHUB_QUEUE_URL=valueREDACTED --build-arg GH_DATAHUB_QUEUE_TOKEN=valueREDACTED -t polkaverse-docker-image:latest .
```
Notes:
Please execute the build process with theses build arguments, you need to specify the value.
* GH_GA_ID=valueREDACTED
* GH_APP_KIND=valueREDACTED
* GH_HCAPTCHA_SITE_KEY=valueREDACTED
* GH_AMP_ID=valueREDACTED
* GH_OFFCHAIN_SIGNER_URL=valueREDACTED
* GH_CONNECTION_KIND=valueREDACTED
* GH_SELLER_CLIENT_ID=valueREDACTED
* GH_SELLER_TOKEN_SIGNER=valueREDACTED
* GH_SERVER_MNEMONIC=valueREDACTED
* GH_NEXT_PUBLIC_DATAHUB_QUERY_URL=valueREDACTED
* GH_NEXT_PUBLIC_DATAHUB_SUBSCRIPTION_URL=valueREDACTED
* GH_DATAHUB_QUEUE_URL=valueREDACTED
* GH_DATAHUB_QUEUE_TOKEN=valueREDACTED
3. Then check the docker images that has been builded.
```bash
$ docker images | grep "polkaverse"
```

### Run the container with docker-compose
1. To run the docker images with docker-compose, please prepare the docker-compose.yaml config file at first.
```yaml
# docker-compose.yml
version: "3"
services:
web-ui:
image: polkaverse-docker-image:latest
ports:
- "3003:3003" # Application port
container_name: polkaverse-web-app
restart: on-failure
```
```bash
$ docker-compose -f docker-compose.yaml up -d
```
2. Check the running container with this command.
```bash
$ docker-compose ps
$ docker-compose logs
```
3. Test to connect to the application.
```bash
$ curl -I http://localhost:3003
```


## Run locally

Clone this repo:
Expand Down
7 changes: 0 additions & 7 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,3 @@ services:
container_name: subsocial-web-ui
restart: on-failure
network_mode: "host"

nginx:
build: ./nginx
container_name: subsocial-proxy
image: dappforce/subsocial-proxy:latest
restart: on-failure
network_mode: "host"
9 changes: 0 additions & 9 deletions docker/nginx/Dockerfile

This file was deleted.

16 changes: 0 additions & 16 deletions docker/nginx/default.conf

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/activity/MyNotifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ const NOTIFICATION_TITLE = 'My notifications'

export const MyNotifications = () => {
const myAddress = useMyAddress()
const isInitializedProxy = useMyAccount(state => state.isInitializedProxy)
const isInitialized = useMyAccount(state => state.isInitialized)

if (!myAddress) return <NotAuthorized />

return (
<PageContent meta={{ title: NOTIFICATION_TITLE }} className={styles.NotificationPage}>
{!isInitializedProxy ? (
{!isInitialized ? (
<Loading center />
) : (
<Notifications title={NOTIFICATION_TITLE} address={myAddress} />
Expand Down
11 changes: 5 additions & 6 deletions src/components/activity/NotifCounter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function InnerNotifCounterProvider(props: React.PropsWithChildren<{}>) {
storageKeyType: 'user',
})
const myAddress = useMyAddress()
const isInitializedProxy = useMyAccount(state => state.isInitializedProxy)
const isInitialized = useMyAccount(state => state.isInitialized)

const [unreadCount, setUnreadCount] = useState(0)
const [previousLastRead, setPreviousLastRead] = useState<string | null>(null)
Expand All @@ -47,15 +47,15 @@ function InnerNotifCounterProvider(props: React.PropsWithChildren<{}>) {
}

useEffect(() => {
if (!isInitializedProxy || !myAddress) return
if (!isInitialized || !myAddress) return
;(async () => {
const unreadCount = await getNotificationsCount({
address: myAddress,
afterDate: getDataForAddress(myAddress) || undefined,
})
setUnreadCount(unreadCount)
})()
}, [myAddress, isInitializedProxy])
}, [myAddress, isInitialized])

return (
<NotifCounterContext.Provider
Expand Down Expand Up @@ -99,12 +99,11 @@ const Bell = ({ unreadCount }: NotificationsProps) => (

export const NotificationsBell = ({ unreadCount }: NotificationsProps) => {
const myAddress = useMyAddress()
const isInitializedProxy = useMyAccount(state => state.isInitializedProxy)
const isInitialized = useMyAccount(state => state.isInitialized)
const { getLastReadNotif } = useNotifCounterContext()

if (!enableNotifications) return null
if (!unreadCount || unreadCount <= 0 || !isInitializedProxy)
return <Bell unreadCount={unreadCount} />
if (!unreadCount || unreadCount <= 0 || !isInitialized) return <Bell unreadCount={unreadCount} />

const showWithoutCount = !getLastReadNotif(myAddress)

Expand Down
25 changes: 19 additions & 6 deletions src/components/auth/MyAccountsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ import { fetchChainsInfo } from 'src/rtk/features/chainsInfo/chainsInfoSlice'
import { fetchProfileSpace } from 'src/rtk/features/profiles/profilesSlice'
import { fetchEntityOfSpaceIdsByFollower } from 'src/rtk/features/spaceIds/followedSpaceIdsSlice'
import { useMyAccount } from 'src/stores/my-account'
import { AnyAccountId, EmailAccount } from 'src/types'
import { AnyAccountId, DataSourceTypes, EmailAccount } from 'src/types'
import useSubsocialEffect from '../api/useSubsocialEffect'
import { useAccountSelector } from '../profile-selector/AccountSelector'
import { useIsMobileWidthOrDevice } from '../responsive'
import { reloadSpaceIdsFollowedByAccount } from '../spaces/helpers/reloadSpaceIdsFollowedByAccount'
import { equalAddresses } from '../substrate'
import { getSignerToken, isProxyAdded } from '../utils/OffchainSigner/ExternalStorage'
import { getSubsocialApi } from '../utils/SubsocialConnect'
import { desktopWalletConnect, mobileWalletConection } from './utils'
//
// Types
Expand Down Expand Up @@ -101,6 +102,7 @@ export function MyAccountsProvider(props: React.PropsWithChildren<{}>) {
const reloadAccountIdsByFollower = useCreateReloadAccountIdsByFollower()
const reloadSpaceIdsRelatedToAccount = useCreateReloadSpaceIdsRelatedToAccount()
const address = useMyAddress()
const isInitialized = useMyAccount(state => state.isInitialized)
const { getAllEmailAccounts } = useEmailAccount()
const [, recheck] = useReducer(x => (x + 1) % 16384, 0)
const isMobile = useIsMobileWidthOrDevice()
Expand Down Expand Up @@ -132,7 +134,7 @@ export function MyAccountsProvider(props: React.PropsWithChildren<{}>) {
}, [status])

useSubsocialEffect(
({ substrate, subsocial }) => {
({ substrate }) => {
if (!address) return

let unsubAccountInfo: UnsubscribeFn
Expand All @@ -141,13 +143,10 @@ export function MyAccountsProvider(props: React.PropsWithChildren<{}>) {
const readyApi = await substrate.api

Promise.all([
reloadSpaceIdsFollowedByAccount({ substrate, dispatch: dispatch, account: address }),
reloadSpaceIdsFollowedByAccount({ substrate, dispatch, account: address }),
reloadAccountIdsByFollower(address),
reloadSpaceIdsRelatedToAccount(address),
dispatch(fetchProfileSpace({ id: address, api: subsocial })),
dispatch(fetchEntityOfSpaceIdsByFollower({ id: address, reload: true, api: subsocial })),
dispatch(fetchChainsInfo({})),
dispatch(fetchAddressLikeCounts({ address, postIds: null })),
])

unsubAccountInfo = await readyApi.query.system.account(
Expand All @@ -166,6 +165,20 @@ export function MyAccountsProvider(props: React.PropsWithChildren<{}>) {
},
[address],
)
useEffect(() => {
if (!isInitialized || !address) return
dispatch(
fetchEntityOfSpaceIdsByFollower({
id: address,
dataSource: DataSourceTypes.SQUID,
api: getSubsocialApi(),
}),
)
dispatch(
fetchProfileSpace({ id: address, api: getSubsocialApi(), dataSource: DataSourceTypes.SQUID }),
)
dispatch(fetchAddressLikeCounts({ address, postIds: null }))
}, [address, isInitialized])

const state = useMemo(
() => ({ accounts, status, emailAccounts }),
Expand Down
18 changes: 16 additions & 2 deletions src/components/main/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { useCallback, useEffect, useState } from 'react'
import config from 'src/config'
import { useSendEvent } from 'src/providers/AnalyticContext'
import { getInitialPropsWithRedux } from 'src/rtk/app'
import { useAppSelector } from 'src/rtk/app/store'
import { useFetchTotalStake } from 'src/rtk/features/creators/totalStakeHooks'
import { selectSpaceIdsByFollower } from 'src/rtk/features/spaceIds/followedSpaceIdsSlice'
import { useMyAccount } from 'src/stores/my-account'
import { PostKind } from 'src/types/graphql-global-types'
import { getAmountRange } from 'src/utils/analytics'
import { useIsSignedIn, useMyAddress } from '../auth/MyAccountsContext'
Expand Down Expand Up @@ -147,9 +150,20 @@ const TabsHomePage = ({
setFiltersInUrl(router, key, filterType, { ref: refId })
}

const isInitialized = useMyAccount(state => state.isInitialized)
const followedIds = useAppSelector(state => {
return selectSpaceIdsByFollower(state, myAddress)
})

const isLoadingFollowedIds = followedIds === undefined
useEffect(() => {
onChangeKey(tab)
}, [isSignedIn])
if (!isInitialized || !isSignedIn || isLoadingFollowedIds) return
if (followedIds.length === 0) {
setFiltersInUrl(router, 'posts', { type: 'hot' }, { ref: refId })
} else {
onChangeKey(tab)
}
}, [followedIds, isInitialized])

const handleScroll = () => {
const currentScrollPos = window.pageYOffset
Expand Down
7 changes: 5 additions & 2 deletions src/components/posts/editor/FullEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ const FullEditor = ({
<Row className={styles.EditorContainer} gutter={[16, 16]} justify='center'>
<Col
style={{ minWidth: 0 }}
className={clsx('d-flex align-items-stretch flex-column', styles.EditorBodyContent)}
className={clsx(
'd-flex align-items-stretch flex-column',
styles.EditorBodyContentContainer,
)}
>
<Card className={clsx(styles.EditorBodyContent, 'mb-3')}>
<Form.Item
Expand Down Expand Up @@ -288,8 +291,8 @@ const FullEditor = ({
type='primary'
block
className='mt-3'
disabled={publishIsDisable}
{...txProps}
disabled={publishIsDisable || txProps.disabled}
/>
</Card>
{!totalStake?.hasStakedEnough && (
Expand Down
4 changes: 2 additions & 2 deletions src/components/posts/editor/ModalEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const PostEditorModalBody = ({
const [spaceId, setSpaceId] = useState<string>(defaultSpace)

const { loading } = useFetchSpaces({ ids: spaceIds, dataSource: DataSourceTypes.SQUID })
const { saveContent } = useAutoSaveFromForm({ entity: 'post' })
const { savedData, saveContent } = useAutoSaveFromForm({ entity: 'post' })

useEffect(() => {
setSpaceId(defaultSpace)
Expand Down Expand Up @@ -201,7 +201,7 @@ export const PostEditorModalBody = ({
)

return (
<Form form={form} className='my-0' onFieldsChange={() => saveDraft()}>
<Form form={form} className='my-0' initialValues={savedData} onFieldsChange={() => saveDraft()}>
<SpaceSelector />
<Form.Item name={fieldName('body')} className='my-3'>
{/* value and onChange are provided by Form.Item */}
Expand Down
3 changes: 3 additions & 0 deletions src/components/posts/editor/index.module.sass
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
\:global .ant-tabs-nav
margin: 0

.EditorBodyContentContainer
width: $max_width_content

.AdvancedBody
width: 325px

Expand Down
2 changes: 1 addition & 1 deletion src/components/posts/pinned-post.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getLastestPostIdsInSpace } from 'src/graphql/apis'
import { GqlClient } from 'src/graphql/ApolloProvider'

const PINNED_POST_IDS: string[] = ['91982']
const PINNED_POST_IDS: string[] = ['100229']
export const PINNED_POST_ID = PINNED_POST_IDS[Math.floor(Math.random() * PINNED_POST_IDS.length)]

const COMMUNITY_SPACE_ID = '1244'
Expand Down
12 changes: 10 additions & 2 deletions src/stores/my-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ import { useAnalytics } from './analytics'
import { create } from './utils'

type State = {
/**
* `isInitialized` is `true` when the addresses (address & parentProxyAddress) are all set
* but there is still a case where the proxy is invalid and user will be logged out after that
*/
isInitialized?: boolean
/**
* `isInitializedProxy` is `true` when the initialization process is all done, including checking the proxy
*/
isInitializedProxy?: boolean

preferredWallet: any | null
Expand Down Expand Up @@ -148,13 +155,14 @@ export const useMyAccount = create<State & Actions>()((set, get) => ({
accountStorage.remove()
accountAddressStorage.remove()
set({ address: null })
} else {
accountAddressStorage.set(address)
}
}

set({ isInitialized: true })
set({ isInitialized: true, parentProxyAddress: parentProxyAddress || undefined })

if (parentProxyAddress) {
set({ parentProxyAddress })
try {
const proxies = await getProxies(parentProxyAddress)
const currentProxy = proxies.find(({ address }) => address === get().address)
Expand Down

0 comments on commit e235814

Please sign in to comment.