1
0
mirror of https://github.com/ragestudio/comty.git synced 2025-07-11 02:04:15 +00:00

Co-authored-by: genericgooglo <chippotato39@gmail.com>

This commit is contained in:
srgooglo 2020-04-01 02:04:43 +02:00
parent 93c90e4c88
commit f9e3014c13
40 changed files with 712 additions and 476 deletions

2
.gitignore vendored

@ -21,4 +21,4 @@ package-lock.json
# jslingui # jslingui
src/locales/_build src/locales/_build
src/locales/**/*.js src/locales/**/*.js
recover/ android/

@ -1,112 +0,0 @@
// Modules to control application life and create native browser window
const path = require('path');
const exec = require('child_process').exec;
const { app, BrowserWindow, ipcMain } = require('electron');
const isDev = process.env.NODE_ENV === 'development';
ipcMain.on('print', async (event, arg) => {
// todo:下载网络文件到本地打印
arg.pdf = `${__dirname}/ReferenceCard.pdf`;
const fileUrl = arg.pdf;
switch (process.platform) {
case 'darwin':
case 'linux':
await exec('lp ' + fileUrl, (e) => {
if (e) throw e;
});
event.reply('asynchronous-reply', 'print done!');
break;
case 'win32':
await exec('print ' + fileUrl, {
windowsHide: true,
}, (e) => {
if (e) throw e;
});
event.reply('asynchronous-reply', 'print done!');
break;
default:
event.reply('asynchronous-reply', 'print failed!');
throw new Error(
'Platform not supported.',
);
}
});
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
for (const name of extensions) {
try {
await installer.default(installer[name], forceDownload);
} catch (e) {
console.log(`Error installing ${name} extension: ${e.message}`);
}
}
};
async function createWindow() {
isDev && await installExtensions();
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1000,
height: 600,
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'preload.js'),
},
});
// and load the index.html of the app.
if (isDev) {
mainWindow.loadURL('http://localhost:8000/');
// Open the DevTools only if in development mode.
mainWindow.webContents.openDevTools();
} else {
const rdurl = path.join(__dirname, '../dist/index.html') // path.join(__dirname, '../dist/index.html')
console.log(rdurl)
mainWindow.loadFile(rdurl)
}
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
}
// hot reload
isDev && require('electron-reload')(__dirname, {
electron: require(`${__dirname}/../node_modules/electron`),
ignored: /node_modules|[\/\\]\./,
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function() {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') app.quit();
});
app.on('activate', function() {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow();
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

@ -1,8 +0,0 @@
// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener('DOMContentLoaded', () => {
for (const versionType of ['chrome', 'electron', 'node']) {
console.log(`${versionType}-version`, process.versions[versionType]);
}
});

@ -1,3 +0,0 @@
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

8
capacitor.config.json Normal file

@ -0,0 +1,8 @@
{
"appId": "com.ragestudio.comty",
"appName": "comty-development",
"bundledWebRuntime": false,
"npmClient": "npm",
"webDir": "dist",
"cordova": {}
}

@ -3,5 +3,4 @@ module.exports = {
server_key: server_key:
'f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768', 'f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768',
secretOrKey: 'secret',
} }

