This commit is contained in:
unknown 2020-07-25 03:44:39 +02:00
parent fb7a3a8b6a
commit 599e706a23
204 changed files with 1938 additions and 9329 deletions

4
.env
View File

@ -1,4 +1,2 @@
UMI_UI=none
UMI_UI=true
NODE_ENV=production
YCORE_CONFIG=./config

View File

@ -1,7 +0,0 @@
src/**/*-test.js
src/public
src/routes/chart/ECharts/theme
src/routes/chart/highCharts/mapdata
src/locales/_build/
src/locales/**/*.js
docs/**/*.js

View File

@ -1,8 +0,0 @@
{
"extends": "react-app",
"rules": {
"jsx-a11y/href-no-hash": "off",
"no-console": "warn",
"valid-jsdoc": "warn"
}
}

35
.gitignore vendored
View File

@ -1,25 +1,20 @@
coverage
dist
node_modules
npm-debug.log
yarn-error.log
yarn.lock
package-lock.json
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# ide
.idea
# dependencies
/node_modules
/npm-debug.log*
/yarn-error.log
/yarn.lock
/package-lock.json
# Mac General
# production
/dist
# misc
.DS_Store
.AppleDouble
.LSOverride
# umi
.umi
.umi-production
# jslingui
src/locales/_build
src/locales/**/*.js
android/
auxCord
/src/.umi
/src/.umi-production
/src/.umi-test
/.env.local

View File

@ -1,6 +1,8 @@
*.svg
*.ejs
.DS_Store
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
src/locales/**/*.json
.umi-test

View File

@ -1,5 +1,11 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "es5"
"trailingComma": "all",
"printWidth": 80,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}

View File

@ -1,9 +0,0 @@
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": {
"declaration-empty-line-before": null,
"no-descending-specificity": null,
"selector-pseudo-class-no-unknown": null,
"selector-pseudo-element-colon-notation": null
}
}

View File

@ -1,27 +0,0 @@
language: node_js
node_js:
- node
script:
- npm run build
before_install:
- |
if [ "$TRAVIS_BRANCH" = "develop" ]; then
for prefixed_envvar in ${!DEV_*}; do
eval export ${prefixed_envvar#DEV_}="${!prefixed_envvar}"
done
elif [ "$TRAVIS_BRANCH" = "master" ]; then
for prefixed_envvar in ${!PROD_*}; do
eval export ${prefixed_envvar#PROD_}="${!prefixed_envvar}"
done
else
for prefixed_envvar in ${!TEST_*}; do
eval export ${prefixed_envvar#TEST_}="${!prefixed_envvar}"
done
fi
- openssl aes-256-cbc -K $encrypted_18b2305b78c9_key -iv $encrypted_18b2305b78c9_iv -in config/id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host $HOST\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- yarn global add now
after_script:
- scp -o stricthostkeychecking=no -r ./dist root@$HOST:$BUILD_DIR
- cd ./docs && now -A $DOC_NOW_CONFIG -t $NOW_TOKEN && now alias -A $DOC_NOW_CONFIG -t $NOW_TOKEN

View File

@ -1,92 +0,0 @@
// https://umijs.org/config/
import { resolve } from 'path'
import { i18n } from './config/ycore.config.js'
export default {
ignoreMomentLocale: true,
hash: false,
ssr: false,
targets: { ie: 9,},
treeShaking: true,
plugins: [
[
'umi-plugin-react',
{
dva: {
immer: true,
},
antd: true,
dynamicImport: {
webpackChunkName: true,
loadingComponent: './components/Loader/Loader',
},
routes: {
exclude: [
/model\.(j|t)sx?$/,
/service\.(j|t)sx?$/,
/models\//,
/components\//,
/services\//,
],
update: routes => {
if (!i18n) return routes
const newRoutes = []
for (const item of routes[0].routes) {
newRoutes.push(item)
if (item.path) {
newRoutes.push(
Object.assign({}, item, {
path:
`/:lang(${i18n.languages
.map(item => item.key)
.join('|')})` + item.path,
})
)
}
}
routes[0].routes = newRoutes
return routes
},
},
dll:false,
pwa: {
manifestOptions: {
srcPath: 'manifest.json',
},
},
},
],
],
// Theme for antd
// https://ant.design/docs/react/customize-theme
theme: './config/theme.config.js',
// Webpack Configuration
alias: {
app: resolve(__dirname, './src/@app/app.js'),
keys: resolve(__dirname, './config/keys.js'),
globals: resolve(__dirname, './globals'),
components: resolve(__dirname, './src/components'),
config: resolve(__dirname, './config/ycore.config.js'),
models: resolve(__dirname, './src/models'),
routes: resolve(__dirname, './src/routes'),
themes: resolve(__dirname, './src/themes'),
utils: resolve(__dirname, './src/utils'),
},
extraBabelPresets: ['@lingui/babel-preset-react'],
extraBabelPlugins: [
[
'import',
{
libraryName: 'lodash',
libraryDirectory: '',
camel2DashComponentName: false,
},
'lodash',
],
],
}

89
.umirc.ts Normal file
View File

@ -0,0 +1,89 @@
import { defineConfig } from 'umi';
const fs = require('fs');
const path = require('path');
const lessToJs = require('less-vars-to-js');
const { resolve } = require('path');
export default defineConfig({
hash: false,
ignoreMomentLocale: true,
targets: { ie: 9 },
dynamicImport: {
loading: 'components/Loader/Loader.js',
},
dva: { immer: true },
nodeModulesTransform: {
type: 'none',
},
alias: {
api: resolve(__dirname, './api'),
globals: resolve(__dirname, './globals'),
core: resolve(__dirname, './src/core'),
theme: resolve(__dirname, './src/theme'),
config: resolve(__dirname, './config'),
components: resolve(__dirname, './src/components'),
models: resolve(__dirname, './src/models'),
routes: resolve(__dirname, './src/routes'),
},
theme: lessToJs(
fs.readFileSync(path.join(__dirname, './src/theme/index.less'), 'utf8'),
),
extraBabelPlugins: [
[
'import',
{
libraryName: 'lodash',
libraryDirectory: '',
camel2DashComponentName: false,
},
'lodash',
],
],
// chainWebpack: function(config, { webpack }) {
// config.module
// .rule('js-in-node_modules')
// .exclude.add(/node_modules/)
// .end()
// config.module
// .rule('ts-in-node_modules')
// .exclude.add(/node_modules/)
// .end()
// config.merge({
// optimization: {
// minimize: true,
// splitChunks: {
// chunks: 'all',
// minSize: 30000,
// minChunks: 3,
// automaticNameDelimiter: '.',
// cacheGroups: {
// react: {
// name: 'react',
// priority: 20,
// test: /[\\/]node_modules[\\/](react|react-dom|react-dom-router)[\\/]/,
// },
// antd: {
// name: 'antd',
// priority: 20,
// test: /[\\/]node_modules[\\/](antd|@ant-design\/icons)[\\/]/,
// },
// async: {
// chunks: 'async',
// minChunks: 2,
// name: 'async',
// maxInitialRequests: 1,
// minSize: 0,
// priority: 5,
// reuseExistingChunk: true,
// },
// },
// },
// },
// })
// },
});

12
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"configurations": [
{
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": ["run-script", "debug"],
"runtimeExecutable": "npm",
"skipFiles": ["<node_internals>/**"],
"type": "pwa-node"
}
]
}

View File

@ -1,4 +0,0 @@
{
"$schema": "http://json.schemastore.org/vsls",
"gitignore":"none"
}

View File

@ -1,3 +0,0 @@
module.exports = {
nigga: 'JeJe So FUny'
}

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# umi project
## Getting Started
Install dependencies,
```bash
$ yarn
```
Start the dev server,
```bash
$ yarn start
```

View File

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

View File

@ -1,37 +0,0 @@
function SettingStoragedValue(e){
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
}
catch (error) {
return null
}
}
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
export var AppSettings = {
__global_server_prexif: 'https://api.ragestudio.net/RSA-COMTY/r/',
// Global Behaviors
InfiniteLoading: false,
InfiniteLogin: false,
InfiniteRegister: false,
DisableLogin: false,
DisableRegister: true,
DisablePasswordRecover: true,
disable_pro_tool: fromStorage? SettingStoragedValue('disable_pro_tool') : false,
force_showDevLogs: fromStorage? SettingStoragedValue('force_showDevLogs') : false,
SignForNotExpire: fromStorage? SettingStoragedValue('sessions_noexpire') : false,
auto_search_ontype: fromStorage? SettingStoragedValue('auto_search_ontype') : false,
auto_feedrefresh: fromStorage? SettingStoragedValue('auto_feedrefresh') : false,
auto_hide_postbar: fromStorage? SettingStoragedValue('auto_hide_postbar') : true,
MaxLengthPosts: '512',
CurrentBundle: 'light_ng',
// In KB
MaximunAPIPayload: '101376',
limit_post_catch: '20',
Maximun_tick_overrun: 10,
}

9
config/app_keys.js Normal file
View File

@ -0,0 +1,9 @@
module.exports = {
unsplash_key: 'slrHmuo9FEJajV4xvWl38TUhbib6BhhGI4VIZ1-cqnw',
unsplash_secret: 'dh3UlgLTdunO7a_l_iKjotXbz0xB7w5EuDIBU8Pa8pA',
g_recaptcha_key: '6Lc55uUUAAAAAEIACMVf3BUzAJSNCmI3RrjEirZ6',
g_recaptcha_secret: '6Lc55uUUAAAAAOP4OgUa5DpqJC-70t53AmW0lyYf',
// Global Server Key (Requiered for RS-YIBTP), Not autogenerated, must be included on. (Recommended not modify this constant)
server_key:
'f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768',
};

7
config/endpoints.js Normal file
View File

@ -0,0 +1,7 @@
export default {
auth_server: 'POST /auth_server',
auth: 'POST /auth',
logout: 'POST /logout',
get_data: 'POST /get-user-data',
};

Binary file not shown.

57
config/index.js Normal file
View File

@ -0,0 +1,57 @@
module.exports = {
app_config: {
siteName: 'Comty',
copyright: 'RageStudio©',
MainPath: '/',
LogoPath: '/logo.svg',
FullLogoPath: '/full_logo.svg',
DarkFullLogoPath: '/dark_full_logo.svg',
DarkLogoPath: '/dark_logo.svg',
api_prefix: 'ycorejs_apiv3',
app_settings_storage: 'app_settings'
},
i18n: {
languages: [
{
key: 'en',
title: 'English',
},
],
defaultLanguage: 'en',
},
layouts: [
{
name: 'primary',
include: [/\/main/, /\/settings/, /\/saves/, /\/pro/, /\/chats/, /\//],
exclude: [/\/publics/, /\/login/ ],
},
{
name: 'public',
include: [/.*/]
}
],
// Default Behaviors
defaults: {
verbosity: false,
session_noexpire: false,
search_ontype: false,
overlay_loosefocus: true,
render_pagetransition_preset: 'moveToRightScaleUp',
feed_autorefresh: false,
post_maxlenght: '512',
post_catchlimit: '20',
post_hidebar: true,
// In KB
api_maxpayload: '101376',
api_maxovertick: 10,
}
};

View File

@ -1,10 +0,0 @@
module.exports = {
spotify_client: '609f59064dfd470c8c2abffbd9044843',
spotify_secret: 'b7efd276bf2e41039dedb2a514f35951',
unsplash_key: "slrHmuo9FEJajV4xvWl38TUhbib6BhhGI4VIZ1-cqnw",
unsplash_secret: "dh3UlgLTdunO7a_l_iKjotXbz0xB7w5EuDIBU8Pa8pA",
g_recaptcha_key: '6Lc55uUUAAAAAEIACMVf3BUzAJSNCmI3RrjEirZ6',
g_recaptcha_secret: '6Lc55uUUAAAAAOP4OgUa5DpqJC-70t53AmW0lyYf',
// Global Server Key (Requiered for RS-YIBTP), Not autogenerated, must be included on. (Recommended not modify this constant)
server_key: 'f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768',
}

View File

@ -1,7 +0,0 @@
const fs = require('fs')
const path = require('path')
const lessToJs = require('less-vars-to-js')
module.exports = () => {
// return {"@__Global_backgroud_image": "url(https://images.unsplash.com/photo-1471286274405-579f8d7132d8?.jpg)"}
}

View File

@ -1,37 +0,0 @@
module.exports = {
siteName: 'Comty',
copyright: 'RageStudio©',
LogoPath: '/logo.svg',
FullLogoPath: '/full_logo.svg',
DarkFullLogoPath: '/dark_full_logo.svg',
DarkLogoPath: '/dark_logo.svg',
resource_bundle: 'light_ng',
sync_server: 'http://85.251.59.39:6050',
rest_server: 'https://comty.pw',
/* Layout configuration, specify which layout to use for route. */
layouts: [
{
name: 'primary',
include: [/\/main/, /\/settings/, /\/saves/, /\/pro/, /\/chats/, /\//],
exclude: [/\/publics/, /\/login/ ],
},
{
name: 'public',
include: [/.*/]
}
],
i18n: {
languages: [
{
key: 'en',
title: 'English',
},
],
defaultLanguage: 'en',
},
}

View File

@ -1,23 +0,0 @@
[
{
"id": "1",
"title": "PINS",
"avatar": "https://dl.ragestudio.net/statics/icons/nxkuOJlFJuAUhzlMTCEe.png",
"description": "Debug pins functions, create, modify, delete...",
"component": "PINS_debugger"
},
{
"id": "2",
"title": "SDCP™",
"avatar":"https://dl.ragestudio.net/statics/icons/nxkuOJlFJuAUhzlMTCEe.png",
"description": "Debug SDCP Controller and data proccess",
"component": "SDCP_debugger"
},
{
"id": "3",
"title": "API",
"avatar": "https://dl.ragestudio.net/statics/icons/nxkuOJlFJuAUhzlMTCEe.png",
"description": "Debug API Controller and data proccess",
"component": "API_debugger"
}
]

View File

@ -1,6 +0,0 @@
module.exports={
// !!! Deprecated for the new model => v0.4.06 (up)
comty_endpoints: {
new_post: "https://comty.pw/api/new_post",
}
}

View File

@ -1,3 +0,0 @@
export * from './comty_endpoints.js'
export * from './twitter_endpoints.js'
export * from './unsplash_endpoints.js'

View File

@ -1,5 +0,0 @@
module.exports = {
autorize: 'https://accounts.spotify.com/authorize',
}

View File

@ -1,6 +0,0 @@
module.exports = {
twitter_endpoints: {
oa_access: "https://api.twitter.com/oauth/access_token",
oa_request: "https://api.twitter.com/oauth/request_token",
}
}

View File

@ -1,6 +0,0 @@
module.exports = {
unsplash_endpoints: {
api: "https://api.unsplash.com/",
search: "https://api.unsplash.com/search/photos"
}
}

View File

@ -1,62 +1,33 @@
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
function SettingStoragedValue(e) {
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e ? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
} catch (error) {
return null
}
}
export var ListSettings = [
module.exports = [
{
SettingID: 'disable_pro_tool',
type: 'switch',
title: 'Hide Pro Tools',
description: 'Hide right sidebar utils of comty pro',
value: fromStorage ? SettingStoragedValue('disable_pro_tool') : false,
},
{
SettingID: 'sessions_noexpire',
id: 'session_noexpire',
type: 'switch',
title: 'No expire session',
description: 'Force the app to not expire any session... [Developer]',
value: fromStorage ? SettingStoragedValue('sessions_noexpire') : false,
},
{
SettingID: 'auto_feedrefresh',
type: 'switch',
title: 'Auto Feed Refresh',
description:
'Force the app to auto refresh the posts feed when exist news posts for update',
value: fromStorage ? SettingStoragedValue('auto_feedrefresh') : false,
},
{
SettingID: 'auto_search_ontype',
id: 'search_ontype',
type: 'switch',
title: 'Detect input on search bar',
description:
'Force the app to automaticly search when a type input is detected... [Developer]',
value: fromStorage ? SettingStoragedValue('auto_search_ontype') : false,
},
{
SettingID: 'auto_hide_postbar',
id: 'post_hidebar',
type: 'switch',
title: 'Auto hide postbar',
description:
'Force the app to dont hide the post actions (likes, comments ...etc) automaticly... [Developer]',
value: fromStorage ? SettingStoragedValue('auto_hide_postbar') : true,
description: 'Force the app to dont hide the post actions (likes, comments ...etc) automaticly... [Developer]',
},
{
SettingID: 'force_showDevLogs',
id: 'verbosity',
type: 'switch',
title: 'Show Functions Logs',
title: 'Enable core verbosity',
description: 'Show all console logs... [Developer]',
value: fromStorage ? SettingStoragedValue('force_showDevLogs') : false,
},
{
id: 'overlay_loosefocus',
type: 'switch',
title: 'Overlay loose focus',
description: 'Close the overlay when loose focus',
},
]

View File

@ -1,7 +1,4 @@
import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons'
import {CustomIcons} from 'components'
import * as Feather from 'feather-reactjs'
import * as Icons from 'components/Icons'
let MenuList = [
{
@ -9,35 +6,40 @@ let MenuList = [
title: 'Main',
path: '/main',
require: 'login',
icon: <Feather.Home />,
icon: <Icons.Home />,
mobile: 'true'
},
{
id: 'explore',
title: 'Explore',
path: '/explore',
require: 'login',
icon: <Feather.Compass />,
icon: <Icons.Compass />,
mobile: 'true'
},
{
id: 'saves',
title: 'Saves',
path: '/saves',
require: 'login',
icon: <Feather.Bookmark />,
icon: <Icons.Bookmark />,
mobile: 'false'
},
{
id: 'messages',
title: 'Messages',
path: '/messages',
require: 'login',
icon: <Feather.MessageSquare />,
icon: <Icons.MessageSquare />,
mobile: 'false'
},
{
id: 'notifications',
title: 'Notifications',
path: '/notifications',
require: 'login',
icon: <Feather.Inbox/>,
icon: <Icons.Inbox/>,
mobile: 'false'
},
]

View File

@ -1,3 +0,0 @@
module.exports = {
testURL: 'http://localhost:8000',
}

View File

@ -1,11 +0,0 @@
{
"name": "Comty",
"start_url": ".",
"display": "standalone",
"description": "An client prototype of universal social network.",
"icons": [
{
"src": "logo.svg"
}
]
}

View File

@ -3,111 +3,88 @@
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
"title": "Comty™",
"DevBuild": true,
"version": "0.4.11",
"version": "0.7.24",
"stage": "dev-pre",
"description": "",
"author": "RageStudio",
"license": "ISC",
"private": true,
"scripts": {
"start": "umi dev",
"build": "umi build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
"test:coverage": "umi-test --coverage"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,less,md,json}": [
"prettier --write"
],
"*.ts?(x)": [
"prettier --parser=typescript --write"
]
},
"dependencies": {
"@lingui/cli": "^2.9.1",
"@lingui/loader": "^2.9.1",
"@lingui/react": "^2.9.1",
"@material-ui/core": "^4.9.9",
"@material-ui/icons": "^4.9.1",
"antd": "^4.1.2",
"@ragestudio/ycorejs-lib": "^0.1.21",
"antd": "^4.3.5",
"axios": "^0.19.2",
"canvas": "^2.6.1",
"babel-core": "^6.26.3",
"classnames": "^2.2.6",
"colorthief": "^2.3.0",
"dva": "2.4.1",
"dva-model-extend": "^0.1.2",
"dva-react-hook": "^1.2.7",
"enquire-js": "^0.2.1",
"feather-reactjs": "^2.0.13",
"interactjs": "^1.9.9",
"jquery": "^3.4.1",
"jsonwebtoken": "^8.5.1",
"koa": "^2.7.0",
"koa-compress": "^3.0.0",
"koa-mount": "^4.0.0",
"koa-static": "^5.0.0",
"localforage": "^1.7.3",
"lodash": "^4.17.15",
"md5": "^2.2.1",
"moment": "^2.24.0",
"jquery": "^3.5.1",
"less-vars-to-js": "^1.3.0",
"lint-staged": "^10.0.7",
"localforage": "^1.7.4",
"lodash": "^4.17.19",
"moment": "^2.27.0",
"node-sass": "^4.13.1",
"nodemon": "^1.19.1",
"nprogress": "^0.2.0",
"path-to-regexp": "^6.1.0",
"prettier": "^1.19.1",
"prop-types": "^15.7.2",
"puppeteer": "^3.0.3",
"radium": "^0.26.0",
"randomstring": "^1.1.5",
"react": "^16.12.0",
"react-animations": "^1.0.0",
"react-color": "^2.18.1",
"react-dazzle": "^1.4.0",
"react-dom": "^16.12.0",
"react-emoji": "^0.5.0",
"react-feather": "^2.0.8",
"react-google-recaptcha": "^2.0.1",
"react-helmet": "^5.2.1",
"react-linkify": "^1.0.0-alpha",
"react-perfect-scrollbar": "^1.5.8",
"react-reveal": "^1.2.2",
"react-scripts": "^3.4.1",
"react-transition-group": "^4.4.1",
"react-virtualized": "^9.21.2",
"reactablejs": "^0.2.0",
"socket.io-client": "^2.3.0",
"stack-trace": "0.0.10",
"store": "^2.0.12",
"timeago.js": "^4.0.2",
"ts-cookies": "^1.0.0",
"umi": "^2.13.12",
"umi-plugin-react": "^1.15.7",
"umi-request": "^1.2.4",
"umi-server": "^1.2.3",
"validator": "^12.2.0",
"ycorejs": "^0.1.1"
"styled-components": "^5.1.1",
"timeago.js": "^4.0.2"
},
"devDependencies": {
"@capacitor/android": "^1.5.2",
"@capacitor/cli": "^1.5.2",
"@capacitor/core": "^1.5.2",
"@lingui/babel-preset-react": "^2.9.1",
"umi-plugin-datahub": "^4.1.0",
"@types/react": "^16.9.33",
"babel-core": "7.0.0-bridge.0",
"babel-plugin-dev-expression": "^0.2.2",
"babel-plugin-import": "^1.13.0",
"babel-plugin-macros": "^2.8.0",
"@lingui/babel-preset-react": "^2.9.0",
"@lingui/cli": "^2.9.0",
"@lingui/loader": "^2.9.0",
"@umijs/preset-react": "^1.4.0",
"babel-eslint": "^10.0.1",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-module-resolver": "^4.0.0",
"cross-env": "^7.0.0",
"less-vars-to-js": "^1.3.0",
"module": "^1.2.5",
"now": "^17.0.3",
"workbox-webpack-plugin": "^5.0.0"
},
"engines": {
"node": ">= 10.0.0"
},
"lingui": {
"fallbackLocale": "en",
"sourceLocale": "en",
"localeDir": "src/locales",
"srcPathDirs": [
"src/pages",
"src/layouts",
"src/components",
"src/layouts"
],
"format": "minimal",
"extractBabelOptions": {
"presets": [
"umi/babel"
]
}
},
"scripts": {
"analyze": "cross-env ANALYZE=1 umi build",
"build": "umi build",
"start": "umi dev",
"test": "cross-env BABELRC=none umi test"
"cross-env": "^6.0.0",
"typescript": "^3.8.3",
"umi": "^3.2.9"
}
}

View File

@ -1 +1,10 @@
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 185.74 232.39"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#feb500;}</style></defs><title>icon_new2019_black</title><path class="cls-1" d="M342.49,451.06c8.28,8.2,16.5,16.44,24.86,24.55,1.85,1.8.6,2.83-.41,4.08-15.56,19.36-35.85,29.16-60.57,27.74-35.91-2.07-63-26.9-67.73-62.51-5.41-40.92,21.42-78.11,59-85.47,25.83-5.05,55.39,7.3,69.51,29.39,1.07,1.68,2.31,2.94.15,5-8.15,7.85-16.08,15.91-24.21,24-.37-.34-.84-.57-1-.93C334.77,401.49,322.76,394,307,395c-13.74.89-25.63,11.25-30.41,26.51-7,22.32,3.85,43.55,25,48.88C317.7,474.46,332.28,467.59,342.49,451.06Z" transform="translate(-182.77 -275.17)"/><path class="cls-2" d="M192.52,352.88c-3.43-.21-6.6-2.45-8.51-6.25a10.13,10.13,0,0,1,1-11.27,152.39,152.39,0,0,1,33-32.36,159,159,0,0,1,61.51-27.38c8-1.68,13.53,1.45,15.06,8.26,1.48,6.53-2.47,11.86-10.49,13.61-33,7.21-59.84,24.16-80.78,50.57C200.76,351.35,197.56,352.84,192.52,352.88Z" transform="translate(-182.77 -275.17)"/><path class="cls-2" d="M228.48,378.16c-5.69.06-9-2.26-11.2-6.11a9.71,9.71,0,0,1,.8-11.28c17.71-23.09,41-37.62,69.2-44.2,5.59-1.3,11.28,2.58,12.63,8,1.59,6.42-1.53,12.16-8.11,13.87a110.09,110.09,0,0,0-24.27,9,100.52,100.52,0,0,0-31.21,26C234,376.28,231.31,378.28,228.48,378.16Z" transform="translate(-182.77 -275.17)"/></svg>
<svg id="e9915989-cca6-4620-8282-9db0f616b757" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 120">
<path
d="M77.55,29.69,92,18.78a1.42,1.42,0,0,0,.25-2,39.2,39.2,0,0,0-56.31-4.21A38.05,38.05,0,0,0,23.23,42a38.09,38.09,0,0,0,3.62,15.1A38.65,38.65,0,0,0,37.8,70.84,39.46,39.46,0,0,0,83.37,73a38.26,38.26,0,0,0,8.41-7.4,1.41,1.41,0,0,0-.23-2L77.65,53a1.43,1.43,0,0,0-1.9.15A17,17,0,0,1,72.55,56a17.75,17.75,0,0,1-9,2.88c-8.32.31-13.62-5.69-14-6.13a17.68,17.68,0,0,1-4.13-10.13,17.93,17.93,0,0,1,4.56-13A17.46,17.46,0,0,1,71.7,26.34a17.3,17.3,0,0,1,4,3.2A1.41,1.41,0,0,0,77.55,29.69Z"
style="fill: #333;"
/>
<path
d="M13,63.17a2.77,2.77,0,0,1,3.75,1.43A48.38,48.38,0,0,0,32.07,84.53,48.83,48.83,0,0,0,52.34,93.3,47.37,47.37,0,0,0,92.57,81.8a2.77,2.77,0,0,1,4,.3l6.23,7.4a2.79,2.79,0,0,1-.21,3.83,63.83,63.83,0,0,1-6,5,62.21,62.21,0,0,1-7.44,4.7A60.84,60.84,0,0,1,77,108a62.3,62.3,0,0,1-27,1.51A62.51,62.51,0,0,1,40.18,107,61.5,61.5,0,0,1,20.1,95.69,61.73,61.73,0,0,1,2.41,71a2.79,2.79,0,0,1,1.42-3.55Z"
style="fill: #333;"
/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,51 +0,0 @@
require('regenerator-runtime/runtime');
const server = require('umi-server');
const Koa = require('koa');
const compress = require('koa-compress');
const mount = require('koa-mount');
const { join, extname } = require('path');
const isDev = process.env.NODE_ENV === 'development';
const root = join(__dirname, 'dist');
const render = server({
root,
polyfill: false,
dev: isDev,
stream: true,
});
const app = new Koa();
app.use(
compress({
threshold: 2048,
flush: require('zlib').Z_SYNC_FLUSH,
}),
);
app.use(async (ctx, next) => {
const ext = extname(ctx.request.path);
// 符合要求的路由才进行服务端渲染,否则走静态文件逻辑
if (!ext) {
ctx.type = 'text/html';
ctx.status = 200;
const { ssrStream } = await render({
req: {
url: ctx.request.url,
},
});
ctx.body = ssrStream;
} else {
await next();
}
});
app.use(mount('/dist', require('koa-static')(root)));
if (!process.env.NOW_ZEIT_ENV) {
app.listen(3000);
console.log('http://localhost:3000');
}
module.exports = app.callback();

View File

@ -1,133 +0,0 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read http://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if ('serviceWorker' in navigator) {
console.log("The URL constructor is available in all browsers that support SW")
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
console.log("Our service worker won't work if PUBLIC_URL is on a different origin from what our page is served on.")
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
console.log('Loading event...')
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit http://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

View File

@ -1,6 +0,0 @@
const Enzyme = require('enzyme');
// this is where we reference the adapter package we installed
// earlier
const EnzymeAdapter = require('enzyme-adapter-react-16');
// This sets up the adapter to be used by Enzyme
Enzyme.configure({ adapter: new EnzymeAdapter() });

View File

@ -1,717 +0,0 @@
import * as Endpoints from 'globals/endpoints/index.js'
import * as Icons from 'components/Icons'
import localforage from 'localforage'
import { format } from 'timeago.js'
import * as antd from 'antd'
import moment from 'moment'
import config from 'config'
import './libs.js'
export * from '../../config/app.settings.js'
export * from './libs.js'
export * from 'utils'
export const package_json = require('../../package.json')
export const UUAID = `${package_json.name}==${package_json.UUID}`
export const endpoints = Endpoints
const prefix = package_json.name
export const AppInfo = {
apid: package_json.name,
stage: package_json.stage,
name: package_json.title,
version: package_json.version,
logo: config.FullLogoPath,
logo_dark: config.DarkFullLogoPath,
}
localforage.config({
name: UUAID,
version: 1.0,
size: 4980736,
storeName: package_json.name,
})
/**
* Convert a base64 string in a Blob according to the data and contentType.
*
* @param b64Data {String} Pure base64 string without contentType
* @param contentType {String} the content type of the file i.e (image/jpeg - image/png - text/plain)
* @param sliceSize {Int} SliceSize to process the byteCharacters
* @return Blob
*/
export function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || ''
sliceSize = sliceSize || 512
var byteCharacters = atob(b64Data)
var byteArrays = []
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize)
var byteNumbers = new Array(slice.length)
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
var byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
var blob = new Blob(byteArrays, { type: contentType })
return blob
}
/**
* Convert a file in a B64 string according to the file.
*
* @param file {object} Raw File object
* @return b64 {string}
*/
export function ReadFileAsB64(file, callback) {
if (file) {
var reader = new FileReader()
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result
const a = `data:image/png;base64, ${btoa(binaryString)}`
return callback(a)
}
reader.readAsBinaryString(file)
}
}
/**
* Handle temporal file uploads
*
* @param file {object} Raw File object
* @return boolean
*/
export function uploadFile(file) {
var formData = new FormData()
formData.append('userfile', file)
var request = new XMLHttpRequest()
request.onload = function() {
if (request.status == 200) {
return true
} else {
alert('Error! Upload failed')
}
}
request.open('POST', '/temp/file')
request.send(formData)
}
/**
* Return the value of an object from array
*
* @param payload {object} data: (array) | key: (string for return the value)
* @return {string} Boolean value
*/
export function ReturnValueFromMap(payload) {
if (!payload) return false
const { data, key } = payload
try {
const a = data.map(item => {
return item.key === key ? item.value : null
})
const b = a.filter(Boolean)
return b.toString()
} catch (error) {
return false
}
}
/**
* (HELPER) Convert the localStorage values (AppSettings) parsed
*
* @param e {String} String of SettingID for search
* @return {string} Boolean value
*/
export function SettingStoragedValue(e) {
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e ? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
} catch (error) {
return null
}
}
/**
* Return the last object from array
*
* @param array {array}
* @return object
*/
export function objectLast(array, n) {
if (array == null) return void 0
if (n == null) return array[array.length - 1]
return array.slice(Math.max(array.length - n, 0))
}
/**
* Remove an element by id from an array
*
* @param array {array}
* @param value {string}
* @return object
*/
export function arrayRemoveByID(arr, value) {
return arr.filter(function(ele) {
return ele.id != value
})
}
/**
* Remove an element by key from an array
*
* @param array {array}
* @param value {string}
* @return object
*/
export function arrayRemoveByKEY(arr, value) {
return arr.filter(function(ele) {
return ele.key != value
})
}
/**
* Global fix for convert '1, 0' to string boolean 'true, false'
*
* @param e {int} Numeric boolean reference
* @return {bool} Boolean value
*/
export function booleanFix(e) {
if (e == 1) return true
return false
}
/**
* Handle time basic functions
*
*/
export const time = {
ago: a => {
const format = moment(a).format('DDMMYYYY')
const b = new Date(format).toLocaleString()
return time.relativeToNow(b)
},
stmToAgo: a => {
const b = a * 1000
return format(b)
},
relativeToNow: (a, b) => {
return moment(a, b || 'DDMMYYYY').fromNow()
},
}
/**
* User console with setting user permissions
*
* @param ... {any} Use for type of console
*/
export const yconsole = {
log: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.log(...cont) : null
return
},
debug: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.debug(...cont) : null
return
},
error: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.error(...cont) : null
return
},
warn: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.warn(...cont) : null
return
},
}
export const __yconsole = {
showLogs: SettingStoragedValue('force_showDevLogs')? true : false,
log: (...cont) => {
console.log(...cont)
logger.consoles.indexeddb.log(...cont);
},
debug: (...cont) => {
return logger.init(function() {
logger.on(function() {
console.debug(...cont);
});
}, null, {showLogs: yconsole.showLogs});
},
error: (...cont) => {
return logger.init(function() {
logger.on(function() {
console.error(...cont);
});
}, null, {showLogs: yconsole.showLogs});
},
warn: (...cont) => {
return logger.init(function() {
logger.on(function() {
console.warn(...cont);
});
}, null, {showLogs: yconsole.showLogs});
},
}
/**
* Request FullScreen mode
*
*/
export function requestFullscreen() {
var elem = document.documentElement
if (elem.requestFullscreen) {
elem.requestFullscreen()
} else if (elem.mozRequestFullScreen) {
/* Firefox */
elem.mozRequestFullScreen()
} else if (elem.webkitRequestFullscreen) {
/* Chrome, Safari and Opera */
elem.webkitRequestFullscreen()
} else if (elem.msRequestFullscreen) {
/* IE/Edge */
elem.msRequestFullscreen()
}
}
export let logger = {
/**
* Is set with true or false after logger.init() invocation.
*/
isIndexedDBSupported: null,
showLogs: true,
//// private variables
databaseName: `${prefix}_ycoreLogger`,
database: null,
/**
* Initializes window.indexedDB and logger.isIndexedDBSupported.
* @param callbackSuccess invokes if browser supports IndexedDB.
* @param callbackFail (optional) invokes if browser does not supports IndexedDB.
*/
init: function(callbackSuccess, callbackFail, options) {
let indexedDB = window.indexedDB
let IDBTransaction = window.IDBTransaction
let IDBKeyRange = window.IDBKeyRange
// Check for options props
if (options) {
options.showLogs? logger.showLogs = options.showLogs : false
}
if (!indexedDB) {
if(callbackFail) {callbackFail();}
}
else {
if(!callbackSuccess) {
throw "IllegalAgrumentException. Please provide a callback for success initialization";
}
callbackSuccess();
}
},
/**
* Turns on catching all console.* methods invocations and saving logs into IndexedDB
* @param callback (optional) is invoked then database is successfully opened and console is replaced with logger.log2both.
*/
on: function(callback) {
if( logger.consoles.originalIsOn === false ) {
logger.consoles.originalIsOn = true;
if( logger.database != null ) {
logger.replaceConsoleThenOn(callback);
}
else {
logger.openDb(logger.databaseName, function() {
logger.replaceConsoleThenOn(callback);
});
}
}
},
off: function() {
if( logger.consoles.originalIsOn === true ) {
console = logger.consoles.original;
logger.consoles.originalIsOn = false;
}
},
isOn: function() {
return logger.consoles.originalIsOn;
},
clear: function() {
if(logger.database == null) {
throw "IllegalStateException: need to logger.init() and logger.on before clearing the database, e.g. logger.init(function(){logger.on(function(){logger.clear();});});";
}
logger.consoles.original.log("logger.clear");
var objectStore = logger.database.transaction("logs").objectStore("logs");
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// cursor.key + "=" + cursor.value
var request = logger.database.transaction(["logs"], "readwrite").objectStore("logs").delete(cursor.key);
request.onsuccess = function(event) {
// It's gone!
};
cursor.continue();
}
else {
logger.consoles.original.log("logs2indexeddb successfully cleared");
}
};
},
/**
* Opens a file with logs.
* If parameters are null (not specified) then method downloads all logs from database.
* If parameters are specified, then the method filters logs and provide only records
* that were created since fromDate to toDate.
* @param fromDate (optional)
* @param toDate (optional)
*/
download: function(fromDate, toDate) {
var fromTime = null;
var toTime = null;
if(fromDate != null) {
if(toDate != null) {
if(typeof(fromDate.getTime) === "undefined" || typeof(toDate.getTime) === "undefined" ) {
throw "IllegalArgumentException: parameters must be Date objects";
}
fromTime = fromDate.getTime();
toTime = toDate.getTime();
}
else {
throw "IllegalArgumentException: Please provide either both parameters or none of them";
}
}
var objectStore = logger.database.transaction("logs").objectStore("logs");
var data = '';
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
var v = cursor.value;
if( fromTime == null || fromTime <= v.time && v.time <= toTime) {
data += new Date(v.time*1)+" "+ v.label+" "+ v.log+"\n";
}
cursor.continue();
}
else {
logger.downloadFile(data);
}
};
},
downloadToday: function() {
var start = new Date();
start.setHours(0,0,0,0);
var end = new Date();
end.setHours(23,59,59,999);
logger.download(start, end);
},
/**
* @private
*/
downloadFile: function(data){
if(!data) {
logger.consoles.original.log("logger.download: Empty database");
return;
}
var filename = 'console.log'
var blob = new Blob([data], {type: 'text/plain'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/plain', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
},
clearAndDrop: function() {
logger.clear();
// todo replace with database drop
},
consoles: {
originalIsOn: false,
/**
* @private Logs into both - console and indexeddb
*/
both: {
log: function(str) {
logger.showLogs ? logger.consoles.original.log(str) : null
logger.consoles.indexeddb.log(str);
},
warn: function(str) {
logger.showLogs ? logger.consoles.original.warn(str) : null
logger.consoles.indexeddb.warn(str);
},
trace: function(str) {
logger.showLogs ? logger.consoles.original.trace(str) : null
logger.consoles.indexeddb.trace(str);
},
error: function(str) {
logger.showLogs ? logger.consoles.original.error(str) : null
logger.consoles.indexeddb.error(str);
},
info: function(str) {
logger.showLogs ? logger.consoles.original.info(str) : null
logger.consoles.indexeddb.info(str);
},
debug: function(str) {
logger.showLogs ? logger.consoles.original.debug(str) : null
logger.consoles.indexeddb.debug(str);
}
},
/**
* @private Original console logger. No matter if logger is on or off. Is used for internal logger logging during test.
*/
original: console,
/**
* @public Logger that saves data into opened IndexedDB.
*/
indexeddb: {
log: function(str) {
logger.consoles.indexeddb.write2db('log', str);
},
warn: function(str) {
logger.consoles.indexeddb.write2db('warn', str);
},
trace: function(str) {
logger.consoles.indexeddb.write2db('trace', str);
},
error: function(str) {
logger.consoles.indexeddb.write2db('error', str);
},
info: function(str) {
logger.consoles.indexeddb.write2db('info', str);
},
debug: function(str) {
logger.consoles.indexeddb.write2db('debug', str);
},
write2db: function(label, str) {
var time = new Date();
time.setMonth(time.getMonth()-1);
var data = {
time: time.getTime()+'',
label: label,
log: str
};
logger.database.transaction(["logs"], "readwrite").objectStore("logs").add(data);
}
}
},
exceptions: {
uncatchable: {
on: function() {
if( logger.isOn() ) {
window.onerror = logger.exceptions.uncatchable.onerror.both;
}
else {
logger.consoles.original.warn("logger needs to be on to start catch uncatchable exceptions");
}
},
off: function() {
window.onerror = logger.exceptions.uncatchable.onerror.original;
},
onerror: {
original: window.onerror,
/**
* Logs exception into the database
*/
custom: function (errorMsg, url, lineNumber) {
logger.consoles.indexeddb.error(errorMsg+" "+url+" line:"+lineNumber);
return false;
},
both: function (errorMsg, url, lineNumber) {
logger.exceptions.uncatchable.onerror.custom("UNCATCHABLE: ----------------"+errorMsg, url, lineNumber);
if( logger.exceptions.uncatchable.onerror.original ) {
logger.exceptions.uncatchable.onerror.original(errorMsg, url, lineNumber);
}
}
}
}
},
/**
* @private Opens database and updates schema if needed.
* @param dbName database name
* @param callbackSuccessOpen (optional) invoked after success connect and update.
* @param onupgradeneeded (optional) function to create different structure of the database.
*/
openDb: function(dbName, callbackSuccessOpen, onupgradeneeded) {
logger.consoles.original.log("openDb ...");
// Let us open our database
var request = indexedDB.open(dbName, 2);
request.onerror = function (event) {
alert("Why didn't you allow my web app to use IndexedDB?!");
logger.consoles.original.error("openDb:", event.target.errorCode);
};
request.onsuccess = function (e) {
logger.database = request.result;
logger.consoles.original.log("openDb DONE");
logger.database.onerror = function (event) {
// Generic error handler for all errors targeted at this database's
// requests!
logger.consoles.original.error("Database error: " + event.target.errorCode);
};
if(callbackSuccessOpen) {callbackSuccessOpen();}
};
// This event is only implemented in recent browsers
request.onupgradeneeded = function (event) {
logger.consoles.original.log("openDb.onupgradeneeded");
var db = event.target.result;
var objectStore = db.createObjectStore("logs", { autoIncrement : true });
// Create an index to search by time
objectStore.createIndex("time", "time", { unique: false });
objectStore.createIndex("label", "label", { unique: false });
objectStore.transaction.oncomplete = function (event) {
logger.consoles.original.log("openDb.onupgradeneeded.transaction.oncomplete");
}
};
},
/**
* @private
*/
replaceConsoleThenOn: function(callback) {
console = logger.consoles.both;
logger.exceptions.uncatchable.on();
if( callback ) callback();
},
/**
* Performance test methods.
* Use
* $(function () { // This is JQuery construction that needed to be sure that html document is loaded
logger.init(function() {// successfully initialized
logger.debug.startIndexedDBTest(5000, 'status');
}, function() {// error
window.alert("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.");
logger.debug.status.html("<span style='color: red;>Error: Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.</span>");
});
});
* <p id="status"></p>
* to test 5000 writes.
*/
debug: {
statusElementId: null,
startTime: null,
totalNumberOfWrites: null,
/**
* Opens database and starts WriteTest
* @param n number of records to write during the test.
* @param statusElementId html element's id to write results of the test.
*/
startIndexedDBTest: function(n, statusElementId) {
if( !n || !statusElementId ) {
throw "IllegalArgumentsException";
}
logger.debug.statusElementId = statusElementId;
logger.debug.status('Testing...');
logger.openDb("logs2indexeddb_test", function() {
logger.debug.processWriteTest(logger.database, n);
}, logger.debug.onupgradeneeded);
},
onupgradeneeded: function (event) {
logger.consoles.original.log("debug.onupgradeneeded");
var db = event.target.result;
// Create an objectStore to hold information about our customers. We're
// going to use "ssn" as our key path because it's guaranteed to be
// unique.
var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
// Create an index to search customers by name. We may have duplicates
// so we can't use a unique index.
objectStore.createIndex("name", "name", { unique: false });
// Create an index to search customers by email. We want to ensure that
// no two customers have the same email, so use a unique index.
objectStore.createIndex("email", "email", { unique: true });
// Use transaction oncomplete to make sure the objectStore creation is
// finished
objectStore.transaction.oncomplete = function (event) {
logger.consoles.original.log("debug.onupgradeneeded.transaction.oncomplete");
}
},
/**
* @private
*/
processWriteTest: function(db, n) {
logger.consoles.original.log("processWriteTest");
logger.debug.status('Connected to database. Preparing to process ' + n + " writes.");
alert("The test can take a lot of time (1-2 minutes). The browser can be locked duting the test. Ready to launch?");
logger.debug.status("Testing... Please wait until test will be finished.");
logger.debug.totalNumberOfWrites = n;
logger.debug.startTime = new Date();
for (var i = 0; i < n; i++) {
// status("Writing "+i+" record..."); // Comment this to get real time estimate
logger.debug.processWrite(db, i);
}
// The write will be finished after last callback
},
/**
* @private
*/
testFinished: function () {
logger.consoles.original.log("testFinished");
var n = logger.debug.totalNumberOfWrites;
var end = new Date();
var diff = end.getMinutes() * 60 + end.getSeconds() - (logger.debug.startTime.getMinutes() * 60 + logger.debug.startTime.getSeconds());
var mean = diff / n;
alert("Done. Check the result on the page.");
logger.debug.status("One write request takes <b>" + mean + "</b> seconds.<br>Test time: " + diff + " seconds");
},
/**
* @private
*/
processWrite: function (db, i) {
// logger.consoles.original.log("processWrite");
var transaction = db.transaction(["customers"], "readwrite");
// Do something when all the data is added to the database.
transaction.oncomplete = function (event) {
// logger.consoles.original.log("processWrite.transaction.oncomplete");
};
transaction.onerror = function (event) {
// Don't forget to handle errors!
// logger.consoles.original.error("processWrite.transaction.onerror: "+event.code);
};
var objectStore = transaction.objectStore("customers");
var data = { ssn: i, name: "Bill", age: 35, email: "mail" + i + "@rtlservice.com" }
var request = objectStore.put(data);
request.onsuccess = function (event) {
// event.target.result == customerData[i].ssn;
// logger.consoles.original.log("processWrite.transaction...onsuccess: "+event.target.result);
if (i == logger.debug.totalNumberOfWrites - 1) {
logger.debug.testFinished();
}
};
request.onerror = function () {
logger.consoles.original.error("addPublication error", this.error);
}
},
status: function (str) {
document.getElementById(logger.debug.statusElementId).innerHTML = str;
}
}
}

View File

@ -1,33 +0,0 @@
// ERROR FLAGS CODES
const flags = {
CRITICAL_ERROR: 1000,
EXCEPTION_ERROR: 1010,
WARNING_ERROR: 1020,
API_FAIL: 100,
API_BADRESPONSE: 110,
API_BADCREDENTIAL: 120,
}
function flag_handle(flag, ...pass){
if (!flag) return false
switch (flag) {
case flags.CRITICAL_ERROR:
const CRITICAL_ERROR = `${flags.CRITICAL_ERROR} | ${JSON.stringify(...pass)}`
console.error(CRITICAL_ERROR)
throw new Error(CRITICAL_ERROR)
case flags.EXCEPTION_ERROR:
const EXCEPTION_ERROR = `${flags.EXCEPTION_ERROR} | ${JSON.stringify(...pass)}`
console.warn(EXCEPTION_ERROR)
return
case flags.WARNING_ERROR:
const WARNING_ERROR = `${flags.WARNING_ERROR} | ${JSON.stringify(...pass)}`
console.warn(WARNING_ERROR)
return
default:
break;
}
}
module.exports.flags = flags
module.exports.flags_handle = flag_handle

View File

@ -1,6 +0,0 @@
// List of modules used for this app
export * from './libs/comty_ng/pre.js';
export * from './libs/yulio_id/pre.js';
export * from './libs/app_functions/pre.js';
export * from './libs/api_call/pre.js';
export * from './libs/apis/pre.js'

View File

@ -1,94 +0,0 @@
import jquery from 'jquery'
import * as app from 'app'
export function API_Call(callback, endpoint, payload, options, __token) {
var prefix = `[API_Call] `
if (!endpoint) return false
if (!payload) {
app.yconsole.log(prefix, 'Calling api without Payload!!!')
}
let payloadContainer = payload ? payload : new FormData()
payloadContainer.append('server_key', app.__server.getKey())
const defaultOptions = {
method: 'POST',
timeout: 0,
processData: false,
includeUserID: false,
override__token: false,
disabledToken: false,
}
let fendpoint
let method = defaultOptions.method
let timeout = defaultOptions.timeout
let processData = defaultOptions.processData
let includeUserID = defaultOptions.includeUserID
let override__token = defaultOptions.override__token
let disabledToken = defaultOptions.disabledToken
if (options) {
options.method ? (method = options.method) : null
options.timeout ? (timeout = options.timeout) : null
options.processData ? (processData = true) : null
options.includeUserID ? (includeUserID = options.includeUserID) : null
options.override__token ? (override__token = options.override__token) : null
options.disabledToken ? (disabledToken = options.disabledToken) : null
}
if (disabledToken) {
app.yconsole.log(`${prefix} Dimmissing the token generation`)
fendpoint = `${endpoint}`
}
if (!disabledToken && !override__token) {
fendpoint = `${endpoint}?access_token=${app.token_data.__token()}`
}
if (override__token || __token) {
if (!__token) {
app.yconsole.log(`${prefix} Missing Overriding __token`)
return
}
app.yconsole.log(`${prefix} Overriding __token => ${__token}`)
fendpoint = `${endpoint}?access_token=${__token}`
}
if (includeUserID) {
payloadContainer.append('user_id', app.token_data.__id())
}
const requestOptions = {
url: fendpoint,
method: method,
timeout: timeout,
data: payloadContainer,
mimeType: 'multipart/form-data',
processData: processData,
contentType: false,
}
jquery
.ajax(requestOptions)
.done(response => {
try {
const a = JSON.parse(response)['api_status']
if (a == '404') {
app.api_err.tokenError(response)
}
} catch (error) {
app.yconsole.log(
'[VIOLATION] The status of the request has not been identified!'
)
app.api_err.violation()
}
app.yconsole.debug(response)
return callback(false, response)
})
.fail(error => {
app.yconsole.debug(`${prefix} (ERROR) `, error)
app.api_err.fail(error)
return callback(true, error)
})
}

View File

@ -1,34 +0,0 @@
import * as app from 'app'
export * from './api_call.js'
import keys from '../../../../config/keys.js'
export const api_err = {
fail: a => {
if (a) {
app.yconsole.log(a)
app.notify.error(a)
}
},
tokenError: a => {
app.notify.expire(
'It seems that your token has expired or no longer exists'
)
app.router.go('login')
},
violation: a => {
app.notify.expire(
'It seems that there has been a problem with your token, we need you to log in again.'
)
app.router.go('login')
},
}
export const __server = {
getKey: () => {
return keys.server_key
},
}
export function gen_endpoint(endpoint) {
return `${app.AppSettings.__global_server_prexif}${endpoint}`
}

View File

@ -1 +0,0 @@
export * from './unsplash.js'

View File

@ -1,16 +0,0 @@
import axios from 'axios'
import * as app from 'app'
import keys from 'keys'
export const api_unsplash = {
search: async (key, callback) => {
if (!key) return false
const response = await axios.get(app.endpoints.unsplash_endpoints.search, {
params: { query: key},
headers: {
Authorization: `Client-ID ${keys.unsplash_key}`
}
})
return callback(response.data.results)
}
}

View File

@ -1,200 +0,0 @@
import { transitionToogle } from '../../../pages/login'
import { SetControls, CloseControls } from 'components/Layout/ControlBar'
import umiRouter from 'umi/router'
import * as app from 'app'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import React from 'react'
import { SwapMode } from 'components/Layout/Overlay'
import { RenderFeed } from 'components/MainFeed'
import { updateTheme } from '../../../layouts/PrimaryLayout'
export * from './modals.js'
export * from './notify.js'
export {SwapMode}
export {RenderFeed}
export const ControlBar = {
set: e => {
SetControls(e)
},
close: () => {
CloseControls()
},
}
export const router = {
go: e => {
goTo.element('primaryContent')
umiRouter.push({
pathname: `/${e}`,
search: window.location.search,
})
},
push: e => {
umiRouter.push({
pathname: `/${e}`,
search: window.location.search,
})
},
goprofile: () => {
goTo.element('primaryContent')
umiRouter.push({
pathname: `/@${app.userData().username}`,
search: window.location.search,
})
}
}
export const goTo = {
top: (id)=> {
const element = document.getElementById(id)
element.scrollTop = element.scrollHeight + element.clientHeight
},
bottom: (id) => {
const element = document.getElementById(id)
element.scrollTop = element.scrollHeight - element.clientHeight
},
element: (element) => {
try {
document.getElementById(element).scrollIntoView()
} catch (error) {
console.debug(error)
return false
}
}
}
export const app_session = {
login: (callback, payload) => {
if (!payload) {
return false
}
const { EncUsername, EncPassword } = payload
let username = atob(EncUsername)
let password = atob(EncPassword)
const containerpayload = { username, password }
app.yulio_id.auth((err, res) => {
if (err) {
return false
}
try {
var identState = JSON.parse(res)['api_status']
if (identState == 200) {
const UserID = JSON.parse(res)['user_id']
const UserToken = JSON.parse(res)['access_token']
const preframepayload = { user_token: UserToken, user_id: UserID}
app.yulio_id.getData(
(err, res) => {
if (err) {
return false
}
let framepayload = { token: { UserID, UserToken }, sdcp: res }
app.yconsole.log('FRAME ', framepayload)
app.__CTID_GEN((err, res) => {
if (err) {
app.notify.error('Critical error, token declined!')
return false
}
app._app.setup()
callback(null, '200')
}, framepayload)
},
preframepayload
)
}
if (identState == 400) {
callback(null, '400')
}
} catch (error) {
console.log(error)
callback(true, '500')
app.notify.error('Server bad response')
}
}, containerpayload)
},
logout: () => {
app.yulio_id.logout((err, res) => {
if (err) {
return false
}
console.log(res)
const api_state = JSON.parse(res)['api_status']
app.yconsole.log(`Exit with => ${api_state}`)
if (api_state == '404') {
antd.notification.open({
placement: 'topLeft',
message: 'Unexpectedly failed logout in YulioID™ ',
description:
'It seems that your token has been removed unexpectedly and could not log out from YulioID ',
icon: <Icons.WarningOutlined style={{ color: 'orange' }} />,
})
app.yconsole.log('Failed logout with YulioID™', res)
} else {
app.yconsole.log('Successful logout with YulioID™', res)
}
// Runtime after dispatch API
app.token_data.remove()
app.router.push('login')
})
},
}
export const app_theme = {
getString: () => {
return localStorage.getItem('theme_style')
},
set: (data, process) => {
if (!data){
return false
}
let newdata = []
if(process){
let style = data
let mix = []
try {
style[key] = value
const obj = Object.entries(style)
obj.forEach((e) => {
mix.push({key: e[0], value: e[1]})
})
newdata = JSON.stringify(mix)
} catch (error) {
console.log(error)
return false
}
}else{
newdata = data
}
localStorage.setItem('theme_style', newdata)
app_theme.update()
},
getStyle: () => {
let final = {}
const storaged = localStorage.getItem('theme_style')
if (storaged) {
try {
let scheme = JSON.parse(storaged)
scheme.forEach((e)=>{
final[e.key] = e.value
})
} catch (error) {
console.log(error)
}
}
return final
},
update: () => {
return updateTheme(app_theme.getStyle())
}
}

View File

@ -1,87 +0,0 @@
import { API_Call, gen_endpoint } from 'app'
export const comty_data = {
sessions: (callback) => {
let formdata = new FormData()
formdata.append('type', 'get')
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("sessions"),
formdata
)
},
session_id: callback => {
let formdata = new FormData()
formdata.append('type', 'get')
API_Call((err,res) => {
if (err) return false
try {
const a = JSON.parse(res)['data']
return callback(err, a.session_id)
} catch (error) {
return callback(err, '0x0000')
}
},
gen_endpoint("session_id"),
formdata)
},
session: (callback) => {
let formdata = new FormData()
formdata.append('type', 'get')
API_Call((err,res) => {
return callback(err, res)
},
gen_endpoint("session_id"),
formdata)
},
general_data: (callback, payload) => {
let formdata = new FormData();
let callOptions = { includeUserID: false };
if (!payload) {
callOptions = { includeUserID: true }
formdata.append('fetch', 'notifications,friend_requests,pro_users,promoted_pages,trending_hashtag,count_new_messages')
}
if (payload) {
payload.user_id? formdata.append('user_id', payload.user_id) : null
payload.fetch? formdata.append('fetch', payload.fetch) : null
}
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("get-general-data"),
formdata, callOptions
)
},
get_user_data: (callback, payload) => {
let formdata = new FormData();
let callOptions = { includeUserID: false };
if (!payload) {
callOptions = { includeUserID: true }
formdata.append('fetch', 'user_data')
}
if (payload) {
payload.user_id? formdata.append('user_id', payload.user_id) : null
payload.fetch? formdata.append('fetch', payload.fetch) : null
}
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint('get-user-data'),
formdata, callOptions
)
}
}