@ -9,6 +9,7 @@ module.exports = {
DarkLogoPath: '/dark_logo.svg', DarkLogoPath: '/dark_logo.svg',
resource_bundle: 'light_ng', resource_bundle: 'light_ng',
sync_server: 'http://eu653-node.ragestudio.net:5500',
/* Layout configuration, specify which layout to use for route. */ /* Layout configuration, specify which layout to use for route. */
layouts: [ layouts: [

@ -3,7 +3,7 @@
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4", "UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
"title": "Comty™", "title": "Comty™",
"DevBuild": true, "DevBuild": true,
"version": "0.2.30", "version": "0.2.32",
"stage": "A1", "stage": "A1",
"description": "", "description": "",
"main": "app/main.js", "main": "app/main.js",
@ -18,6 +18,9 @@
"dependencies": { "dependencies": {
"@ant-design/compatible": "^1.0.1", "@ant-design/compatible": "^1.0.1",
"@ant-design/pro-layout": "^5.0.6", "@ant-design/pro-layout": "^5.0.6",
"@capacitor/android": "^1.5.2",
"@capacitor/cli": "^1.5.2",
"@capacitor/core": "^1.5.2",
"@lingui/react": "^2.9.1", "@lingui/react": "^2.9.1",
"@material-ui/core": "^4.9.3", "@material-ui/core": "^4.9.3",
"@material-ui/icons": "^4.9.1", "@material-ui/icons": "^4.9.1",

@ -16,6 +16,10 @@ export function QueryRuntime() {
const validBackup = ycore.validate.backup() const validBackup = ycore.validate.backup()
if (!validBackup) ycore.make_data.backup() if (!validBackup) ycore.make_data.backup()
ycore.sync.listen((data) => {
})
} }
export function SetupApp() { export function SetupApp() {
@ -77,6 +81,9 @@ export const FeedHandler = {
goToElement: post_id => { goToElement: post_id => {
RenderFeed.goToElement(post_id) RenderFeed.goToElement(post_id)
}, },
sync: data => {
RenderFeed.sync(data)
}
} }
export const LoginPage = { export const LoginPage = {

@ -1,10 +1,50 @@
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd'
import * as Icons from '@ant-design/icons'
import io from 'socket.io-client' import io from 'socket.io-client'
import config from 'config'
var endpoint = config.sync_server;
var socket = io('http://localhost:5500');
export const sync = { export const sync = {
emmitPost: () => { listen: (callback) => {
socket.emit('new'); let conn_overrun_tick = 0;
const socket = io(endpoint);
socket.on('connect_error', (error) => {
conn_overrun_tick ++
ycore.yconsole.log('Overrun tick => ',conn_overrun_tick)
if (conn_overrun_tick == 1) {
antd.notification.open({
onClose: () => conn_overrun_tick = 0,
duration: 15,
message: 'Disconected from server!',
description: 'Attempting to reconnect...',
icon: <Icons.LoadingOutlined spin />,
});
}
});
socket.on('connect', () => {
conn_overrun_tick = 0
antd.message.success('Connected to the server')
});
socket.on('pull_event', function (data) {
console.log('SOCKET => ',data)
callback(data)
});
},
FeedListen: (callback) => {
const socket = io(endpoint);
socket.on('pull_event', function (data) {
callback(data)
});
},
emmitPost: (last_id) => {
const socket = io(endpoint);
socket.emit('push_event', last_id);
} }
} }

@ -1,12 +1,12 @@
import * as ycore from 'ycore' import * as ycore from 'ycore'
import Cookies from 'ts-cookies' import Cookies from 'ts-cookies'
import keys from '../../../../config/keys.js' import {server_key} from '../../../../config/keys.js'
var jwt = require('jsonwebtoken') var jwt = require('jsonwebtoken')
export const token_data = { export const token_data = {
set: (value, callback) => { set: (value, callback) => {
jwt.sign(value, keys.secretOrKey, (err, token) => { jwt.sign(value, server_key, (err, token) => {
err ? null : Cookies.set('cid', token) err ? null : Cookies.set('cid', token)
return callback(true) return callback(true)
}) })

@ -42,11 +42,7 @@ localforage.config({
storeName: package_json.name, storeName: package_json.name,
}) })
var socket = io('http://localhost:5500');
socket.on('post_feed', function (data) {
console.log('SOCKET => ',data)
});
/** /**
* Convert a base64 string in a Blob according to the data and contentType. * Convert a base64 string in a Blob according to the data and contentType.

@ -144,7 +144,7 @@ export default class Secondary extends React.PureComponent {
renderPost = payload => { renderPost = payload => {
const post_data = JSON.parse(payload)['post_data'] const post_data = JSON.parse(payload)['post_data']
return <__priPost payload={post_data} /> return <__priPost isMobile={this.props.isMobile} payload={post_data} />
} }
renderComments = payload => { renderComments = payload => {
@ -193,26 +193,29 @@ export default class Secondary extends React.PureComponent {
} }
render() { render() {
const { userData } = this.props const { userData, isMobile } = this.props
if (!this.state.loading) return ( if (!this.state.loading) return (
<> <>
<div className={styles.__secondary_colider}></div> {isMobile? null : <div className={styles.__secondary_colider}></div>}
<div <div
id="secondary_layout"
className={classnames(styles.secondary_wrapper, { className={classnames(styles.secondary_wrapper, {
[styles.mobile]: isMobile,
[styles.active]: this.state.swap, [styles.active]: this.state.swap,
[styles.half]: this.state.half, [styles.half]: this.state.half,
[styles.unique]: this.state.unique, [styles.unique]: this.state.unique,
})} })}
> >
{isMobile? null :
<div className={styles.secondary_userholder}> <div className={styles.secondary_userholder}>
<div className={styles.notif_box}> <div className={styles.notif_box}>
<h1>{this.state.notification_data.length}</h1> <h1>{this.state.notification_data.length}</h1>
</div>
<img
onClick={() => ycore.router.go(`@${userData.username}`)}
src={userData.avatar}
/>
</div> </div>
<img
onClick={() => ycore.router.go(`@${userData.username}`)}
src={userData.avatar}
/>
</div>}
<div <div
className={styles.secondary_layout_bg} className={styles.secondary_layout_bg}
@ -234,6 +237,7 @@ export default class Secondary extends React.PureComponent {
<div <div
className={classnames(styles.secondary_container_2, { className={classnames(styles.secondary_container_2, {
[styles.mobile]: isMobile,
[styles.active]: this.state.swap, [styles.active]: this.state.swap,
})} })}
> >

@ -20,6 +20,8 @@
display: flex; display: flex;
&.active { &.active {
width: @secondary_wrapper_showFull_width; width: @secondary_wrapper_showFull_width;
>.secondary_container_1 { >.secondary_container_1 {
@ -30,6 +32,25 @@
//} //}
} }
&.mobile {
height: 45px;
width: 100%;
bottom: -70px;
top: unset;
overflow-y: hidden;
overflow-x: hidden;
>.secondary_layout_bg{
border-radius: 27px 27px 0 0;
overflow-y: hidden;
overflow-x: scroll;
}
&.active {
bottom: 0;
height: 100vh;
}
}
&.half { &.half {
width: @secondary_wrapper_showHalf_width; width: @secondary_wrapper_showHalf_width;
} }
@ -40,7 +61,7 @@
padding-right: 90px; padding-right: 90px;
} }
} }
transition: width @__Global_SwapAnimDuration ease-in-out; transition: all @__Global_SwapAnimDuration ease-in-out;
} }
@ -133,7 +154,7 @@
background-color: @secondary_container_2_backgroud; background-color: @secondary_container_2_backgroud;
border-radius: 32px 0 0 32px; border-radius: 32px 0 0 32px;
&.active { &.active {
width: 400px; width: 400px;
opacity: 1; opacity: 1;
@ -142,6 +163,17 @@
width: 600px width: 600px
} }
} }
&.mobile{
overflow-x: hidden;
&.active {
width: 400px;
right: -120px;
opacity: 1;
}
}
transition: all @__Global_SwapAnimDuration ease-in-out; transition: all @__Global_SwapAnimDuration ease-in-out;

@ -24,19 +24,23 @@ const VerifiedBadge = () => (
export class __priPost extends React.Component { export class __priPost extends React.Component {
renderContent(payload) { renderContent(payload) {
const { id, postText, postFile_full, post_time, publisher } = payload const { id, postText, postFile_full, post_time, publisher } = payload
const {isMobile}= this.props
if (!postFile_full) { if (!postFile_full) {
return ( return (
<div className={styles.postContent_OnlyText}> <div className={styles.contentWrapper}>
<PostCard payload={payload} /> {postText ? (
</div> <div className={styles.postContent}>
<h3 dangerouslySetInnerHTML={{ __html: postText }} />{' '}
</div>
) : null}
</div>
) )
} }
return ( return (
<div className={styles.contentWrapper}> <div className={styles.contentWrapper}>
{postFile_full ? <MediaPlayer file={postFile_full} /> : null} {postFile_full ? <MediaPlayer isMobile={isMobile} entire={true} file={postFile_full} /> : null}
{postText ? ( {postText ? (
<div className={styles.postContent}> <div className={styles.postContent}>
{' '}
<h3 dangerouslySetInnerHTML={{ __html: postText }} />{' '} <h3 dangerouslySetInnerHTML={{ __html: postText }} />{' '}
</div> </div>
) : null} ) : null}
@ -45,7 +49,7 @@ export class __priPost extends React.Component {
} }
render() { render() {
const payload = this.props.payload const {payload} = this.props
if (!payload) { if (!payload) {
return <h1>This post not exists!!!</h1> return <h1>This post not exists!!!</h1>
} }

@ -1,77 +1,29 @@
import React, { PureComponent } from 'react' import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons' import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import { withI18n, Trans } from '@lingui/react' import { withI18n, Trans } from '@lingui/react'
import { config } from 'utils' import styles from './default.less'
import styles from './Sider.less'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import router from 'umi/router' import CustomIcons from '../../CustomIcons'
import CustomIcons from '../CustomIcons'
@withI18n() @withI18n()
class Sider extends PureComponent { export default class Sider_Default extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
selectedKey: '',
isHover: false,
collapsedWidth: '70',
}
}
isSelected(key){
if (this.state.selectedKey == (key)) {
return true
}
return false
}
onClickFunctions = {
saves: (e) => {
this.setState({selectedKey: e})
ycore.router.go('saves')
},
events: (e) => {
this.setState({selectedKey: e})
ycore.router.go('events')
},
marketplace: (e) => {
this.setState({selectedKey: e})
ycore.router.go('marketplace')
},
explore: (e) => {
this.setState({selectedKey: e})
ycore.router.go('main')
},
}
handleClickMenu = e => {
e.key === 'SignOut' && ycore.app_session.logout()
e.key === 'general_settings' && ycore.router.go('settings')
e.key === 'saves' && this.onClickFunctions.saves(e.key)
e.key === 'events' && this.onClickFunctions.events(e.key)
e.key === 'marketplace' && this.onClickFunctions.marketplace(e.key)
e.key === 'explore' && this.onClickFunctions.explore(e.key)
e.key === 'debug_area' && ycore.router.go('__m')
}
render() { render() {
const { handleClickMenu, logo } = this.props
return ( return (
<div className={styles.left_sider_wrapper}> <div className={styles.left_sider_wrapper}>
<antd.Layout.Sider <antd.Layout.Sider
trigger={null} trigger={null}
collapsed collapsed
width="90" collapsedWidth='80'
className={styles.left_sider_container} className={styles.left_sider_container}
> >
<div className={styles.left_sider_brandholder}> <div className={styles.left_sider_brandholder}>
<img <img
onClick={() => ycore.router.go('main')} onClick={() => ycore.router.go('main')}
src={config.LogoPath} src={logo}
/> />
</div> </div>
@ -81,17 +33,17 @@ class Sider extends PureComponent {
selectable={false} selectable={false}
className={styles.left_sider_menuItems} className={styles.left_sider_menuItems}
mode="vertical" mode="vertical"
onClick={this.handleClickMenu} onClick={handleClickMenu}
> >
<antd.Menu.Item key="explore"> <antd.Menu.Item key="explore">
<Icons.CompassTwoTone twoToneColor={this.isSelected('explore')? "#28c35d" : "#85858570"} /> <Icons.CompassTwoTone twoToneColor={"#28c35d"} />
<Trans> <Trans>
<span>Explore</span> <span>Explore</span>
</Trans> </Trans>
</antd.Menu.Item> </antd.Menu.Item>
<antd.Menu.Item key="saves"> <antd.Menu.Item key="saves">
<Icon component={this.isSelected('saves')? CustomIcons.SavedPostColor : CustomIcons.SavedPostGrey} /> <Icon component={CustomIcons.SavedPostColor} />
<Trans> <Trans>
<span>Saves</span> <span>Saves</span>
</Trans> </Trans>
@ -99,7 +51,7 @@ class Sider extends PureComponent {
<antd.Menu.Item key="marketplace"> <antd.Menu.Item key="marketplace">
<Icons.ShoppingTwoTone twoToneColor={this.isSelected('marketplace')? "#ff7a45" : "#85858570" }/> <Icons.ShoppingTwoTone twoToneColor={"#ff7a45"}/>
<Trans> <Trans>
<span>Marketplace</span> <span>Marketplace</span>
</Trans> </Trans>
@ -107,7 +59,7 @@ class Sider extends PureComponent {
<antd.Menu.Item key="events"> <antd.Menu.Item key="events">
<Icons.CarryOutTwoTone twoToneColor={this.isSelected('events')? "#ff4d4f" : "#85858570"}/> <Icons.CarryOutTwoTone twoToneColor={"#ff4d4f"}/>
<Trans> <Trans>
<span>Events</span> <span>Events</span>
</Trans> </Trans>
@ -119,8 +71,8 @@ class Sider extends PureComponent {
<antd.Menu <antd.Menu
selectable={false} selectable={false}
className={styles.left_sider_menuItems} className={styles.left_sider_menuItems}
mode="vertical" mode="horizontal"
onClick={this.handleClickMenu} onClick={handleClickMenu}
> >
<antd.Menu.Item key="general_settings"> <antd.Menu.Item key="general_settings">
<Icons.SettingOutlined /> <Icons.SettingOutlined />
@ -153,14 +105,3 @@ class Sider extends PureComponent {
) )
} }
} }
Sider.propTypes = {
menus: PropTypes.array,
theme: PropTypes.string,
isMobile: PropTypes.bool,
collapsed: PropTypes.bool,
onThemeChange: PropTypes.func,
onCollapseChange: PropTypes.func,
}
export default Sider

@ -0,0 +1,50 @@
import React from 'react'
import { config } from 'utils'
import * as ycore from 'ycore'
import Sider_Mobile from './mobile.js'
import Sider_Default from './default.js'
class Sider extends React.PureComponent {
onClickFunctions = {
saves: (e) => {
this.setState({selectedKey: e})
ycore.router.go('saves')
},
events: (e) => {
this.setState({selectedKey: e})
ycore.router.go('events')
},
marketplace: (e) => {
this.setState({selectedKey: e})
ycore.router.go('marketplace')
},
explore: (e) => {
this.setState({selectedKey: e})
ycore.router.go('main')
},
}
handleClickMenu = e => {
e.key === 'SignOut' && ycore.app_session.logout()
e.key === 'general_settings' && ycore.router.go('settings')
e.key === 'saves' && this.onClickFunctions.saves(e.key)
e.key === 'events' && this.onClickFunctions.events(e.key)
e.key === 'marketplace' && this.onClickFunctions.marketplace(e.key)
e.key === 'explore' && this.onClickFunctions.explore(e.key)
e.key === 'debug_area' && ycore.router.go('__m')
}
render() {
const { isMobile } = this.props
const sider_props = {handleClickMenu: this.handleClickMenu ,logo: config.LogoPath, menulist: null}
if (isMobile) {
return <Sider_Mobile {...sider_props} />
}
return <Sider_Default {...sider_props} />
}
}
export default Sider

@ -0,0 +1,61 @@
import React from 'react'
import * as antd from 'antd'
import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons'
import { withI18n, Trans } from '@lingui/react'
import styles from './mobile.less'
import * as ycore from 'ycore'
import CustomIcons from '../../CustomIcons'
@withI18n()
export default class Sider_Mobile extends React.PureComponent {
render() {
const { handleClickMenu, logo } = this.props
return (
<div className={styles.left_sider_wrapper}>
<antd.Layout.Sider
trigger={null}
width='100%'
>
<antd.Menu
mode="horizontal"
onClick={handleClickMenu}
>
<antd.Menu.Item key="explore">
<Icons.CompassTwoTone twoToneColor={"#28c35d"} />
</antd.Menu.Item>
<antd.Menu.Item key="saves">
<Icon component={CustomIcons.SavedPostColor} />
</antd.Menu.Item>
<antd.Menu.Item key="marketplace">
<Icons.ShoppingTwoTone twoToneColor={"#ff7a45"}/>
</antd.Menu.Item>
<antd.Menu.Item key="events">
<Icons.CarryOutTwoTone twoToneColor={"#ff4d4f"}/>
</antd.Menu.Item>
<antd.Menu.Item key="general_settings">
<Icons.SettingOutlined />
</antd.Menu.Item>
<antd.Menu.Item key="SignOut">
<Icons.LogoutOutlined style={{ color: 'red' }} />
</antd.Menu.Item>
</antd.Menu>
</antd.Layout.Sider>
</div>
)
}
}

@ -0,0 +1,49 @@
@import '~themes/index.less';
.left_sider_wrapper {
position: fixed;
z-index: 500;
bottom: 0;
right: 0;
left: 0;
height: 50px;
width: 100%;
border-color: transparent;
font-size: 13px;
font-family: @__Global_general_font_family;
padding: 0 27px;
:global {
.ant-layout-sider {
background-color: transparent;
height: 100%;
.ant-menu-item {color: @left_sider_color;}
.anticon {font-size: @left_sider_sizeIcons;}
.ant-menu-item{margin: auto; padding: 0;}
.ant-menu {
background-color: #2d2d2d;
height: 100%;
border-radius: 27px 27px 0 0;
padding: 0 27px;
display: flex;
}
.ant-menu-horizontal {
line-height: 46px;
white-space: nowrap;
border: 0;
border-bottom: 0;
box-shadow: none;
}
}
}
}

@ -1,4 +1,4 @@
import Sider from './Sider' import Sider from './Sider/index.js'
import Control from './Control' import Control from './Control'
import Secondary from './Secondary/index.js' import Secondary from './Secondary/index.js'

@ -28,6 +28,7 @@
animation: loader 0.8s linear; animation: loader 0.8s linear;
} }
opacity: 0; opacity: 0;
display: none;
} }
.newloader { .newloader {
@ -107,6 +108,7 @@
@keyframes unshow { @keyframes unshow {
0% { 0% {
opacity: 1; opacity: 1;
display: block;
} }
100% { 100% {

@ -0,0 +1,5 @@
import ComponentNewAV from './newav'
import ComponentInvalid from './invalid'
import renderFeedPosts from './renderFeedPosts'
export { ComponentNewAV, ComponentInvalid, renderFeedPosts }

@ -0,0 +1,24 @@
import { Card } from 'antd'
import { ExclamationCircleOutlined } from '@ant-design/icons'
const ComponentInvalid = fn => {
return (
<Card
style={{
borderRadius: '10px',
maxWidth: '26.5vw',
margin: 'auto',
textAlign: 'center',
}}
>
<h2>
<ExclamationCircleOutlined /> Invalid Data
</h2>
<span>
If this error has occurred several times, try restarting the app
</span>
</Card>
)
}
export default ComponentInvalid

@ -0,0 +1,11 @@
import { Button } from 'antd'
import styles from './newav.less'
const ComponentNewAV = fn => {
return (
<div className={styles.main_feed_newav}>
<Button onClick={fn}> New posts </Button>
</div>
)
}
export default ComponentNewAV

@ -0,0 +1,3 @@
.main_feed_newav{
}

@ -0,0 +1,43 @@
import React from 'react'
import { PostCard } from 'components'
import { yconsole } from 'ycore'
import { Button, List } from 'antd'
import { DownSquareOutlined } from '@ant-design/icons'
const renderFeedPosts = payload => {
const { data, loading, isEnd, feedGet } = payload
const loadMore =
!isEnd && !loading ? (
<div
style={{
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}}
>
<Button
type="ghost"
icon={<DownSquareOutlined />}
onClick={() => feedGet.more()}
/>
</div>
) : null
try {
yconsole.log(data)
return (
<List
loadMore={loadMore}
dataSource={data}
renderItem={item => (
<div id={item.id}>
<PostCard payload={item} key={item.id} />
</div>
)}
/>
)
} catch (err) {
return false
}
}
export default renderFeedPosts

@ -1,14 +1,13 @@
import React from 'react' import React from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as Icons from '@ant-design/icons'
import styles from './index.less' import styles from './index.less'
import { PostCard } from 'components' import { ComponentNewAV, ComponentInvalid, renderFeedPosts } from './components/index.js'
export const RenderFeed = { export const RenderFeed = {
RefreshFeed: () => { RefreshFeed: () => {
window.MainFeedComponent.FirstGet() window.MainFeedComponent.feedGet.first()
return return
}, },
killByID: post_id => { killByID: post_id => {
@ -27,12 +26,17 @@ export const RenderFeed = {
disableMenu: true, disableMenu: true,
}) })
}, },
sync: (c) => {
window.MainFeedComponent.syncService(c)
return
}
} }
class MainFeed extends React.Component { class MainFeed extends React.PureComponent {
constructor(props) { constructor(props) {
super(props) super(props)
window.MainFeedComponent = this window.MainFeedComponent = this
this.state = { this.state = {
NewAV: false,
invalid: false, invalid: false,
loading: false, loading: false,
disableMenu: false, disableMenu: false,
@ -42,12 +46,28 @@ class MainFeed extends React.Component {
} }
componentDidMount() { componentDidMount() {
this.FirstGet() this.feedGet.first()
ycore.sync.FeedListen((data) => {
this.syncService(data)
})
} }
toogleLoader() { toogleLoader() {
this.setState({ loading: !this.state.loading }) this.setState({ loading: !this.state.loading })
} }
syncService(data){
if (!data) return false
const { last_post_id, now } = data
const first = this.state.data[0]
if (first){
const a = first.id
console.log(` SYNC => ${last_post_id} | LAST => ${a}`)
if(last_post_id>a){
this.setState({ NewAV: true })
}
}
}
killByID(post_id) { killByID(post_id) {
const a = this.state.data const a = this.state.data
@ -61,148 +81,106 @@ class MainFeed extends React.Component {
this.setState({ data: a }) this.setState({ data: a })
} }
FirstGet() { feedGet = {
try { first: ()=>{
const { get, uid, filters } = this.props try {
if (this.props.custompayload) { const { get, uid, filters } = this.props
this.setState({ if (this.props.custompayload) {
isEnd: true, this.setState({
data: this.props.custompayload, isEnd: true,
loading: false, NewAV: false,
}) data: this.props.custompayload,
return loading: false,
} })
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
this.toogleLoader()
const payload = { fkey: 0, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
ycore.notify.error('Error when get data from this input')
return return
} }
if (JSON.parse(res).api_status == '400') { if (!get) {
this.setState({ invalid: true }) ycore.yconsole.error('Please, fill params with an catch type...')
return return
} }
try { this.toogleLoader()
const payload = { fkey: 0, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
ycore.notify.error('Error when get data from this input')
return
}
if (JSON.parse(res).api_status == '400') {
this.setState({ invalid: true })
return
}
try {
const parsed = JSON.parse(res)['data']
const isEnd =parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ NewAV: false, isEnd: isEnd, data: parsed, loading: false })
} catch (error) {
ycore.yconsole.log(error)
}
}, payload)
} catch (err) {
ycore.notify.error('err')
}
},
more(fkey){
try {
const { get, uid, filters } = this.props
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
if (!fkey) {
ycore.yconsole.warn(
'Please, provide a fkey for offset the feed, default using => 0'
)
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
return false
}
const oldData = this.state.data
const parsed = JSON.parse(res)['data'] const parsed = JSON.parse(res)['data']
const isEnd =parsed.length < ycore.AppSettings.limit_post_catch ? true : false const mix = oldData.concat(parsed)
this.setState({ isEnd: isEnd, data: parsed, loading: false }) const isEnd =
} catch (error) { parsed.length < ycore.AppSettings.limit_post_catch ? true : false
ycore.yconsole.log(error) this.setState({ isEnd: isEnd, data: mix, loading: false }, () =>
} ycore.goTo.element(getLastPost.id)
}, payload) )
} catch (err) { return true
ycore.notify.error('err') }, payload)
} } catch (err) {
} ycore.notify.error(err)
GetMore(fkey) {
try {
const { get, uid, filters } = this.props
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
} }
if (!fkey) {
ycore.yconsole.warn(
'Please, provide a fkey for offset the feed, default using => 0'
)
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
return false
}
const oldData = this.state.data
const parsed = JSON.parse(res)['data']
const mix = oldData.concat(parsed)
const isEnd =
parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () =>
ycore.goTo.element(getLastPost.id)
)
return true
}, payload)
} catch (err) {
ycore.notify.error(err)
}
}
renderFeedPosts = () => {
const { data, loading, isEnd } = this.state
const loadMore =
!isEnd && !loading ? (
<div
style={{
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}}
>
<antd.Button
type="ghost"
icon={<Icons.DownSquareOutlined />}
onClick={() => this.GetMore()}
/>
</div>
) : null
try {
ycore.yconsole.log(data)
return (
<antd.List
loadMore={loadMore}
dataSource={data}
renderItem={item => (
<div id={item.id}>
<PostCard payload={item} key={item.id} />
</div>
)}
/>
)
} catch (err) {
return false
} }
} }
render() { render() {
const { loading, invalid } = this.state const { data, loading, isEnd, invalid, NewAV } = this.state
return ( const renderFeedPosts_payload = {data: data, loading: loading, isEnd: isEnd, feedGet: this.feedGet}
<div className={styles.main_feed_wrapper} id="mainfeed">
{invalid ? ( if (invalid){
<antd.Card return ComponentInvalid()
style={{ }
borderRadius: '10px', if (loading) {
maxWidth: '26.5vw', return (
margin: 'auto', <antd.Card style={{ maxWidth: '26.5vw', margin: 'auto' }}>
textAlign: 'center',
}}
>
<h2>
<Icons.ExclamationCircleOutlined /> Invalid Data{' '}
</h2>
<span>
If this error has occurred several times, try restarting the app
</span>
</antd.Card>
) : loading ? (
<antd.Card style={{ maxWidth: '26.5vw', margin: 'auto' }}>
<antd.Skeleton avatar paragraph={{ rows: 4 }} active /> <antd.Skeleton avatar paragraph={{ rows: 4 }} active />
</antd.Card> </antd.Card>
) : ( )
this.renderFeedPosts() }
)} if (!loading) {
</div> return (
) <div className={styles.main_feed_wrapper} id="mainfeed">
{NewAV? ComponentNewAV(() => this.feedGet.first()) : null}
{renderFeedPosts(renderFeedPosts_payload)}
</div>
)
}
} }
} }
export default MainFeed export default MainFeed

@ -1,4 +1,4 @@
.main_feed_wrapper{ .main_feed_wrapper{
scroll-behavior: smooth; scroll-behavior: smooth;
} }

@ -1,28 +1,32 @@
import React from 'react' import React from 'react'
import * as Icons from '@ant-design/icons' import classnames from 'classnames'
import styles from './index.less'
export default class MediaPlayer extends React.PureComponent { export default class MediaPlayer extends React.PureComponent {
render() { player() {
const { file } = this.props const { file } = this.props
let type; let type
const ImageExtensions = ['.png', '.jpg', '.jpeg', '.gif'] const ImageExtensions = ['.png', '.jpg', '.jpeg', '.gif']
const VideoExtensions = ['.mp4', '.mov', '.avi'] const VideoExtensions = ['.mp4', '.mov', '.avi']
const AudioExtensions = ['.mp3', '.ogg', '.wav'] const AudioExtensions = ['.mp3', '.ogg', '.wav']
const FilesAllowed = ImageExtensions.concat(VideoExtensions, AudioExtensions) const FilesAllowed = ImageExtensions.concat(
VideoExtensions,
AudioExtensions
)
for (const prop in FilesAllowed) { for (const prop in FilesAllowed) {
if(file.includes(`${ImageExtensions[prop]}`)){ if (file.includes(`${ImageExtensions[prop]}`)) {
type = 'image' type = 'image'
} }
if(file.includes(`${VideoExtensions[prop]}`)){ if (file.includes(`${VideoExtensions[prop]}`)) {
type = 'video' type = 'video'
} }
if(file.includes(`${AudioExtensions[prop]}`)){ if (file.includes(`${AudioExtensions[prop]}`)) {
type = 'audio' type = 'audio'
} }
} }
if (type == 'video') { if (type == 'video') {
// const payload = {type: 'video', sources: [{src: file,}]} // const payload = {type: 'video', sources: [{src: file,}]}
@ -43,11 +47,19 @@ export default class MediaPlayer extends React.PureComponent {
) )
} }
if (type == 'image') { if (type == 'image') {
if (file.includes('gif')) { return <img src={file} />
return <div><Icons.GifOutlined /> <img src={file} /></div> }
} }
return <img src={file} /> render() {
} return (
return null <div
className={classnames(styles.PlayerContainer, {
[styles.mobile]: this.props.isMobile,
[styles.entire]: this.props.entire,
})}
>
{this.player()}
</div>
)
} }
} }

@ -1,29 +1,80 @@
.PlayerContainer { .PlayerContainer {
max-width: 100vw; width: 100%;
max-height: 75vh;
img { img {
object-fit: contain; width: 100%;
position: absolute; overflow: hidden;
top: 50%; margin: auto;
left: 47%;
width: 500px;
height: 500px;
margin-top: -250px;
margin-left: -350px;
} }
audio{
video {
max-height: 600px;
width: 100%;
overflow: hidden;
}
audio {
width: 100%; width: 100%;
} }
video {
object-fit: contain;
position: absolute; &.entire {
max-width: 52vw;
max-height: 80vh;
position: fixed;
top: 50%; top: 50%;
left: 47%; left: 50%;
width: 500px; transform: translate(-70%, -50%);
height: 500px;
margin-top: -250px; img {
margin-left: -350px; object-fit: contain;
height: 100%;
width: 100%;
max-width: 52vw;
max-height: 80vh;
}
audio {
height: 100%;
width: 100%;
}
video {
object-fit: contain;
height: 100%;
width: 100%;
max-width: 52vw;
max-height: 80vh;
}
}
&.mobile {
max-width: 52vw;
max-height: 80vh;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
img {
object-fit: contain;
height: 100%;
width: 100%;
max-width: 52vw;
max-height: 80vh;
}
audio {
height: 100%;
width: 100%;
}
video {
object-fit: contain;
height: 100%;
width: 100%;
max-width: 52vw;
max-height: 80vh;
}
} }
} }

@ -195,22 +195,6 @@
max-height: 600px; max-height: 600px;
overflow: hidden; overflow: hidden;
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto;
}
video {
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
audio {
width: 100%;
}
h3 { h3 {
color: rgb(85, 85, 85); color: rgb(85, 85, 85);
font-weight: 470; font-weight: 470;

@ -9,8 +9,6 @@ import * as MICONS from '@material-ui/icons'
import Post_options from './local_components/post_options' import Post_options from './local_components/post_options'
import { optionBox } from './local_components/post_options' import { optionBox } from './local_components/post_options'
import io from 'socket.io-client'
var socket = io('http://localhost:5500');
function getBase64(img, callback) { function getBase64(img, callback) {
const reader = new FileReader() const reader = new FileReader()
@ -188,7 +186,8 @@ class PostCreator extends React.PureComponent {
const pro_boost_val = ycore.ReturnValueFromMap({ data: post_options, key: 'pro_boost' }) const pro_boost_val = ycore.ReturnValueFromMap({ data: post_options, key: 'pro_boost' })
const allow_comments_val = ycore.ReturnValueFromMap({ data: post_options, key: 'allow_comments' }) const allow_comments_val = ycore.ReturnValueFromMap({ data: post_options, key: 'allow_comments' })
socket.emit('push_post'); console.log(id_temp_parse)
ycore.sync.emmitPost(id_temp_parse)
ycore.yconsole.log(`pro_boost => ${pro_boost_val} | allow_comments => ${allow_comments_val}`) ycore.yconsole.log(`pro_boost => ${pro_boost_val} | allow_comments => ${allow_comments_val}`)
if (pro_boost_val) { if (pro_boost_val) {

@ -40,7 +40,6 @@ class PrimaryLayout extends React.Component {
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
userData: ycore.userData(), userData: ycore.userData(),
desktop_mode: ycore.CheckThisApp.desktop_mode(),
}) })
this.enquireHandler = enquireScreen(mobile => { this.enquireHandler = enquireScreen(mobile => {
@ -63,23 +62,13 @@ class PrimaryLayout extends React.Component {
store.set('collapsed', !fromStore) store.set('collapsed', !fromStore)
} }
isDarkMode = () => {
const { app } = this.props
const { theme } = app
if (theme == 'light') {
return false
}
return true
}
render() { render() {
const { app, location, dispatch, children } = this.props const { app, location, dispatch, children } = this.props
const { userData, collapsed, isMobile, desktop_mode } = this.state const { userData, collapsed, isMobile } = this.state
const { onCollapseChange } = this const { onCollapseChange } = this
const { theme } = app const { theme } = app
const SiderProps = { const SiderProps = {
desktop_mode: desktop_mode,
theme, theme,
userData, userData,
isMobile, isMobile,
@ -100,11 +89,11 @@ class PrimaryLayout extends React.Component {
return ( return (
<React.Fragment> <React.Fragment>
{isMobile ? <MobileWarning /> : null} {/* {isMobile ? <MobileWarning /> : null} */}
<div className={styles.__ControlBar}> <div className={styles.__ControlBar}>
<Control /> <Control />
</div> </div>
<antd.Layout id="primaryLayout" className={styles.primary_layout}> <antd.Layout id="primaryLayout" className={classnames(styles.primary_layout, {[styles.mobile]: isMobile})}>
<Sider {...SiderProps} /> <Sider {...SiderProps} />
<div className={styles.primary_layout_container}> <div className={styles.primary_layout_container}>

@ -12,6 +12,16 @@
overflow-y: hidden!important; overflow-y: hidden!important;
background-color: @primary_layout_backgroud; background-color: @primary_layout_backgroud;
margin: auto; margin: auto;
&.mobile{
>.primary_layout_container {
border-radius: 0;
margin: 0;
padding: 0;
}
>.primary_layout_content{
padding: 0;
}
}
} }
// PRIMARY LAYOUT // PRIMARY LAYOUT

@ -48,6 +48,7 @@ export default {
router.push({ pathname: '/main' }) router.push({ pathname: '/main' })
} }
ycore.QueryRuntime() ycore.QueryRuntime()
return true return true
} else if (!pathMatchRegexp(['', '/login'], window.location.pathname)) { } else if (!pathMatchRegexp(['', '/login'], window.location.pathname)) {
if (validBackup == true) { if (validBackup == true) {

@ -1,3 +1,4 @@
@import './resolutions.less';
// FOR LAYOUTS // FOR LAYOUTS
@__Global_general_font_family: "Poppins", sans-serif; @__Global_general_font_family: "Poppins", sans-serif;
@ -42,47 +43,79 @@ body {
scroll-behavior: smooth; scroll-behavior: smooth;
height: 100%; height: 100%;
overflow-y: hidden; overflow-y: hidden;
background-color: transparent; // rgb(249, 249, 249); min-width: 430px;
background-color: transparent;
font-size: @base-font-size;
line-height: @base-line-height;
} }
@media (min-width: 1600px) { @media (min-width: @bp-medium) {
:global {
.ant-col-xl-48 {
width: 20%;
}
.ant-col-xl-96 {
width: 40%;
}
}
}
@media (max-width: 767px) {
:global {
.ant-card {
.ant-card-head {
padding: 0 12px;
}
.ant-card-body {
padding: 12px;
}
}
}
}
// PrimaryLayout
@media (max-width: 767px) {
.primary_layout_content {
padding: 12px;
}
.primary_layout {
height: 100vh;
flex: 1;
}
} }
@media (min-width: @bp-large) {
}
@media (min-width: @bp-xlarge) {
body{
zoom: 1.4;
}
}
@media (min-width: @bp-xxlarge) {
body{
zoom: 1.6;
}
}
// @media (min-width: 770px){
// >#secondary_layout{
// width: 0px!important;
// }
// }
// @media (min-width: 1600px) {
// :global {
// .ant-col-xl-48 {
// width: 20%;
// }
// .ant-col-xl-96 {
// width: 40%;
// }
// }
// }
// @media (max-width: 767px) {
// :global {
// .ant-card {
// .ant-card-head {
// padding: 0 12px;
// }
// .ant-card-body {
// padding: 12px;
// }
// }
// }
// }
// // PrimaryLayout
// @media (max-width: 767px) {
// .primary_layout_content {
// padding: 12px;
// }
// .primary_layout {
// height: 100vh;
// flex: 1;
// }
// }
// .primary_layout_* // .primary_layout_*
@primary_layout_backgroud: #2d2d2d; @primary_layout_backgroud: #2d2d2d;

@ -0,0 +1,20 @@
@bp-small: 48em; // 768px
@bp-medium: 64em; // 1024px
@bp-large: 85.375em; // 1366px
@bp-xlarge: 120em; // 1920px
@bp-xxlarge: 160em; // 2560px
// Media Queries
@mq-small: "min-width: @bp-small";
@mq-medium: "(min-width: @bp-medium)";
@mq-large: "(min-width: @bp-large)";
@mq-xlarge: "(min-width: @bp-xlarge)";
@mq-xxlarge: "(min-width: @bp-xxlarge)";
@mq-retina: "(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)";
// Font-Size
@base-font-size: 1em;
// Line-Height
@base-line-height: 1.5;
@header-line-height: 1.25;

@ -3,4 +3,3 @@
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro&display=swap'); @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro&display=swap');
@import url('https://fonts.googleapis.com/css?family=Kulim+Park&display=swap'); @import url('https://fonts.googleapis.com/css?family=Kulim+Park&display=swap');
@import url('https://fonts.googleapis.com/css?family=Nunito&display=swap'); @import url('https://fonts.googleapis.com/css?family=Nunito&display=swap');
@import url('https://api.ragestudio.net/fonts/trueno/font.css');