View File

@ -1,216 +0,0 @@
import { API_Call, endpoints, AppSettings, yconsole, gen_endpoint} from 'app'
export const comty_post = {
getFeed: (callback, payload) => {
if (!payload) {
return false
}
const { fkey, type, id } = payload
let formdata = new FormData()
formdata.append('after_post_id', fkey || 0)
formdata.append('limit', AppSettings.limit_post_catch || 20)
switch (type) {
case 'feed':
formdata.append('type', 'get_news_feed')
break
case 'user':
formdata.append('type', 'get_user_posts')
formdata.append('id', id)
break
default:
formdata.append('type', 'get_news_feed')
break
}
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("posts"),
formdata
)
},
get: (callback, payload) => {
if (!payload) {
return false
}
const { post_id, fetch } = payload
let formdata = new FormData()
formdata.append('post_id', post_id)
formdata.append(
'fetch',
fetch || 'post_data,post_comments,post_wondered_users,post_liked_users'
)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("get-post-data"),
formdata
)
},
new: (callback, payload) => {
if (!payload) {
return false
}
const { privacy, text, file } = payload
let formdata = new FormData()
formdata.append('type', 'new_post')
formdata.append('postPrivacy', privacy)
formdata.append('postText', text)
file ? formdata.append('uploadFile', file) : null
const callOptions = { includeUserID: true }
API_Call(
(err, res) => {
return callback(err, res)
},
// UNIQUE API !!!
endpoints.comty_endpoints.new_post,
formdata,
callOptions
)
},
delete: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'delete')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
save: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'save')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
like: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'like')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
hashtag: (callback, payload) => {
if (!payload) return false
const { hashtag } = payload
// DOING
},
getSaved: (callback, payload) => {
if (!payload) {
yconsole.log(
'Calling api without Payload!!! | Limmit & OffsetKey = default |'
)
}
if (payload) {
const { limit, fkey } = payload
}
let formdata = new FormData()
formdata.append('type', 'saved')
formdata.append('limit', payload? limit : AppSettings.limit_post_catch || 20)
formdata.append('after_post_id', payload? fkey : 0)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("posts"),
formdata
)
},
edit: (callback, payload) => {},
__pin: (callback, payload) => {},
__boost: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'boost')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
__disableComments: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'disable_comments')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
__report: (callback, payload) => {
if (!payload) {
return false
}
const { post_id } = payload
let formdata = new FormData()
formdata.append('action', 'report')
formdata.append('post_id', post_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
}

View File

@ -1,41 +0,0 @@
import { API_Call, gen_endpoint } from 'app'
export const comty_post_comment = {
delete: (callback, payload) => {
if (!payload) {
return false
}
const { comment_id } = payload
let formdata = new FormData()
formdata.append('type', 'delete')
formdata.append('comment_id', comment_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("comments"),
formdata
)
},
new: (callback, payload) => {
if (!payload) {
return false
}
const { post_id, raw_text } = payload
let formdata = new FormData()
formdata.append('action', 'comment')
formdata.append('post_id', post_id)
formdata.append('text', raw_text)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("post-actions"),
formdata
)
},
}

View File

@ -1,23 +0,0 @@
import { API_Call, gen_endpoint } from 'app'
export const comty_search = {
keywords: (callback, payload) => {
if (!payload) {
return false
}
const { key } = payload
let formdata = new FormData()
formdata.append('search_key', key)
const callOptions = { timeout: 10000 }
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("search"),
formdata,
callOptions
)
},
}

View File

@ -1,109 +0,0 @@
import { API_Call, get_early, gen_endpoint } from 'app'
export const comty_user = {
setData: () => {},
data: {
avatar: (callback,key) => {
if(!key) return false
try {
const payload = {username: key}
get_early.user((err,res) => {
const d = JSON.parse(res)['data']
return callback(d.avatar)
},payload)
} catch (error) {
return false
}
},
},
getFollowers: (callback, payload) => {
if (!payload)return false
const { user_id } = payload
let formdata = new FormData()
formdata.append('user_id', user_id)
formdata.append('fetch', 'followers')
API_Call(
(err,res) => {
return callback(err,res)
},
gen_endpoint('get-user-data'),
formdata
)
},
follow: (callback, payload) => {
if (!payload) {
return false
}
const { user_id } = payload
let formdata = new FormData()
formdata.append('user_id', user_id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("follow-user"),
formdata
)
},
block: (callback, payload) => {
if (!payload) {
return false
}
const { user_id, block_action } = payload
let formdata = new FormData()
formdata.append('user_id', user_id)
formdata.append('block_action', block_action)
API_Call((err,res)=>{
return callback(err,res)
},
gen_endpoint('block-user'),
formdata
)
},
find: (callback, payload) => {
if (!payload) {
return false
}
const { key } = payload
let formdata = new FormData()
formdata.append('search_key', key)
const callOptions = { timeout: 10000 }
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("find_user"),
formdata,
callOptions
)
},
__tags: (callback, payload) => {
if (!payload) {
return false
}
const { id } = payload
let formdata = new FormData()
formdata.append('user_id', id)
API_Call(
(err, res) => {
return callback(err, res)
},
gen_endpoint("user_tags"),
formdata
)
},
}

View File

@ -1,119 +0,0 @@
import { token_data } from 'app'
import * as Icons from 'components/Icons'
export * from './comty_post.js'
export * from './comty_user.js'
export * from './comty_post_comment.js'
export * from './comty_search.js'
export * from './comty_data.js'
export const IsThisPost = {
owner: (post_uid) => {
const a = token_data.__id()
if (post_uid == a) {
return true
}
return false
},
boosted: () => {
},
saved: () => {
},
pinned: () => {
},
flagged: () => {
}
}
export const GetPostPrivacy = {
bool: (e) => {
switch (e) {
case 'any':
return '0'
case 'only_followers':
return '1'
case 'only_follow':
return '2'
case 'private':
return '3'
default:
return '0'
}
},
decorator: (e) => {
switch (e) {
case 'any':
return <span><Icons.GlobalOutlined /> Share with everyone</span>
case 'only_follow':
return <span><Icons.TeamOutlined /> Share with people I follow</span>
case 'only_followers':
return <span><Icons.UsergroupAddOutlined /> Share with people follow me</span>
case 'private':
return <span><Icons.EyeInvisibleOutlined /> Dont share, only me</span>
default:
return <span>Unknown</span>
}
},
}
import * as app from 'app'
import * as antd from 'antd'
import io from 'socket.io-client'
import config from 'config'
const prefix = '[Yulio Sync]'
var endpoint = config.sync_server;
export const sync = {
listen: (callback) => {
let active = true;
if (active){
let conn_overrun_tick = 0;
const socket = io(endpoint);
socket.on('connect_error', (error) => {
conn_overrun_tick ++
app.yconsole.log('Overrun tick => ',conn_overrun_tick)
if (conn_overrun_tick == 1) {
antd.notification.open({
duration: 5,
message: 'Disconected from server!',
description: 'Attempting to reconnect...',
icon: <Icons.LoadingOutlined spin />,
});
}
if (conn_overrun_tick == app.AppSettings.Maximun_tick_overrun) {
active = false;
}
});
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)
});
}else{
console.log(prefix,' Offline Mode')
}
},
FeedListen: (callback) => {
const socket = io(`${endpoint}/feed`);
socket.on('pull_event', function (data) {
console.log(data)
callback(data)
});
},
emmitPost: (last_id) => {
const socket = io(`${endpoint}/feed`);
socket.emit('push_event', last_id);
}
}

View File

@ -1,34 +0,0 @@
import * as app from 'app'
/**
* Cookies Token ID Generator
*
* @callback {func} return with (err,res) model
* @payload {object} Payload data
*/
export async function __CTID_GEN(callback, payload) {
const { token, sdcp } = payload
const { UserID, UserToken } = token
const { avatar, admin, pro, dev, is_pro, username } = sdcp
const frame = {
UserID,
UserToken,
avatar,
admin,
pro,
dev,
is_pro,
username,
exp: app.AppSettings.SignForNotExpire
? 0
: Math.floor(Date.now() / 1000) + 60 * 60,
}
console.log(frame)
app.token_data.set(frame, done => {
done ? callback(false, true) : callback(true, false)
})
}

View File

@ -1,114 +0,0 @@
import * as app from 'app'
// EXPORT PUBLIC WORKERS
export * from './token_data.js'
export * from './ctid_gen.js'
export * from './validate.js'
export function userData() {
return app.token_data.get()
}
export const IsThisUser = {
admin: () => {
return app.booleanFix(app.userData().admin) ? true : false
},
dev: () => {
return app.booleanFix(app.userData().dev) ? true : false
},
pro: () => {
return app.booleanFix(app.userData().is_pro) ? true : false
},
nsfw: () => {
return app.booleanFix(app.userData().nsfw) ? true : false
},
same: a => {
if (a == app.userData().UserID) {
return true
}
return false
},
}
export const get_early = {
user: (callback, payload)=>{
if (!payload) {
return false
}
const { username } = payload
let formdata = new FormData()
formdata.append('username', username)
const callOptions = { timeout: 10000 }
app.API_Call(
(err, res) => {
return callback(err, res)
},
app.gen_endpoint('early_user'),
formdata,
callOptions
)
}
}
export const yulio_id = {
auth: (callback, payload) => {
if (!payload) return false
const { username, password } = payload
const formdata = new FormData()
formdata.append('username', username)
formdata.append('password', password)
const callOptions = { disabledToken: true }
app.API_Call(
(err, res) => {
return callback(err, res)
},
app.gen_endpoint('auth'),
formdata,
callOptions
)
},
logout: callback => {
app.API_Call(
(err, res) => {
return callback(err, res)
},
app.gen_endpoint('delete-access-token'),
null
)
},
verify: (callback, payload) => {
// TO DO
},
sign: (callback, payload) => {
// TO DO
},
getData: (callback, payload) => {
if (!payload) return false
const { user_token, user_id } = payload
const formdata = new FormData()
formdata.append('fetch', 'user_data')
formdata.append('user_id', user_id)
const optionCall = { override__token: true }
app.API_Call(
(err, res) => {
try {
let a = JSON.parse(res)['user_data']
return callback(err, a)
} catch (error) {
return callback(true, error)
}
},
app.gen_endpoint('get-user-data'),
formdata,
optionCall,
user_token
)
},
setData: () => {
// TO DO
},
}

View File

@ -1,44 +0,0 @@
import * as app from 'app'
import Cookies from 'ts-cookies'
import {server_key} from '../../../../config/keys.js'
var jwt = require('jsonwebtoken')
export const token_data = {
set: (value, callback) => {
jwt.sign(value, server_key, (err, token) => {
err ? null : Cookies.set('cid', token)
return callback(true)
})
},
getRaw: () => {
return Cookies.get('cid')
},
get: () => {
let final =
jwt.decode(Cookies.get('cid')) ||
jwt.decode(localStorage.getItem('last_backup'))
const a = jwt.decode(Cookies.get('cid'))
const b = jwt.decode(localStorage.getItem('last_backup'))
if (!a && !b) {
final = false
return final
}
if (!a) {
final = b
}
if (!b) {
final = a
}
return final
},
remove: () => {
Cookies.remove('cid')
},
__token: () => {
return app.token_data.get().UserToken
},
__id: () => {
return app.token_data.get().UserID
},
}

View File

@ -1,64 +0,0 @@
import * as app from 'app'
import Cookies from 'ts-cookies'
var jwt = require('jsonwebtoken')
export const cid_backup = {
set: () => {
localStorage.setItem('last_backup', Cookies.get('cid'))
},
get: () => {
localStorage.getItem('last_backup')
}
}
export const validate = {
session: callback => {
let validtoken = false
const a = Cookies.get('cid')
if (a) {
const modExp = app.AppSettings.SignForNotExpire
const ad = jwt.decode(a)
let notexp = true // Sets if this is expired (Default is not expired)
let exists = false // Sets if this exist
ad ? (exists = true) : null
const tokenExp = ad.exp * 1000
const tokenExpLocale = new Date(tokenExp).toLocaleString()
const now = new Date().getTime()
app.yconsole.log(
`TOKEN EXP => ${tokenExp} ${
modExp ? '( Infinite )' : `( ${tokenExpLocale} )`
} || NOW => ${now}`
)
if (modExp == false) {
if (tokenExp < now) {
app.yconsole.log('This token is expired !!!')
notexp = false
}
}
if (notexp && exists) {
validtoken = true
}
}
if (callback) {
callback(validtoken)
}
return validtoken
},
backup: () => {
let ValidBackupToken = false
let LastestToken = cid_backup.get()
if (LastestToken) {
let LastestTokenDC = jwt.decode(LastestToken)
if (LastestTokenDC) {
ValidBackupToken = true
}
}
return ValidBackupToken
}
}

View File

@ -1,11 +1,13 @@
import React from 'react'
import styles from './index.less'
import * as app from 'app'
import { app_info, UUAID, package_json } from 'core'
import * as antd from 'antd'
const { logo, name, version, stage } = app_info
export default class App_About extends React.Component {
DetectNoNStableBuild() {
if (app.package_json.DevBuild == false) {
if (package_json.DevBuild == false) {
return <antd.Tag color="blue">Stable</antd.Tag>
} else {
return <antd.Tag color="orange">No Stable</antd.Tag>
@ -14,13 +16,13 @@ export default class App_About extends React.Component {
render() {
return (
<div className={styles.aboutWrapper}>
<img src={app.AppInfo.logo} />
<img src={logo} />
<antd.Card>
<h1 className={styles.appName}> {app.AppInfo.name} </h1>
{app.UUAID}
<h1 className={styles.appName}> {name} </h1>
{UUAID}
<br />
<antd.Tag color="geekblue">v{app.AppInfo.version}</antd.Tag>
<antd.Tag color="red">{app.AppInfo.stage}</antd.Tag>
<antd.Tag color="geekblue">v{version}</antd.Tag>
<antd.Tag color="red">{stage}</antd.Tag>
{this.DetectNoNStableBuild()}
</antd.Card>
</div>

View File

@ -1,79 +0,0 @@
import React, { Component } from 'react'
import * as antd from 'antd'
import * as app from 'app'
import styles from './index.less'
import classnames from 'classnames'
import * as Icons from 'components/Icons'
export const SetHeaderSearchType = {
disable: () => {
window.HeaderSearchComponent.setState({ searchidden: true })
},
enable: () => {
window.HeaderSearchComponent.setState({ searchidden: false })
},
}
export default class HeaderSearch extends Component {
constructor(props) {
super(props)
window.HeaderSearchComponent = this
this.state = {
value: '',
searchidden: false,
framelocation: 'primary',
}
}
openSearcher = () => {
const { value } = this.state
if (value.length < 1) return false
if (value == /\s/) return false
app.SwapMode.openSearch(value);
}
sendToSearch = () => {
const { value } = this.state
app.router.go(`s/${value}`)
}
onChange = e => {
const { value } = e.target
this.setState({ value: value })
if (app.AppSettings.auto_search_ontype == 'true') {
this.autosend()
}
}
autosend = () => {
let timeout = null
let input = document.getElementById('search_input')
input.addEventListener('keyup', e => {
clearTimeout(timeout)
timeout = setTimeout(() => {
const { value } = this.state
app.router.go(`s/${value}`)
}, 500)
})
}
render() {
const { searchidden } = this.state
return (
<div
className={classnames(styles.HeaderSearchWrapper, {
[styles.hidden]: searchidden,
})}
>
<span className={styles.headerSearch}>
<antd.Input
id="search_input"
prefix={<Icons.SearchOutlined />}
placeholder=" Search on Comty..."
onChange={this.onChange}
onPressEnter={this.openSearcher}
/>
</span>
</div>
)
}
}

View File

@ -1,78 +0,0 @@
@import '~themes/index.less';
.HeaderSearchWrapper {
z-index: 20;
top: 0;
display: flex;
margin: auto;
max-width: 510px;
min-width: 265px;
width: auto;
height: 50px;
&.hidden {
display: none;
}
}
.headerSearch {
width: 100%;
height: 100%;
:global {
.ant-input-affix-wrapper {
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
.ant-input-affix-wrapper .ant-input-prefix {
left: 12px;
}
.ant-input-affix-wrapper {
background-color: transparent !important;
border-color: transparent;
border-radius: 12px;
}
.ant-input-affix-wrapper>input.ant-input {
padding: 0 0 0 30px;
border: inherit;
outline: inherit;
}
.ant-input-affix-wrapper .ant-input-prefix,
.ant-input-affix-wrapper .ant-input-suffix {
background-color: transparent !important;
border-color: transparent;
border-radius: 12px;
position: absolute;
top: 50%;
z-index: 2;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
color: rgba(0, 0, 0, .65);
line-height: 0;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
color: #9d9da7 !important;
}
.ant-input {
border-radius: 12px;
color: #9D9DA7;
background-color: #FFFFFF;
border-color: transparent;
height: 50px;
width: 510px;
}
}
}

View File

@ -1,6 +1,6 @@
export const VerifiedBadge = () => (<svg xmlns="http://www.w3.org/2000/svg" fill="#55acee" width="15" height="15" viewBox="0 0 24 24"> <path d="M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12m-13 5l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"></path></svg>)
export const Patreon = () => (<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 100 96">
<g fill="currentColor" fill-rule="evenodd">
<g fill="currentColor" fillRule="evenodd">
<path d="M64.1102,0.1004 C44.259,0.1004 28.1086,16.2486 28.1086,36.0986 C28.1086,55.8884 44.259,71.989 64.1102,71.989 C83.9,71.989 100,55.8884 100,36.0986 C100,16.2486 83.9,0.1004 64.1102,0.1004"/>
<polygon points=".012 95.988 17.59 95.988 17.59 .1 .012 .1"/>
</g>

View File

@ -1,7 +1,6 @@
import React from 'react'
import * as antd from 'antd'
import * as app from 'app'
import styles from './Control.less'
import styles from './index.less'
import classnames from 'classnames'
import Radium, { StyleRoot } from 'radium'
@ -35,15 +34,13 @@ class Control extends React.PureComponent {
FadeIN: true,
}
}
DummySetControls = e => {
app.yconsole.log('Controls recived => ', e)
set = e => {
if (this.state.Show == false) {
this.setState({ FadeIN: true })
}
this.setState({ Show: true, RenderFragment: e })
}
DummyCloseControls() {
app.yconsole.log('Closing Control Bar...')
close() {
this.setState({ FadeIN: false })
setTimeout(() => this.setState({ Show: false, RenderFragment: null }), 1000)
}

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.ControlCard {
overflow: hidden;

View File

@ -1,6 +1,6 @@
import React from 'react'
import * as app from 'app'
import styles from './__searchBar.less'
import {newSearch} from "core/cores/interface_helper"
export default class __searchBar extends React.Component{
state = {
@ -10,15 +10,13 @@ export default class __searchBar extends React.Component{
const { value } = this.state
if (value.length < 1) return false
if (value == /\s/) return false
app.SwapMode.openSearch(value);
newSearch({ keyword: value });
}
onChange = e => {
const { value } = e.target
this.setState({ value: value })
if (app.AppSettings.auto_search_ontype == 'true') {
this.autosend()
}
}
handleKey = (e) =>{
if (e.key == 'Enter') {
this.openSearcher()
@ -30,7 +28,6 @@ export default class __searchBar extends React.Component{
<input
placeholder="Search on Comty..."
onChange={this.onChange}
onPressEnter={this.openSearcher}
onKeyPress={this.handleKey}
/>
</div>

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.search_bar {
height: 24px;

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.trendings{
word-break: break-all;

View File

@ -1,26 +1,16 @@
import Primary from './layout/Primary.tsx'
import Secondary from './layout/Secondary.tsx'
import Card_Component from './Card_Component.tsx'
import Card_Component from './component.tsx'
import __sec from './layout/__sec.tsx'
import __pri from './layout/__pri.tsx'
import __searchBar from './main/__searchBar'
import __trendings from './main/__trendings'
import __suggestions from './main/__suggestions'
import __priPost from './swapper/__priPost'
import __secComments from './swapper/__secComments'
import __priSearch from './swapper/__priSearch'
import __searchBar from './cards/__searchBar'
import __trendings from './cards/__trendings'
import __suggestions from './cards/__suggestions'
export {
Card_Component,
__sec,
__pri,
__trendings,
Secondary,
Primary,
__searchBar,
__trendings,
__suggestions,
__priPost,
__secComments,
__priSearch
}

View File

@ -0,0 +1,52 @@
import * as React from 'react'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from '../../index.less'
import classnames from 'classnames'
import { Swapper } from '../../index.tsx'
export interface overlay_primary_props {
y?: number;
getRef: React.Ref<HTMLDivElement>;
isMobile: boolean;
fragment: any;
mode: string;
closable: boolean;
}
const renderExit = (
<div className={styles.exit_button}>
<antd.Button type="ghost" icon={<Icons.LeftOutlined />} onClick={() => Swapper.closeAll()}> Back </antd.Button>
</div>
)
const overlay_primary = (props: overlay_primary_props) => {
const { fragment, mode, isMobile } = props
return (
<div
id="overlay_primary"
className={classnames(styles.overlay_primary_wrapper, {
[styles.full]: mode === 'full'? true : false,
[styles.half]: mode === 'half'? true : false,
})}
>
<div className={styles.renderBody}>
{props.mode === 'full' || props.mode === 'half'? renderExit : null}
<React.Fragment>{fragment}</React.Fragment>
</div>
</div>
)
}
overlay_primary.defaultProps = {
mode: false,
fragment: null,
isMobile: false,
closable: true,
y: 0,
}
export default overlay_primary

View File

@ -4,7 +4,6 @@ import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from '../../index.less'
import classnames from 'classnames'
import reactable from 'reactablejs'
export interface __sec_props {
y?: number;

View File

@ -1,70 +0,0 @@
import * as React from 'react'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from '../../index.less'
import classnames from 'classnames'
import reactable from 'reactablejs'
export interface __pri_props {
y?: number;
getRef: React.Ref<HTMLDivElement>;
isMobile: boolean;
functs: any;
render: any;
type: any;
}
const isOpen = (props: __pri_props) => {
const t_full = props.type === 'full_open'? true : false
const t_half = props.type === 'half'? true: false
if (t_full || t_half ) {
return true
}
return false
}
const renderExit = (props: __pri_props) => {
const {functs} = props
if (isOpen) {
return <div className={styles.exit_button}>
<antd.Button type="ghost" icon={<Icons.LeftOutlined />} onClick={() => functs.Swapper.close()}> Back </antd.Button>
</div>
}
return null
}
const __pri = (props: __pri_props) => {
const { render, type, isMobile } = props
const t_full = type == 'full_open'? true : false
const t_half = type == 'half'? true : false
return (
<div
id="Overlay_layout_pri"
className={classnames(styles.Overlay_container_1, {
[styles.mobile]: isMobile,
[styles.full_open]: t_full,
[styles.half]: t_half,
})}
>
<div className={styles.pri_body}>
{renderExit}
<React.Fragment>{render}</React.Fragment>
</div>
</div>
)
}
__pri.defaultProps = {
render: null,
y: 0,
isMobile: false,
functs: null,
type: null,
}
export default __pri

View File

@ -1,29 +0,0 @@
import React from 'react'
import styles from './__priPost.less'
import * as antd from 'antd'
import * as app from 'app'
import * as Icons from 'components/Icons'
import Icon from '@ant-design/icons'
import { MediaPlayer, PostCard } from 'components'
export default class __priPost extends React.PureComponent {
render() {
const {payload} = this.props
if (!payload) {
return <h1>This post not exists!!!</h1>
}
const { id, postText, postFile_full, post_time, publisher } = payload
const {isMobile}= this.props
return (
<div className={styles.contentWrapper}>
<div className={styles.contentBody}>
<PostCard id="post_card" payload={payload} key={id} />
</div>
</div>
)
}
}

View File

@ -1,27 +0,0 @@
@import '~themes/index.less';
.contentWrapper {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
align-items: center;
margin: auto;
background: rgba(158, 158, 158, 0.5); // Make sure this color has an opacity of less than 1
backdrop-filter: blur(10px); // This be the blur
display: flex;
align-items: center;
transition: all @__Global_SwapAnimDuration ease-in-out;
}
.contentBody{
position: relative;
width: calc(100% - @Overlay_container2_active_width);
}

View File

@ -1,120 +0,0 @@
import React from 'react'
import styles from './__priSearch.less'
import * as antd from 'antd'
import * as app from 'app'
import Icon from '@ant-design/icons'
const VerifiedBadge = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="#55acee"
width="15"
height="15"
viewBox="0 0 24 24"
>
<path d="M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12m-13 5l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"></path>
</svg>
)
export default class __priSearch extends React.PureComponent {
renderResult = source => {
try {
const Empty = (
<div>
<antd.Result
status="404"
title="Nothing..."
subTitle="Sorry, this does not exist."
/>
</div>
)
// TO DO: Settings serach & Post Search
const usersParsed = JSON.parse(source)['users']
const groupsParsed = JSON.parse(source)['groups']
const pagesParsed = JSON.parse(source)['pages']
const users = () => {
if (usersParsed.length >= 1) {
app.yconsole.log('Users => ', usersParsed)
return this.EntryComponent('Users', usersParsed)
}
}
const groups = () => {
if (groupsParsed.length >= 1) {
app.yconsole.log('Groups => ', groupsParsed)
return this.EntryComponent('Groups', groupsParsed)
}
}
const pages = () => {
if (pagesParsed.length >= 1) {
app.yconsole.log('Pages => ', pagesParsed)
return this.EntryComponent('Pages', pagesParsed)
}
}
if (
!usersParsed.length >= 1 &&
!groupsParsed.length >= 1 &&
!pagesParsed.length >= 1
) {
return Empty
}
return [users(), groups(), pages()]
} catch (error) {
return (
<center>
<h2>Render Error</h2>
</center>
)
}
}
EntryComponent = (t, source) => {
function goToEntry(e){
if(!e) return false
app.router.go(`@${e}`)
}
try {
return (
<antd.List
dataSource={source}
renderItem={item =>
<div id={item.id} className={styles.search_card} onClick={() => goToEntry(item.username) }>
<div className={styles.search_title}>
<img src={item.avatar} />
<p className={styles.search_user_username}>
@{item.username}
{app.booleanFix(item.verified) ? (
<Icon component={VerifiedBadge} />
) : null}
</p>
</div>
<div className={styles.search_text}>
<p>{item.about}</p>
</div>
</div>
}
/>
)
} catch (error) {
return (
<center>
<h2>Render Error</h2>
</center>
)
}
}
render(){
return(
<div className={styles.search_wrapper}>
{this.renderResult(this.props.payload)}
</div>
)
}
}

View File

@ -1,58 +0,0 @@
@import '~themes/index.less';
.search_wrapper{
color: #201F23;
height: 100%;
width: 82%;
margin: auto;
:global{
.ant-result-title{
color: #fff;
}
.ant-result-subtitle{
color: #fff;
}
.ant-list-items{
height: 82vh;
overflow: scroll;
}
}
}
.search_card {
position: relative;
background-color: rgba(255, 255, 255, 0.034);
margin: 10px 0 10px 0;
border-radius: 8px;
padding: 10px;
word-break: break-all;
color: #fff;
cursor: pointer;
.search_title {
display: flex;
img {
float: left;
width: 30px;
height: 30px;
border-radius: 12px;
}
.search_user_username {
margin: 0 5px 0 8px;
vertical-align: middle;
height: 100%;
color: #fff;
line-height: 25px;
}
}
.search_text {
margin: 10px 0 0 0;
}
}

View File

@ -1,147 +0,0 @@
import React from 'react'
import styles from './__secComments.less'
import { SearchCard, Feather } from 'components'
import * as antd from 'antd'
import * as app from 'app'
import * as Icons from 'components/Icons'
import Icon from '@ant-design/icons'
const VerifiedBadge = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="#55acee"
width="15"
height="15"
viewBox="0 0 24 24"
>
<path d="M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12m-13 5l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"></path>
</svg>
)
export default class __secComments extends React.Component {
state = {
comment_data: this.props.payload,
raw_comment: '',
loading: false,
}
handleDeleteComment(id) {
app.yconsole.log(`Removing Comment with id => ${id}`)
app.comty_post_comment.delete(
(err, res) => {
if (err) {
return false
}
return this.reloadComments()
},
{ comment_id: id }
)
}
handleNewComment() {
const { raw_comment } = this.state
const { post_id } = this.props
if (raw_comment) {
const payload = { post_id: post_id, raw_text: raw_comment }
app.comty_post_comment.new((err, res) => {
if (err) {
app.notify.error('This action could not be performed.', err)
}
this.setState({ raw_comment: '' })
return this.reloadComments()
}, payload)
}
return false
}
renderComment = a => {
const { id, time, Orginaltext, publisher } = a
const CommentMenu = (
<antd.Menu>
<antd.Menu.Item
key="remove_comment"
onClick={() => this.handleDeleteComment(id)}
>
<Icons.DeleteOutlined /> Delete
</antd.Menu.Item>
</antd.Menu>
)
return (
<div className={styles.comment_card}>
<div className={styles.comment_title}>
<img src={publisher.avatar} />
<p className={styles.comment_user_username}>
@{publisher.username}{' '}
{app.booleanFix(publisher.verified) ? (
<Icon style={{ color: 'black' }} component={VerifiedBadge} />
) : null}
</p>
<antd.Dropdown
disabled={app.IsThisPost.owner(publisher.id) ? false : true}
overlay={CommentMenu}
trigger={['click']}
>
<p
onClick={e => e.preventDefault()}
className={styles.comment_user_ago}
>
{app.time.stmToAgo(time)}
</p>
</antd.Dropdown>
</div>
<div className={styles.comment_text}>
<p>{Orginaltext}</p>
</div>
</div>
)
}
HandleCommentInput = e => {
const { value } = e.target
this.setState({ raw_comment: value })
}
reloadComments() {
try {
this.setState({ loading: true })
const payload = { post_id: this.props.post_id }
app.comty_post.get((err, res) => {
const post_comments = JSON.parse(res)['post_comments']
this.setState({ comment_data: post_comments, loading: false })
}, payload)
} catch (error) {
return false
}
}
render() {
const { comment_data, loading } = this.state
return (
<div className={styles.comments_body}>
<div className={styles.comments_body_title}>
<h1>Comments ({comment_data.length})</h1>
</div>
<div className={styles.comments_cards_wrapper}>
{loading ? (
<antd.Skeleton active />
) : (
<antd.List
itemLayout="horizontal"
dataSource={comment_data}
renderItem={item => this.renderComment(item)}
/>
)}
</div>
<div className={styles.comment_box}>
<div className={styles.comment_box_body}>
<antd.Input
value={this.state.raw_comment}
onPressEnter={() => this.handleNewComment()}
placeholder="Write a comment..."
allowClear
onChange={this.HandleCommentInput}
/>
</div>
</div>
</div>
)
}
}

View File

@ -1,91 +0,0 @@
@import '~themes/index.less';
.comments_body {
height: 100%;
padding: 50px 10px 10px 20px;
font-family: @__Global_general_font_family;
.comments_body_title {
font-size: 12px;
h1 {
font-weight: 550;
letter-spacing: 0.01px;
}
}
.comments_cards_wrapper {
z-index: 50;
overflow-y: scroll!important;
height: 70vh; //84%;
.comment_card {
overflow-y: scroll!important;
position: relative;
width: 100%;
max-height: 100px;
word-break: break-all;
margin: 0 0 10px 0;
.comment_title {
display: flex;
img {
float: left;
width: 30px;
height: 30px;
border-radius: 12px;
}
.comment_user_username {
margin: 0 5px 0 8px;
vertical-align: middle;
height: 100%;
color: #2d2d2d;
line-height: 25px;
}
.comment_user_ago {
cursor: pointer;
position: absolute;
right: 0;
text-align: right;
font-size: 9px;
}
}
}
}
.comment_box {
width: 100%;
bottom: 0;
right: 0;
position: absolute;
z-index: 100;
padding-top: 20px;
padding-bottom: 60px;
border-radius: 0 0 0 32px;
.comment_box_body {
border-radius: 5px;
width: 85%;
height: 40px;
margin: auto;
background-color: #f8f6f8;
:global {
.ant-input-affix-wrapper,
.ant-input {
padding: 4px 5px;
background-color: transparent;
border: 0;
}
}
}
}
}

View File

@ -1,340 +0,0 @@
import React from 'react'
import * as app from 'app'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from './index.less'
import classnames from 'classnames'
import reactable from 'reactablejs'
import {
__sec,
__pri,
__trendings,
__searchBar,
__suggestions,
__priPost,
__secComments,
__priSearch,
} from './components'
export const SwapMode = {
loose_focus: () => {
OverlayLayoutComponent.loose_focus()
},
close: () => {
OverlayLayoutComponent.Swapper.close()
},
openFragment: (fragment)=>{
if (!fragment) return false
return OverlayLayoutComponent.setState({
rd__sec: fragment,
__sec_active: true,
})
},
openPost: async (id, content) => {
if (!id) return false
let tmp;
let promise = new Promise((res, rej) => {
const payload = { post_id: id }
app.comty_post.get((err, response) => {
try {
res(JSON.parse(response)['post_data'])
} catch (error) {
console.log(error)
}
}, payload)
});
if (!content){
tmp = await promise
}
if (content){
tmp = content
}
const pdata = <__priPost isMobile={OverlayLayoutComponent.props.isMobile} payload={tmp}/>
return OverlayLayoutComponent.setState({
rd__pri: pdata,
__pri_full: true
})
},
openComments: async (id, content) => {
if (!id) return false
let tmp;
let promise = new Promise((res, rej) => {
const payload = { post_id: id }
app.comty_post.get((err, response) => {
try {
res(JSON.parse(response)['post_comments'])
}catch (error) {
console.log(error)
}
}, payload)
});
if (!content){
tmp = await promise
}
if (content){
tmp = content
}
const pdata = <__secComments post_id={id} payload={tmp} />
return OverlayLayoutComponent.setState({
rd__sec: pdata,
__sec_active: true,
})
},
openSearch: async (id, content) => {
if (!id) return false
let tmp;
let promise = new Promise((res, rej) => {
const payload = { key: id }
app.comty_search.keywords((err, response) => {
res(response)
}, payload)
});
if (!content){
tmp = await promise;
}
if (content){
tmp = content;
}
const pdata = <div className={styles.renderSearch_wrapper}>
<h2>
<Icons.SearchOutlined /> Results of {id || '... nothing ?'}
</h2>
<__priSearch payload={tmp} />
</div>
return OverlayLayoutComponent.setState({
rd__pri: pdata,
__pri_half: true,
})
},
}
export default class Overlay extends React.PureComponent {
constructor(props) {
super(props),
(window.OverlayLayoutComponent = this),
(this.state = {
loading: true,
gen_data: null,
// Lays
rd__pri: null,
rd__sec: null,
__pri_full: false,
__pri_half: false,
__sec_active: false,
__sec_full: false,
})
this.setWrapperRef = this.setWrapperRef.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
}
Swapper = {
close: () => {
this.setState({
rd__pri: null,
rd__sec: null,
__pri_full: false,
__pri_half: false,
__sec_active: false,
__sec_full: false,
})
},
}
handle_Exit(event) {
if (event.keyCode === 27) {
SwapMode.close()
}
}
loose_focus(){
if (this.isOpen()) {
SwapMode.close()
}
}
handle_genData() {
app.comty_data.general_data((err, res) => {
if (err) return false
try {
const notification_data = JSON.parse(res)['notifications']
const trending_hashtag = JSON.parse(res)['trending_hashtag']
this.setState({
loading: false,
gen_data: res,
notification_data: notification_data,
trending_hashtag: trending_hashtag,
})
} catch (error) {
console.log(error)
return null
}
})
}
isOpen() {
if (
this.state.__pri_full ||
this.state.__pri_half ||
this.state.__sec_active ||
this.state.__sec_full
)
return true
return false
}
componentDidMount() {
this.handle_genData()
if(this.props.isMobile){
window.addEventListener('popstate', function(event) {
SwapMode.close()
}, false);
}
}
componentWillUnmount() {
if(this.props.isMobile){
document.removeEventListener('popstate', null)
}
document.removeEventListener('keydown', this.handle_Exit, false)
}
componentDidUpdate() {
if (this.isOpen()) {
document.addEventListener('keydown', this.handle_Exit, false)
document.addEventListener('mousedown', this.handleClickOutside);
} else {
document.removeEventListener('mousedown', this.handleClickOutside);
}
}
/**
* Set the wrapper ref
*/
setWrapperRef(node) {
this.wrapperRef = node;
}
/**
* Alert if clicked on outside of element
*/
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
SwapMode.close()
}
}
renderTarget(target) {
try {
switch (target) {
case '__pri': {
const fragment = this.state.rd__pri
if (!fragment && !this.props.isMobile) {
return <React.Fragment>{this.__main()}</React.Fragment>
}
return <React.Fragment>{fragment}</React.Fragment>
}
case '__sec': {
const fragment = this.state.rd__sec
return <>
{this.props.isMobile? <div className={styles.mobile_drag}><div className={styles.inner_drag}></div></div> : null}
<React.Fragment>{fragment}</React.Fragment>
</>
}
default:
return <h3>Invalid Render Target</h3>
}
} catch (error) {
console.log(error)
return null
}
}
renderExit(target){
if (!target) return null
const { rd__pri, rd__sec } = this.state
const btn = <div className={styles.exit_button}><antd.Button type="ghost" icon={<Icons.LeftOutlined />} onClick={() => this.Swapper.close()}> Back </antd.Button></div>
if (this.isOpen()) {
switch (target) {
case '__pri':{
if (rd__pri&&rd__sec) {
return btn
}
if (!rd__sec) {
return btn
}
return null
}
case '__sec':{
if (!rd__pri && this.props.isMobile) {
return null
}
if (!rd__pri) {
return btn
}
return null
}
default:
return null
}
}
return null
}
__main(){
const fragment = this.state.rd__pr
if (!fragment && !this.props.isMobile) {
return (
<React.Fragment>
<div className={styles.Overlay_body_component}> <__searchBar /> </div>
<div className={styles.Overlay_body_component}> <__trendings data={this.state.trending_hashtag} /> </div>
<div className={styles.Overlay_body_component}> <__suggestions /> </div>
</React.Fragment>
)
}
}
render() {
const { userData, isMobile } = this.props
const __sec_functs = (this.Swapper)
if (!this.state.loading)
return (
<>
<div
id="Overlay_layout"
ref={this.setWrapperRef}
className={classnames(styles.Overlay_wrapper, {
[styles.mobile]: isMobile,
[styles.active]: this.isOpen(),
[styles.expand]: this.state.__pri_half
})}
>
<__pri render={this.renderTarget('__pri')} isMobile={isMobile} functs={__sec_functs} type={this.state.__pri_full? "full_open" : this.state.__pri_half? "half" : null} />
<__sec render={this.renderTarget('__sec')} isMobile={isMobile} functs={__sec_functs} type={this.state.__sec_full? "full_open" : this.state.__sec_active? "active" : null} />
</div>
</>
)
return null
}
}

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.render_component {
width: 100%;
@ -20,19 +20,6 @@
}
}
.mobile_drag{
width: 100%;
height: auto;
.inner_drag{
height: 6px;
margin: auto;
width: 20%;
background-color: #2d2d2d;
border-radius: 12px;
}
}
.exit_button{
position: relative;
z-index: 52;
@ -75,11 +62,10 @@
max-width: calc(100% + 150px);
}
transition: all @__Global_SwapAnimDuration ease-in-out;
}
.Overlay_container_1 {
.overlay_primary_wrapper {
height: 100%;
width: 100%;
@ -99,13 +85,21 @@
color: @Overlay_container1_def_color;
.renderBody{
height: 100%;
width: 100%;
> div {
margin-bottom: 35px;
}
}
&.half {
background-color: #2d2d2d;
color: @Overlay_container1_active_color;
max-width: calc(100% + 150px);
}
&.full_open {
&.full{
max-width: none;
background-color: transparent;
position: absolute;
@ -113,44 +107,6 @@
height: 100vh;
}
&.mobile {
min-width: unset;
max-width: unset;
width: 100%;
height: 0;
bottom: 0;
opacity: 0;
top: unset;
overflow: hidden;
border-radius: 12px 12px 0 0;
flex-direction: column;
:global{
.comments_body {
padding: 30px 10px 10px 10px;
}
}
&.full_open {
opacity: 1;
height: 100vh;
.pri_body{
width: 100%;
}
}
&.half {
opacity: 1;
height: 95vh;
}
transition: all @__Global_Components_transitions_dur linear;
}
:global {
.ant-btn {
color: @Overlay_container_1_btn_color;
@ -165,17 +121,12 @@
}
}
.pri_body{
height: 100%;
width: 100%;
}
transition: all @__Global_SwapAnimDuration ease-in-out;
border-radius: @__Global_layout_border-rd;
}
.Overlay_container_2 {
.overlay_secondary_wrapper {
position: absolute;
z-index: 55;
height: 100vh;
@ -193,53 +144,6 @@
&.active {
width: @Overlay_container2_active_width;
opacity: 1;
}
&.mobile {
width: 100%;
height: 0;
bottom: 0;
opacity: 0;
top: unset;
transform: translate(0, 86%);
border-radius: 12px 12px 0 0;
flex-direction: column;
overflow-y: overlay;
overflow-x: hidden;
touch-action: none;
user-select: none;
cursor: default;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
-webkit-touch-action: none;
-moz-touch-action: none;
-ms-touch-action: none;
touch-action: none;
:global{
.comments_body {
padding: 30px 10px 10px 10px;
}
}
&.active {
opacity: 1;
height: 100%;
}
&.full_open {
opacity: 1;
height: 100vh;
}
}
@ -247,10 +151,6 @@
}
.Overlay_body_component{
// Spacing between components
margin-bottom: 35px;
}
.renderSearch_wrapper {
height: 87vh;

View File

@ -0,0 +1,138 @@
import React from 'react'
import verbosity from 'core/libs/verbosity'
import { connect } from 'umi'
import classnames from 'classnames'
import styles from './index.less'
import * as errorhandler from 'core/libs/errorhandler'
import {
Primary,
Secondary,
Card_Component,
__searchBar
} from './components'
export let Swapper = {
isOpen: (...props) => {
window.OverlayComponent.swap.isOpen(...props)
},
closeAll: (...props) => {
window.OverlayComponent.swap.closeAll(...props)
},
openFragment: (...props) => {
window.OverlayComponent.swap.openFragment(...props)
}
}
@connect(({ app }) => ({ app }))
export default class Overlay extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
loading: true,
};
this.setWrapperRef = this.setWrapperRef.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this.keydownFilter = this.keydownFilter.bind(this);
window.OverlayComponent = this;
}
swap = {
isOpen: () => {
return this.props.app.overlayActive
},
closeAll: () => {
this.props.dispatch({
type: 'app/updateState',
payload: {
overlayActive: false,
overlayElement: null
},
});
},
openFragment: (payload) => {
if (!payload) return false;
verbosity.debug('Dispatching fragment =>', payload)
this.props.dispatch({
type: 'app/updateState',
payload: {
overlayActive: true,
overlayElement: payload
},
});
}
}
keydownFilter(event) {
if (event.keyCode === 27) {
this.swap.closeAll()
}
}
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
this.swap.closeAll()
}
}
componentDidUpdate() {
if (this.props.app.overlayElement) {
document.addEventListener('keydown', this.keydownFilter, false)
document.addEventListener('mousedown', this.handleClickOutside);
} else {
document.removeEventListener('mousedown', this.handleClickOutside);
}
}
/**
* Set the wrapper ref
*/
setWrapperRef(node) {
this.wrapperRef = node;
}
render() {
const { overlayElement, overlayActive } = this.props.app
const renderElement = () => {
if (overlayElement && overlayActive) {
const renderProps = {id: overlayElement.id, mode: overlayElement.mode, fragment: overlayElement.element}
switch (overlayElement.position) {
case 'primary':{
return <Primary {...renderProps} />
}
case 'secondary':{
return <Secondary {...renderProps} />
}
default:{
verbosity.error(errorhandler.OVERLAY_BADPOSITION)
return null
}
}
}
return(
<Primary id="main" fragment={<> <div><__searchBar /></div> <div><Card_Component> yeah </Card_Component></div> </>} />
)
}
return (
<>
<div
id="Overlay_layout"
ref={this.setWrapperRef}
className={classnames(styles.Overlay_wrapper)}
>
{renderElement()}
</div>
</>
)
}
}

View File

@ -1,72 +1,32 @@
import React from 'react'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from './index.less'
import Icon from '@ant-design/icons'
import { withI18n, Trans } from '@lingui/react'
import styles from './default.less'
import * as app from 'app'
import classnames from 'classnames'
@withI18n()
export default class Sider_Default extends React.PureComponent {
state = {
loading: true,
menus: null
}
require(e){
switch (e) {
case 'login':
return true
case 'admin':
return true
default:
return true
}
}
componentDidMount(){
try {
let tmp = [];
const { menus } = this.props
menus.forEach(e => {
if (this.require(e.require)) {
tmp.push(e)
}
});
this.setState({ menus: tmp, loading: false })
} catch (error) {
console.log(error)
}
this.setState({ menus: this.props.menus, loading: false })
}
renderMenus(data){
try {
return data.map(e => {
return(
<antd.Menu.Item key={e.id}>
{e.icon}
<Trans>
<span>{e.title}</span>
</Trans>
</antd.Menu.Item>
)
})
} catch (error) {
console.log(error)
return null
}
return data.map(e => {
return(
<antd.Menu.Item key={e.id}>
{e.icon}
<span>{e.title}</span>
</antd.Menu.Item>
)
})
}
render() {
const { handleClickMenu, logo, theme } = this.props
const predominantColor = theme.predominantColor || "#333"
if (this.state.loading) return <div>Loading</div>
return (
const { handleClickMenu, logo } = this.props
return this.state.loading? null : (
<div className={styles.left_sider_wrapper}>
<antd.Layout.Sider
trigger={null}
@ -75,13 +35,12 @@ export default class Sider_Default extends React.PureComponent {
>
<div className={styles.left_sider_brandholder}>
<img
onClick={() => app.router.go('main')}
onClick={() => handleClickMenu({key: '/'})}
src={logo}
/>
</div>
<div className={styles.left_sider_menuContainer}>
<antd.Menu
// style={{color: predominantColor}}
//className={classnames(styles.left_sider_menuItems, {[styles.matchColor]: theme.predominantColor? true : false})}
@ -91,7 +50,6 @@ export default class Sider_Default extends React.PureComponent {
onClick={handleClickMenu}
>
{this.renderMenus(this.state.menus)}
</antd.Menu>
<div className={styles.something_thats_pulling_me_down}>
@ -100,33 +58,18 @@ export default class Sider_Default extends React.PureComponent {
className={styles.left_sider_menuItems}
mode="vertical"
onClick={handleClickMenu}
>
<antd.Menu.Item key="general_settings">
<antd.Menu.Item key="settings">
<Icons.SettingOutlined />
<Trans>
<span>Settings</span>
</Trans>
</antd.Menu.Item>
{app.IsThisUser.dev() ? (
<antd.Menu.Item key="debug_area">
<Icons.ThunderboltOutlined />
<span>Debug</span>
</antd.Menu.Item>
) : (
undefined
)}
<antd.Menu.Item key="SignOut">
<antd.Menu.Item key="logout">
<Icons.LogoutOutlined style={{ color: 'red' }} />
<Trans>
<span>Logout</span>
</Trans>
</antd.Menu.Item>
</antd.Menu>
</div>
</div>
</antd.Layout.Sider>
</div>

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.left_sider_wrapper {
@ -33,8 +33,6 @@
}
.ant-menu-item {
transition: @transition-ease-inout;
border-radius: 4px 8px 8px 4px;
@ -78,10 +76,10 @@
cursor: pointer;
img{
margin: 7px 0 0 20px;
margin: 15px 0 0 0;
max-height: 70px;
height: 7vh;
filter: drop-shadow(1px 0px 1px #b9b9b9);
height: 5vh;
width: 5vh;
}
}

View File

@ -1,33 +1,22 @@
import React from 'react'
import config from 'config'
import * as app from 'app'
import { app_config } from 'config'
import { router } from 'core/cores'
import MenuList from 'globals/sidebar_menu'
import Sider_Mobile from './mobile.js'
import Sider_Default from './default.js'
import Sider_Mobile from './mobile'
import Sider_Default from './default'
class Sider extends React.PureComponent {
handleClickMenu = e => {
e.key === 'messages' && app.router.go('messages')
e.key === 'SignOut' && app.app_session.logout()
e.key === 'general_settings' && app.router.go('settings')
e.key === 'profile' && app.router.goprofile()
e.key === 'saves' && app.router.go('saves')
e.key === 'main' && app.router.go('main')
e.key === 'explore' && app.router.go('explore')
e.key === 'notifications' && app.router.go('notifications')
e.key === 'debug_area' && app.router.go('debug')
router.go(e.key)
}
render() {
const { isMobile, theme } = this.props
const sider_props = {theme: theme, menus: MenuList, handleClickMenu: this.handleClickMenu ,logo: config.LogoPath, menulist: null, userData: this.props.userData}
const { isMobile } = this.props
const sider_props = { menus: MenuList, handleClickMenu: this.handleClickMenu, logo: app_config.LogoPath }
if (isMobile) {
return <Sider_Mobile {...sider_props} />
}
return <Sider_Default {...sider_props} />
return isMobile? <Sider_Mobile {...sider_props} /> : <Sider_Default {...sider_props} />
}
}

View File

@ -1,51 +0,0 @@
import React from 'react'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import Icon from '@ant-design/icons'
import { withI18n, Trans } from '@lingui/react'
import styles from './mobile.less'
import * as app from 'app'
@withI18n()
export default class Sider_Mobile extends React.PureComponent {
render() {
const { handleClickMenu, userData } = 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">
<Icons.HeartTwoTone twoToneColor={"#ff4d4f"} />
</antd.Menu.Item>
<antd.Menu.Item key="general_settings">
<Icons.SettingOutlined />
</antd.Menu.Item>
<antd.Menu.Item key="profile">
<antd.Avatar size={20} shape="square" src={userData.avatar} />
</antd.Menu.Item>
</antd.Menu>
</antd.Layout.Sider>
</div>
)
}
}

View File

@ -0,0 +1,35 @@
import React from 'react'
import * as antd from 'antd'
import * as Icons from 'components/Icons'
import styles from './index.less'
export default class Sider_Mobile extends React.PureComponent {
renderMenus(data){
// filter by item with mobile support
return data.map(e => {
return(
<antd.Menu.Item key={e.id} style={{ color: '#ffffff', fontSize: '18px' }} >{e.icon}</antd.Menu.Item>
)
})
}
render() {
const { handleClickMenu, menus } = this.props
return (
<div className={styles.left_sider_wrapper}>
<antd.Layout.Sider
trigger={null}
width='100%'
>
<antd.Menu
mode="horizontal"
onClick={handleClickMenu}
>
{this.renderMenus(menus)}
</antd.Menu>
</antd.Layout.Sider>
</div>
)
}
}

View File

@ -1,5 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.left_sider_wrapper {
overflow: hidden!important;
@ -43,8 +42,4 @@
}
}
}
}

View File

@ -1,4 +1,5 @@
import Sider from './Sider'
import Control from './ControlBar'
import Overlay from './Overlay'
import Overlay from './Overlay/index.tsx'
export { Sider, Control, Overlay }

View File

@ -1,106 +0,0 @@
import React from 'react'
import styles from './index.scss'
import * as app from 'app'
import classnames from 'classnames'
class Like_button extends React.PureComponent {
constructor(props) {
super(props),
this.state = {
liked: this.props.liked,
likes: this.props.count,
type: this.props.liked ? 'dislike' : 'like',
clicked: false,
}
}
SumLike() {
this.setState({
likes: parseInt(this.state.likes) + 1,
type: 'dislike',
})
setTimeout(() => {
this.setState({ liked: true })
}, 500)
}
RestLike() {
this.setState({
likes: parseInt(this.state.likes) - 1,
type: 'like',
})
setTimeout(() => {
this.setState({ liked: false })
}, 500)
}
dispatchLike(e) {
const { type } = this.state
app.yconsole.log(`Dispatch ${type} to post id => ${e}`)
this.setState({ clicked: true })
setTimeout(() => {
this.setState({ clicked: false })
}, 500)
const payload = { post_id: e }
app.comty_post.like((err, res) => {
if (err) {
app.notify.error(res)
return
}
if (type == 'like') {
this.SumLike()
}
if (type == 'dislike') {
this.RestLike()
}
}, payload)
}
render() {
const { id } = this.props
const { likes, liked, clicked } = this.state
if (!id) {
app.yconsole.error('[LikeBTN] No post id provided!')
return null
}
return (
<div className={styles.btnWrapper}>
<button
onClick={() => this.dispatchLike(id)}
className={classnames(styles.like_button, {
[styles.clickanim]: clicked,
})}
>
<div className={styles.like_wrapper}>
<div
className={classnames(
styles.ripple,
liked ? null : { [styles.clickanim]: clicked }
)}
></div>
<svg
className={classnames(
styles.heart,
{ [styles.empty]: !liked },
liked ? null : { [styles.clickanim]: clicked }
)}
width="24"
height="24"
viewBox="0 0 24 24"
>
<path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"></path>
</svg>
</div>
</button>
<p
className={classnames(styles.likeCounter, {
[styles.active]: !clicked,
[styles.past]: clicked,
})}
>
{likes}
</p>
</div>
)
}
}
export default Like_button

View File

@ -1,205 +0,0 @@
.like_button,
.like_button:before,
.like_button:after {
position: relative;
box-sizing: border-box;
}
.ripple,
.ripple:before,
.ripple:after {
position: relative;
box-sizing: border-box;
}
.btnWrapper {
display: flex;
}
.likeCounter {
font-family: "Poppins", sans-serif;
line-height: 70px;
margin: 0 0 0 10px;
opacity: 0;
transform: perspective(100px) translateZ(10px);
filter: blur(10px);
letter-spacing: 0.1em;
&.active {
opacity: 1;
transform: perspective(100px) translateZ(0px);
filter: blur(0px);
letter-spacing: 0.15em;
transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear;
}
&.past {
opacity: 0;
transform: perspective(100px) translateZ(-10px);
filter: blur(10px);
letter-spacing: 0.2em;
transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear;
}
}
.like_button {
--color-heart: #EA442B;
--easing: cubic-bezier(.7, 0, .3, 1);
--duration: .5s;
font-size: 40px;
border: none;
border-radius: 50%;
background: white;
width: 1em;
height: 1em;
padding: 0;
margin: 0;
outline: none;
z-index: 2;
transition: transform var(--duration) var(--easing);
cursor: pointer;
&:before {
z-index: -1;
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
transition: inherit;
}
&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
border-radius: inherit;
z-index: -1;
}
@keyframes depress {
from,
to {
transform: none;
}
50% {
transform: translateY(5%) scale(0.9);
}
}
@keyframes depress-shadow {
from,
to {
transform: none;
}
50% {
transform: scale(0.5);
}
}
}
.like_wrapper {
display: grid;
align-items: center;
justify-content: center;
z-index: 1;
>* {
margin: auto;
grid-area: 1 / 1;
}
}
.heart {
width: .5em;
height: .5em;
display: block;
transform-origin: center 80%;
>path {
stroke: var(--color-heart);
stroke-width: 2;
transition: fill var(--duration) var(--easing);
fill: var(--color-heart);
}
&.empty {
>path {
stroke: var(--color-heart);
stroke-width: 2;
transition: fill var(--duration) var(--easing);
fill: transparent;
}
}
&.clickanim {
animation: heart-bounce var(--duration) var(--easing);
@keyframes heart-bounce {
40% {
transform: scale(0.7);
}
0%,
80%,
100% {
transform: scale(1);
}
}
}
animation: none;
}
.ripple {
height: 1em;
width: 1em;
border-radius: 50%;
overflow: hidden;
z-index: 1;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: .4em solid var(--color-heart);
border-radius: inherit;
transform: scale(0);
}
&.clickanim {
&:before {
animation: ripple-out var(--duration) var(--easing);
@keyframes ripple-out {
from {
transform: scale(0);
}
to {
transform: scale(5);
}
}
}
}
}

View File

@ -1,4 +1,4 @@
@import '~themes/index.less';
@import '~theme/index.less';
.wrapper {
font-family: @__Global_general_font_family;

View File

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

View File

@ -1,24 +0,0 @@
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

View File

@ -1,11 +0,0 @@
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

View File

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

View File

@ -1,43 +0,0 @@
import React from 'react'
import { PostCard } from 'components'
import { yconsole } from 'app'
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

View File

@ -1,188 +0,0 @@
import React from 'react'
import * as antd from 'antd'
import * as app from 'app'
import styles from './index.less'
import { ComponentNewAV, ComponentInvalid, renderFeedPosts } from './components/index.js'
export const RenderFeed = {
RefreshFeed: () => {
window.MainFeedComponent.feedGet.first()
return
},
killByID: post_id => {
window.MainFeedComponent.killByID(post_id)
return
},
addToRend: payload => {
window.MainFeedComponent.addToRend(payload)
return
},
goToElement: post_id => {
app.goTo.element(post_id)
},
disableMenu: () => {
window.MainFeedComponent.setState({
disableMenu: true,
})
},
sync: (c) => {
window.MainFeedComponent.syncService(c)
return
}
}
class MainFeed extends React.PureComponent {
constructor(props) {
super(props)
window.MainFeedComponent = this
this.state = {
AutoFeed: this.props.auto? true:false,
NewAV: false,
invalid: false,
loading: false,
disableMenu: false,
data: [],
fkey: 0,
}
}
componentDidMount() {
this.feedGet.first()
app.sync.FeedListen((data) => {
this.syncService(data)
})
}
toogleLoader() {
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) {
const a = this.state.data
const b = app.arrayRemoveByID(a, post_id)
this.setState({ data: b })
}
addToRend(payload) {
let a = this.state.data
a.unshift(payload)
this.setState({ data: a })
}
feedGet = {
first: ()=>{
try {
const { get, uid, filters } = this.props
if (this.props.custompayload) {
this.setState({
isEnd: true,
NewAV: false,
data: this.props.custompayload,
loading: false,
})
return
}
if (!get) {
app.yconsole.error('Please, fill params with an catch type...')
return
}
this.toogleLoader()
const payload = { fkey: 0, type: get, id: uid }
app.comty_post.getFeed((err, res) => {
if (err) {
app.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 < app.AppSettings.limit_post_catch ? true : false
this.setState({ NewAV: false, isEnd: isEnd, data: parsed, loading: false })
} catch (error) {
app.yconsole.log(error)
}
}, payload)
} catch (err) {
app.notify.error('err')
}
},
more(fkey){
try {
const { get, uid, filters } = this.props
console.log(get)
if (!get) {
app.yconsole.error('Please, fill params with an catch type...')
return
}
if (!fkey) {
app.yconsole.warn(
'Please, provide a fkey for offset the feed, default using => 0'
)
}
this.toogleLoader()
const getLastPost = app.objectLast(this.state.data)
app.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
app.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 < app.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () =>
app.goTo.element(getLastPost.id)
)
return true
}, payload)
} catch (err) {
app.notify.error('[ MainFeed ]', err)
}
}
}
render() {
const { data, loading, isEnd, invalid, NewAV, AutoFeed } = this.state
const renderFeedPosts_payload = {data: data, loading: loading, isEnd: isEnd, feedGet: this.feedGet}
if (invalid){
return ComponentInvalid()
}
if (loading) {
return (
<antd.Card style={{ maxWidth: '26.5vw', margin: 'auto' }}>
<antd.Skeleton avatar paragraph={{ rows: 4 }} active />
</antd.Card>
)
}
if (!loading) {
return (
<div className={styles.main_feed_wrapper} id="mainfeed">
{AutoFeed? NewAV? ComponentNewAV(() => this.feedGet.first()) : null : null}
{renderFeedPosts(renderFeedPosts_payload)}
</div>
)
}
}
}
export default MainFeed

Some files were not shown because too many files have changed in this diff Show More