0.2.24A3 - Major yCore optimization

This commit is contained in:
srgooglo 2020-03-24 23:38:15 +01:00
parent cc00d36f14
commit 5e87c6c933
119 changed files with 7097 additions and 5957 deletions

View File

@ -1,8 +1,7 @@
// https://umijs.org/config/ // https://umijs.org/config/
import { resolve } from 'path'; import { resolve } from 'path'
import { i18n } from './config/ycore.config.js'; import { i18n } from './config/ycore.config.js'
export default { export default {
ignoreMomentLocale: true, ignoreMomentLocale: true,
targets: { targets: {
ie: 9, ie: 9,
@ -21,7 +20,7 @@ export default {
webpackChunkName: true, webpackChunkName: true,
loadingComponent: './components/Loader/Loader', loadingComponent: './components/Loader/Loader',
}, },
routes: { routes: {
exclude: [ exclude: [
/model\.(j|t)sx?$/, /model\.(j|t)sx?$/,
@ -31,23 +30,26 @@ export default {
/services\//, /services\//,
], ],
update: routes => { update: routes => {
if (!i18n) return routes; if (!i18n) return routes
const newRoutes = []; const newRoutes = []
for (const item of routes[0].routes) { for (const item of routes[0].routes) {
newRoutes.push(item); newRoutes.push(item)
if (item.path) { if (item.path) {
newRoutes.push( newRoutes.push(
Object.assign({}, item, { Object.assign({}, item, {
path: `/:lang(${i18n.languages.map(item => item.key).join('|')})` + item.path, path:
`/:lang(${i18n.languages
.map(item => item.key)
.join('|')})` + item.path,
}) })
); )
} }
} }
routes[0].routes = newRoutes; routes[0].routes = newRoutes
return routes; return routes
}, },
}, },
dll: false, dll: false,
@ -88,5 +90,4 @@ export default {
'lodash', 'lodash',
], ],
], ],
}; }

View File

@ -1,38 +1,53 @@
function SettingStoragedValue(e){ function SettingStoragedValue(e) {
try { try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings')) const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => { const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null return item.SettingID === e ? item.value : null
}) })
const fr = Ite.filter(Boolean) const fr = Ite.filter(Boolean)
return fr.toString() return fr.toString()
} } catch (error) {
catch (error) { return null
return null }
}
} }
const fromStorage = JSON.parse(localStorage.getItem('app_settings')) const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
export var AppSettings = { export var AppSettings = {
// Global Behaviors // Global Behaviors
InfiniteLoading: false, InfiniteLoading: false,
InfiniteLogin: false, InfiniteLogin: false,
InfiniteRegister: false, InfiniteRegister: false,
DisableLogin: false, DisableLogin: false,
DisableRegister: true, DisableRegister: true,
DisablePasswordRecover: true, DisablePasswordRecover: true,
// Activating this, the logs must be trowed // Activating this, the logs must be trowed
force_showDevLogs: fromStorage? SettingStoragedValue('force_showDevLogs') : false, force_showDevLogs: fromStorage
StrictLightMode: fromStorage? SettingStoragedValue('strict_lightMode') : false, ? SettingStoragedValue('force_showDevLogs')
SignForNotExpire: fromStorage? SettingStoragedValue('sessions_noexpire') : false, : false,
auto_search_ontype: fromStorage? SettingStoragedValue('auto_search_ontype') : false, StrictLightMode: fromStorage
auto_feedrefresh: fromStorage? SettingStoragedValue('auto_feedrefresh') : false, ? SettingStoragedValue('strict_lightMode')
default_showpostcreator: fromStorage? SettingStoragedValue('default_showpostcreator') : false, : false,
default_collapse_sider: fromStorage? SettingStoragedValue('default_collapse_sider') : true, SignForNotExpire: fromStorage
force_show_postactions: fromStorage? SettingStoragedValue('force_show_postactions') : false, ? SettingStoragedValue('sessions_noexpire')
MaxLengthPosts: '512', : false,
CurrentBundle: 'light_ng', auto_search_ontype: fromStorage
// In KB ? SettingStoragedValue('auto_search_ontype')
MaximunAPIPayload: '101376', : false,
limit_post_catch: '20' auto_feedrefresh: fromStorage
} ? SettingStoragedValue('auto_feedrefresh')
: false,
default_showpostcreator: fromStorage
? SettingStoragedValue('default_showpostcreator')
: false,
default_collapse_sider: fromStorage
? SettingStoragedValue('default_collapse_sider')
: true,
force_show_postactions: fromStorage
? SettingStoragedValue('force_show_postactions')
: false,
MaxLengthPosts: '512',
CurrentBundle: 'light_ng',
// In KB
MaximunAPIPayload: '101376',
limit_post_catch: '20',
}

View File

@ -1,3 +1,3 @@
module.exports = { module.exports = {
secretOrKey: "secret" secretOrKey: 'secret',
}; }

View File

@ -1,42 +1,38 @@
module.exports = { module.exports = {
server_endpoint: 'https://comty.julioworld.club', server_endpoint: 'https://comty.julioworld.club',
siteName: 'Comty', siteName: 'Comty',
copyright: 'RageStudio©', copyright: 'RageStudio©',
LogoPath: '/logo.svg', LogoPath: '/logo.svg',
FullLogoPath: '/full_logo.svg', FullLogoPath: '/full_logo.svg',
DarkFullLogoPath: '/dark_full_logo.svg', DarkFullLogoPath: '/dark_full_logo.svg',
DarkLogoPath: '/dark_logo.svg', DarkLogoPath: '/dark_logo.svg',
resource_bundle: 'light_ng', resource_bundle: 'light_ng',
/* Layout configuration, specify which layout to use for route. */
/* Layout configuration, specify which layout to use for route. */ layouts: [
layouts: [ {
name: 'primary',
include: [/.*/],
exclude: [/\/login/, /\/socket\/(.*)/, /\/publics/, /\/authorize/],
},
],
yConfig: {
// Disused Variables, exported from yCoreWorker
// Global Server Key (Requiered for RS-YIBTP), Not autogenerated, must be included on. (Recommended not modify this constants)
server_key:
'f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768',
},
i18n: {
languages: [
{ {
name: 'primary', key: 'en',
include: [/.*/], title: 'English',
exclude: [/\/login/, /\/socket\/(.*)/, /\/publics/, /\/authorize/],
}, },
], ],
yConfig: { defaultLanguage: 'en',
// Disused Variables, exported from yCoreWorker },
// Global Server Key (Requiered for RS-YIBTP), Not autogenerated, must be included on. (Recommended not modify this constants) }
server_key: "f706b0a535b6c2d36545c4137a0a3a26853ea8b5-1223c9ba7923152cae28e5a2e7501b2b-50600768",
},
App_Config: {
InitRes: '800x600',
},
i18n: {
languages: [
{
key: 'en',
title: 'English',
},
],
defaultLanguage: 'en',
},
}

View File

@ -1,8 +1,8 @@
export var BadgesType = [ export var BadgesType = [
{ {
"id": "alpha_test", id: 'alpha_test',
"title": "Alpha Tester", title: 'Alpha Tester',
"color": "volcano", color: 'volcano',
"tip": "Oh yeah!" tip: 'Oh yeah!',
}, },
] ]

View File

@ -1,31 +1,22 @@
import * as Icons from '@ant-design/icons' import * as Icons from '@ant-design/icons'
export var Post_Options = [ export var Post_Options = [
{ {
"option": "pro_boost", key: 'pro_boost',
"icon": <Icons.RocketOutlined />, icon: <Icons.RocketOutlined />,
"type" : "switch", type: 'switch',
"title": "CPRO™ Boost", title: 'CPRO™ Boost',
"description": "", description: '',
"require": "pro", require: 'pro',
"value": false value: false,
}, },
{ {
"option": "allow_likes", key: 'allow_comments',
"icon": <Icons.HeartOutlined />, icon: <Icons.CommentOutlined />,
"type" : "switch", type: 'switch',
"title": "Allow Likes", title: 'Allow Comments',
"description": "", description: '',
"require": "", require: '',
"value": true value: true,
}, },
{
"option": "allow_comments",
"icon": <Icons.CommentOutlined />,
"type" : "switch",
"title": "Allow Comments",
"description": "",
"require": "",
"value": true
},
] ]

View File

@ -1,74 +1,81 @@
const fromStorage = JSON.parse(localStorage.getItem('app_settings')) const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
function SettingStoragedValue(e){ function SettingStoragedValue(e) {
try { try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings')) const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => { const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null return item.SettingID === e ? item.value : null
}) })
const fr = Ite.filter(Boolean) const fr = Ite.filter(Boolean)
return fr.toString() return fr.toString()
} } catch (error) {
catch (error) {
return null return null
} }
} }
export var ListSettings = [ export var ListSettings = [
{ {
"SettingID": "strict_lightMode", SettingID: 'strict_lightMode',
"type" : "switch", type: 'switch',
"title": "Strict Light Mode", title: 'Strict Light Mode',
"description": "Force the app to apply full light mode theme when the light mode is activated... (Experimental)", description:
"value": fromStorage? SettingStoragedValue('strict_lightMode') : false 'Force the app to apply full light mode theme when the light mode is activated... (Experimental)',
}, value: fromStorage ? SettingStoragedValue('strict_lightMode') : false,
{ },
"SettingID": "default_collapse_sider", {
"type" : "switch", SettingID: 'default_collapse_sider',
"title": "Default Collapse Sider", type: 'switch',
"description": "Force the app to apply collapsed mode theme when the app is mounted...", title: 'Default Collapse Sider',
"value": fromStorage? SettingStoragedValue('default_collapse_sider') : true description:
}, 'Force the app to apply collapsed mode theme when the app is mounted...',
{ value: fromStorage ? SettingStoragedValue('default_collapse_sider') : true,
"SettingID": "auto_feedrefresh", },
"type" : "switch", {
"title": "Auto Feed Refresh", SettingID: 'auto_feedrefresh',
"description": "Force the app to auto refresh the posts feed when exist news posts for update", type: 'switch',
"value": fromStorage? SettingStoragedValue('auto_feedrefresh') : false title: 'Auto Feed Refresh',
}, description:
{ 'Force the app to auto refresh the posts feed when exist news posts for update',
"SettingID": "force_showDevLogs", value: fromStorage ? SettingStoragedValue('auto_feedrefresh') : false,
"type" : "switch", },
"title": "Show Functions Logs", {
"description": "Show all console logs... [Developer]", SettingID: 'force_showDevLogs',
"value": fromStorage? SettingStoragedValue('force_showDevLogs') : false type: 'switch',
}, title: 'Show Functions Logs',
{ description: 'Show all console logs... [Developer]',
"SettingID": "sessions_noexpire", value: fromStorage ? SettingStoragedValue('force_showDevLogs') : false,
"type" : "switch", },
"title": "No expire session", {
"description": "Force the app to not expire any session... [Developer]", SettingID: 'sessions_noexpire',
"value": fromStorage? SettingStoragedValue('sessions_noexpire') : false type: 'switch',
}, title: 'No expire session',
{ description: 'Force the app to not expire any session... [Developer]',
"SettingID": "auto_search_ontype", value: fromStorage ? SettingStoragedValue('sessions_noexpire') : false,
"type" : "switch", },
"title": "Auto search", {
"description": "Force the app to automaticly search when a type input is detected... [Developer]", SettingID: 'auto_search_ontype',
"value": fromStorage? SettingStoragedValue('auto_search_ontype') : false type: 'switch',
}, title: 'Auto search',
{ description:
"SettingID": "default_showpostcreator", 'Force the app to automaticly search when a type input is detected... [Developer]',
"type" : "switch", value: fromStorage ? SettingStoragedValue('auto_search_ontype') : false,
"title": "Show default Post Creator", },
"description": "Force the app to automaticly search when a type input is detected... [Developer]", {
"value": fromStorage? SettingStoragedValue('default_showpostcreator') : false SettingID: 'default_showpostcreator',
}, type: 'switch',
{ title: 'Show default Post Creator',
"SettingID": "force_show_postactions", description:
"type" : "switch", 'Force the app to automaticly search when a type input is detected... [Developer]',
"title": "Not auto hide Posts Actions", value: fromStorage
"description": "Force the app to dont hide the post actions (likes, comments ...etc) automaticly... [Developer]", ? SettingStoragedValue('default_showpostcreator')
"value": fromStorage? SettingStoragedValue('force_show_postactions') : false : false,
}, },
{
SettingID: 'force_show_postactions',
type: 'switch',
title: 'Not auto hide Posts Actions',
description:
'Force the app to dont hide the post actions (likes, comments ...etc) automaticly... [Developer]',
value: fromStorage ? SettingStoragedValue('force_show_postactions') : false,
},
] ]

View File

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

View File

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

View File

@ -3,6 +3,5 @@ export * from './libs/comty_ng/pre.js';
export * from './libs/yulio_id/pre.js'; export * from './libs/yulio_id/pre.js';
export * from './libs/ycore_styles/pre.js'; export * from './libs/ycore_styles/pre.js';
export * from './libs/ycore_sdcp/pre.js'; export * from './libs/ycore_sdcp/pre.js';
export * from './libs/app_functions/pre.js' export * from './libs/app_functions/pre.js';
export * from './libs/rs_cloud/pre.js' export * from './libs/rs_cloud/pre.js';

View File

@ -1,34 +1,154 @@
import {SetControls, CloseControls} from "../../../components/Layout/Control" import { SetControls, CloseControls } from '../../../components/Layout/Control'
import {SwapMode} from '../../../components/Layout/Secondary' import { SwapMode } from '../../../components/Layout/Secondary'
import * as ycore from 'ycore'
export function QueryRuntime() { export function QueryRuntime() {
const validBackup = ycore.validate.backup()
if (!validBackup) ycore.make_data.backup()
} }
export function SetupApp() {
// TODO: Default sets
ycore.notify.success('Authorised, please reload the app for login!')
const resourceLoad = localStorage.getItem('resource_bundle')
if (!resourceLoad) {
localStorage.setItem('resource_bundle', 'light_ng')
}
}
export const CheckThisApp = { export const CheckThisApp = {
desktop_mode: () => { desktop_mode: () => {
const a = localStorage.getItem('desktop_src') const a = localStorage.getItem('desktop_src')
if (a == 'true') { if (a == 'true') {
return true return true
} }
return false return false
}, },
} }
export const SecondarySwap = { export const SecondarySwap = {
close: () => { close: () => {
SwapMode.close() SwapMode.close()
}, },
openPost: (e) => { openPost: e => {
SwapMode.openPost(e) SwapMode.openPost(e)
} },
} }
export const ControlBar = { export const ControlBar = {
set: (e) => { set: e => {
SetControls(e) SetControls(e)
}, },
close: () => { close: () => {
CloseControls() CloseControls()
} },
}
export function RefreshONCE() {
window.location = '/'
}
export function DetectNoNStableBuild(e1) {
switch (e1) {
case 'TagComponent':
if (package_json.DevBuild == true) {
return React.createElement(antd.Tag, { color: 'orange' }, ' No Stable')
}
if (package_json.DevBuild == false) {
return React.createElement(antd.Tag, { color: 'blue' }, ' Stable')
} else {
return 'No Stable'
}
break
default:
if (package_json.DevBuild == true) {
return 'No Stable'
}
if (package_json.DevBuild == false) {
return 'Stable'
} else {
return 'No Stable'
}
break
}
}
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 }
ycore.__rscloud.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']
ycore.__rscloud.sdcp_cloud.get(
(err, res) => {
if (err) {
return false
}
let framepayload = { token: { UserID, UserToken }, sdcp: res }
ycore.yconsole.log('FRAME ', framepayload)
ycore.__CTID_GEN((err, res) => {
if (err) {
ycore.notify.error('Critical error, token declined!')
return false
}
ycore.SetupApp()
callback(null, '200')
}, framepayload)
},
{ user_token: UserToken, user_id: UserID }
)
}
if (identState == 400) {
callback(null, '400')
}
} catch (error) {
console.log(error)
callback(true, '500')
ycore.notify.error('Server bad response')
}
}, containerpayload)
},
logout: () => {
ycore.__rscloud.yulio_id.logout((err, res) => {
if (err) {
return false
}
console.log(res)
const api_state = JSON.parse(res)['api_status']
ycore.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' }} />,
})
ycore.yconsole.log('Failed logout with YulioID™', res)
} else {
ycore.yconsole.log('Successful logout with YulioID™', res)
}
// Runtime after dispatch API
ycore.token_data.remove()
ycore.router.push({ pathname: '/login' })
})
},
} }

View File

@ -0,0 +1,22 @@
import { API_Call, endpoints } from 'ycore'
export const comty_get = {
session_data: () => {},
general_data: () => {
if (!payload) {
return false
}
const { id } = payload
let formdata = new FormData()
formdata.append('user_id', id)
API_Call(
(err, res) => {
return callback(err, res)
},
endpoints.get_general_data,
formdata
)
},
}

View File

@ -0,0 +1,186 @@
import { API_Call, endpoints, AppSettings } from 'ycore'
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)
},
endpoints.get_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)
},
endpoints.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('postPhoto', file) : null
const callOptions = { includeUserID: true }
API_Call(
(err, res) => {
return callback(err, res)
},
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)
},
endpoints.action_post,
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)
},
endpoints.action_post,
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)
},
endpoints.action_post,
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)
},
endpoints.action_post,
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)
},
endpoints.action_post,
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)
},
endpoints.action_post,
formdata
)
},
}

View File

@ -0,0 +1,41 @@
import { API_Call, endpoints } from 'ycore'
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)
},
endpoints.comments_actions,
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)
},
endpoints.action_post,
formdata
)
},
}

View File

@ -0,0 +1,23 @@
import { API_Call, endpoints } from 'ycore'
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)
},
endpoints.search_endpoint,
formdata,
callOptions
)
},
}

View File

@ -0,0 +1,62 @@
import { API_Call, endpoints } from 'ycore'
export const comty_user = {
setData: () => {},
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)
},
endpoints.follow_user,
formdata
)
},
block: (callback, payload) => {
// TO DO
return false
},
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)
},
endpoints.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)
},
endpoints.get_user_tags,
formdata
)
},
}

View File

@ -0,0 +1,46 @@
import { yConfig, yconsole, endpoints, token_data } from 'ycore'
export const get_app_session = {
get_id: callback => {
let formdata = new FormData()
formdata.append('server_key', yConfig.server_key)
formdata.append('type', 'get')
const requestOptions = {
method: 'POST',
body: formdata,
redirect: 'follow',
}
const uriObj = `${endpoints.get_sessions}${token_data.__token()}`
fetch(uriObj, requestOptions)
.then(response => response.text())
.then(result => {
const pre = JSON.stringify(result)
const pre2 = JSON.parse(pre)
const pre3 = JSON.stringify(JSON.parse(pre2)['data'])
const obj = JSON.parse(pre3)['session_id']
return callback(null, obj)
})
.catch(error => yconsole.log('error', error))
},
raw: callback => {
const formdata = new FormData()
formdata.append('server_key', yConfig.server_key)
formdata.append('type', 'get')
const requestOptions = {
method: 'POST',
body: formdata,
redirect: 'follow',
}
const uriObj = `${endpoints.get_sessions}${token_data.__token()}`
fetch(uriObj, requestOptions)
.then(response => response.text())
.then(result => {
const pre = JSON.stringify(result)
const parsed = JSON.parse(pre)
const obj = JSON.parse(parsed)['data']
yconsole.log(result, obj)
return callback(null, obj)
})
.catch(error => yconsole.log('error', error))
},
}

View File

@ -1,7 +1,14 @@
import * as ycore from 'ycore' import { token_data } from 'ycore'
import * as Icons from '@ant-design/icons' import * as Icons from '@ant-design/icons'
import { RenderFeed } from 'components/MainFeed' import { RenderFeed } from 'components/MainFeed'
export * from './comty_post.js'
export * from './comty_user.js'
export * from './comty_post_comment.js'
export * from './get_app_session.js'
export * from './comty_search.js'
export * from './comty_get.js'
export const FeedHandler = { export const FeedHandler = {
refresh: () => { refresh: () => {
RenderFeed.RefreshFeed() RenderFeed.RefreshFeed()
@ -16,7 +23,7 @@ export const FeedHandler = {
export const IsThisPost = { export const IsThisPost = {
owner: (post_uid) => { owner: (post_uid) => {
const a = ycore.handlerYIDT.__id() const a = token_data.__id()
if (post_uid == a) { if (post_uid == a) {
return true return true
} }
@ -33,273 +40,6 @@ export const IsThisPost = {
} }
} }
export const Post_Comments = {
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);
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.comments_actions,
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)
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.action_post,
formdata,
)
}
}
export const comty_user = {
setData: () => {
},
follow: (callback, payload) => {
if (!payload) {return false}
const { user_id } = payload
let formdata = new FormData();
formdata.append("user_id", user_id);
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.follow_user,
formdata,
)
},
block:(callback, payload) => {
// TO DO
return false
},
find: (callback, payload) => {
if (!payload) {return false}
const { key } = payload
let formdata = new FormData();
formdata.append("search_key", key);
const callOptions = { timeout: 10000 }
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.find_user,
formdata,
callOptions
)
},
__tags: (callback, payload) => {
if (!payload) {return false}
const { id } = payload
let formdata = new FormData();
formdata.append("user_id", id )
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.get_user_tags,
formdata
)
}
}
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", ycore.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;
}
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.get_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"))
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.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("postPhoto", file) : null
const callOptions = { includeUserID: true }
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.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)
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.action_post,
formdata,
)
},
save: (callback, payload) => {
},
edit: (callback, payload) =>{
},
__pin: (callback, payload) => {
},
__boost: (callback, payload) => {
}
}
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 }
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.search_endpoint,
formdata,
callOptions
)
}
}
export const comty_get = {
session_data: () => {
},
general_data: () => {
if (!payload) {return false}
const { id } = payload
let formdata = new FormData();
formdata.append("user_id", id);
ycore.API_Call((err,res)=> {
return callback(err,res)
},
ycore.endpoints.get_general_data,
formdata
)
}
}
export const get_app_session = {
get_id: (callback) => {
let formdata = new FormData();
formdata.append("server_key", ycore.yConfig.server_key);
formdata.append("type", "get");
const requestOptions = {
method: 'POST',
body: formdata,
redirect: 'follow'
};
const uriObj = `${ycore.endpoints.get_sessions}${ycore.handlerYIDT.__token()}`
fetch(uriObj, requestOptions)
.then(response => response.text())
.then(result => {
const pre = JSON.stringify(result)
const pre2 = JSON.parse(pre)
const pre3 = JSON.stringify(JSON.parse(pre2)["data"])
const obj = JSON.parse(pre3)["session_id"]
return callback(null, obj)
})
.catch(error => ycore.yconsole.log('error', error));
},
raw: (callback) => {
const formdata = new FormData();
formdata.append("server_key", ycore.yConfig.server_key);
formdata.append("type", "get");
const requestOptions = {
method: 'POST',
body: formdata,
redirect: 'follow'
};
const uriObj = `${ycore.endpoints.get_sessions}${ycore.handlerYIDT.__token()}`
fetch(uriObj, requestOptions)
.then(response => response.text())
.then(result => {
const pre = JSON.stringify(result)
const parsed = JSON.parse(pre)
const obj = JSON.parse(parsed)["data"]
ycore.yconsole.log(result, obj)
return callback(null, obj)
})
.catch(error => ycore.yconsole.log('error', error));
}
}
export const GetPostPrivacy = { export const GetPostPrivacy = {
bool: (e) => { bool: (e) => {
switch (e) { switch (e) {

View File

@ -0,0 +1,75 @@
import jquery from 'jquery'
import * as ycore from 'ycore'
export function API_Call(callback, endpoint, payload, options, __token) {
var prefix = `[API_Call] `
if (!endpoint) return false
if (!payload) {
ycore.yconsole.log(prefix, 'Calling api without Payload!!!')
}
let payloadContainer = payload ? payload : new FormData()
payloadContainer.append('server_key', ycore.yConfig.server_key)
let fendpoint = `${endpoint}${ycore.token_data.__token()}`
let method
let timeout
let processData
let includeUserID
let override__token
let disabledToken
if (options) {
method = options.method ? options.method : 'POST'
timeout = options.timeout ? options.timeout : 0
processData = options.processData ? options.processData : false
includeUserID = options.includeUserID ? options.includeUserID : false
override__token = options.override__token ? options.override__token : false
disabledToken = options.disabledToken ? options.disabledToken : false
} else {
method = 'POST'
timeout = 0
processData = false
includeUserID = false
override__token = false
disabledToken = false
}
if (override__token || __token) {
if (!__token) {
ycore.yconsole.log(`${prefix} Missing Overriding __token`)
return
}
ycore.yconsole.log(`${prefix} Overriding __token => ${__token}`)
fendpoint = `${endpoint}${__token}`
}
if (disabledToken) {
ycore.yconsole.log('${prefix} Dimmissing the token generation')
fendpoint = `${endpoint}`
}
if (includeUserID) {
payloadContainer.append('user_id', ycore.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 => {
ycore.yconsole.log(response)
return callback(false, response)
})
.fail(error => {
ycore.yconsole.log(`${prefix} (ERROR) `, error)
ycore.Alive_API.fail(error)
return callback(true, error)
})
}

View File

@ -1,62 +1,73 @@
import jquery from 'jquery'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import { FormatColorResetOutlined } from '@material-ui/icons' export * from './api_call.js'
export const Alive_API = { export const Alive_API = {
fail: (a) => { fail: a => {
if (a){ if (a) {
ycore.yconsole.log(a) ycore.yconsole.log(a)
ycore.notify.error(a) ycore.notify.error(a)
}
} }
},
} }
export const __rscloud = {
yulio_id: {
auth: (callback, payload) => {
if (!payload) return false
const { username, password } = payload
export function API_Call(callback, endpoint, payload, options){ const formdata = new FormData()
if (!payload || !endpoint) { formdata.append('username', username)
return false formdata.append('password', password)
}
let payloadContainer = payload;
payloadContainer.append("server_key", ycore.yConfig.server_key);
let method;
let timeout;
let processData;
let includeUserID;
if (options) { const callOptions = { disabledToken: true }
method = options.method? options.method : "POST" ycore.API_Call(
timeout = options.timeout? options.timeout : 0 (err, res) => {
processData = options.processData? options.processData : false return callback(err, res)
includeUserID = options.includeUserID? options.includeUserID : false },
}else { ycore.endpoints.auth_endpoint,
method = "POST" formdata,
timeout = 0 callOptions
processData = false )
includeUserID = false },
} logout: callback => {
const callOptions = { includeUserID: true }
if (includeUserID) { ycore.API_Call(
payloadContainer.append("user_id", ycore.handlerYIDT.__id()); (err, res) => {
} return callback(err, res)
},
ycore.endpoints.removeToken,
null,
callOptions
)
},
verify: (callback, payload) => {},
sign: (callback, payload) => {},
},
sdcp_cloud: {
get: (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 requestOptions = { const optionCall = { override__token: true }
"url": `${endpoint}${ycore.handlerYIDT.__token()}`, ycore.API_Call(
"method": method, (err, res) => {
"timeout": timeout, try {
"data": payloadContainer, let cooked = JSON.parse(res)['user_data']
"mimeType": "multipart/form-data", let Ensamblator = btoa(JSON.stringify(cooked))
"processData": processData, return callback(err, Ensamblator)
"contentType": false } catch (error) {
}; return callback(true, error)
}
jquery.ajax(requestOptions) },
.done(response => { ycore.endpoints.get_userData_endpoint,
ycore.yconsole.log(response) formdata,
return callback(false, response) optionCall,
}) user_token
.fail(error => { )
ycore.yconsole.log('error', error) },
ycore.Alive_API.fail(error) set: () => {},
return callback(true, error) },
}); }
}

View File

@ -2,117 +2,58 @@ import * as ycore from 'ycore'
import localforage from 'localforage' import localforage from 'localforage'
export const asyncSDCP = { export const asyncSDCP = {
setSDCP: function (value) { setSDCP: function(value) {
return Promise.resolve().then(function () { return Promise.resolve().then(function() {
localforage.setItem('SDCP', value) localforage.setItem('SDCP', value)
}); })
}, },
getRaw: () => { getRaw: () => {
try { try {
return localforage.getItem('SDCP'); return localforage.getItem('SDCP')
} catch (err) { } catch (err) {
return false return false
}
},
get: (callback) => {
try {
const a = ycore.asyncSDCP.getRaw((err, value)=> {
const b = ycore.CryptSDCP.atob_parse(value)
return callback(null, b)
})
} catch (err) {
return false
}
},
};
export function GetSDCPfromCloud(values, res) {
const prefix = '[InitSDCP]';
let payload = {};
if (!values) {
const message = 'Missing payload! Exception while request data...';
ycore.yconsole.log(prefix, message)
return;
} }
payload.UserToken = values.UserToken; },
payload.UserID = values.UserID; get: callback => {
if (payload) { try {
ycore.GetUserData(payload, (err, response) => const a = ycore.asyncSDCP.getRaw((err, value) => {
{ const b = ycore.cryptSDCP.atob_parse(value)
let cooked = JSON.parse(response)['user_data'] return callback(null, b)
let Ensamblator = btoa(JSON.stringify(cooked)) })
res(Ensamblator); } catch (err) {
} return false
)
} }
},
} }
export function UpdateSDCP() { export const cryptSDCP = {
const prefix = '[UpdateSDCP]'; atob_parse: e => {
ycore.GetUserData(null, (err, response) => { if (e) {
let cooked = JSON.parse(response)['user_data'] try {
let Lsdcp = [atob(sessionStorage.getItem('SDCP'))]; atob(e)
let Nsdcp = [JSON.stringify(cooked)] } catch (err) {
const e1 = btoa(Lsdcp) ycore.notify.error(err)
const e2 = btoa(Nsdcp) ycore.router.push({
const n = e1.localeCompare(e2) pathname: '/login',
if (!e2) { })
ycore.yconsole.log(prefix, 'API Returned empty response! We recommend to logout')
return
}
if (e1 == e2) {
ycore.yconsole.log(prefix, 'SDCP Equality')
}else{
ycore.yconsole.log(prefix, 'SDCP Update detected ! => ', n)
ycore.yconsole.debug(`Compare versions => NEW ${[e1]} || OLD ${[e2]} `)
ycore.asyncSDCP.setSDCP(e2)
}
})
}
export function SDCP() {
let a = ycore.asyncSDCP.get()
if (a) {
return a
}
return false
}
export const CryptSDCP = {
atob_parse: (e) => {
if (e) {
try {
atob(e);
} catch (err) {
ycore.notifyError(err)
ycore.router.push({pathname: '/login',})
return false
}
try {
let decodedSDCP = atob(e);
let parsedSDCP = JSON.parse(decodedSDCP);
return parsedSDCP;
} catch (err) {
ycore.notifyError(err)
ycore.router.push({pathname: '/login',})
return false
}
}
return false return false
}, }
valid: () => { try {
const a = ycore.asyncSDCP.get() let decodedSDCP = atob(e)
return a? true : false let parsedSDCP = JSON.parse(decodedSDCP)
return parsedSDCP
} catch (err) {
ycore.notify.error(err)
ycore.router.push({
pathname: '/login',
})
return false
}
} }
return false
},
valid: () => {
const a = ycore.asyncSDCP.get()
return a ? true : false
},
} }
export function SetupApp(){
// TODO: Default sets
ycore.notify.success('Authorised, please reload the app for login!')
const resourceLoad = localStorage.getItem('resource_bundle')
if (!resourceLoad) {
localStorage.setItem('resource_bundle', 'light_ng')
}
}

View File

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

View File

@ -1,296 +1,38 @@
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import Cookies from 'ts-cookies'
import Cookies from "ts-cookies";
import keys from '../../../../config/keys.js';
import * as Icons from '@ant-design/icons';
var jquery = require("jquery"); // EXPORT PUBLIC WORKERS
var jwt = require("jsonwebtoken") export * from './token_data.js'
export * from './ctid_gen.js'
export * from './validate.js'
export function userData() {
export function userData(){ return ycore.token_data.get()
return ycore.handlerYIDT.get()
} }
export const make_data = {
function __API__User (payload, sdcp, callback){ backup: () => {
const { UserID, UserToken } = payload localStorage.setItem('last_backup', Cookies.get('cid'))
},
const a = ycore.CryptSDCP.atob_parse(sdcp)
const { avatar, admin, pro, dev, is_pro, username } = a;
const frame = {
UserID,
UserToken,
avatar,
admin,
pro,
dev,
is_pro,
username,
exp: ycore.AppSettings.SignForNotExpire? 0 : Math.floor(Date.now() / 1000) + (60 * 60),
}
ycore.handlerYIDT.set(frame, done => {
done? callback(false, true) : callback(true, false)
})
}
export const handlerYIDT = {
set: (value, callback) => {
jwt.sign(
value,
keys.secretOrKey,
(err, token) => {
err? null : Cookies.set('cid', token)
callback(true)
}
)
return 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
}
ycore.yconsole.debug(final)
return final
},
remove: () =>{
Cookies.remove('cid')
},
__token: () => {
return ycore.handlerYIDT.get().UserToken
},
__id: () => {
return ycore.handlerYIDT.get().UserID
}
}
export function ValidLoginSession(callback){
let validtoken = false;
const a = Cookies.get('cid');
if (a) {
const modExp = ycore.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()
ycore.yconsole.log(`TOKEN EXP => ${tokenExp} ${modExp? '( Infinite )' : `( ${tokenExpLocale} )` } || NOW => ${now}`)
if (modExp == false) {
if(tokenExp < now) {
ycore.yconsole.log('This token is expired !!!')
notexp = false
}
}
if (notexp && exists) {
validtoken = true
}
}
if (callback) {
callback(validtoken)
}
return validtoken
}
export function ValidBackup(){
let ValidBackupToken = false;
let LastestToken = localStorage.getItem('last_backup');
if (LastestToken) {
let LastestTokenDC = jwt.decode(LastestToken)
if (LastestTokenDC){
ValidBackupToken = true
}
}
return ValidBackupToken;
}
export function MakeBackup(){
if (ValidBackup() == false) {
localStorage.setItem('last_backup', Cookies.get('cid'))
return
}
}
export function LogoutCall(){
const prefix = ('[YID Session] ')
ycore.yconsole.log('Logout Called !')
let DecodedToken = ycore.handlerYIDT.__token() || atob(localStorage.getItem('last_backup'))
const urlOBJ = (`${ycore.endpoints.removeToken}${DecodedToken}`)
ycore.yconsole.log(prefix, ' Login out with token => ', DecodedToken, urlOBJ)
const form = new FormData();
form.append("server_key", ycore.yConfig.server_key);
const settings = {
"url": urlOBJ,
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
jquery.ajax(settings)
.done((response) => {
const api_state = JSON.parse(response)['api_status']
ycore.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' }} />
})
ycore.yconsole.log("Failed logout with YulioID™", response)
}
else {
ycore.yconsole.log("Successful logout with YulioID™", response, urlOBJ)
}
// Runtime after dispatch API
ycore.handlerYIDT.remove()
ycore.router.push({pathname: '/login',})
})
.fail((response) => {
ycore.Alive_API.fail(response)
})
}
export function __AppSetup__(EncUsername, EncPassword, callback) {
const prefix = '[Auth Server]:';
if (!EncUsername || !EncPassword) {
const message = 'Missing Data! Process Aborted...';
ycore.yconsole.log(prefix, message);
}
const server_key = ycore.yConfig.server_key;
let username = atob(EncUsername);
let password = atob(EncPassword);
const form = new FormData();
form.append("server_key", server_key);
form.append("username", username);
form.append("password", password);
const settings = {
"url": ycore.endpoints.auth_endpoint,
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
jquery.ajax(settings)
.done(function (response) {
ycore.yconsole.log(prefix, 'Server response... Dispathing data to login API...');
try {
var identState = JSON.parse(response)['api_status'];
if (identState == 200) {
const UserID = JSON.parse(response)['user_id'];
const UserToken = JSON.parse(response)['access_token'];
let FramePayload = { UserID, UserToken }
ycore.yconsole.log(FramePayload)
callback(null, '200')
ycore.GetSDCPfromCloud(FramePayload, (res) => res? __API__User(FramePayload, res,
(err, done) => {
if (err){
ycore.notify.error('Critical error, token declined!')
return false
}
ycore.SetupApp()
}) : null )
}
if (identState == 400) {
callback(null, '400')
}
} catch (error) {
callback(true, '500')
ycore.notifyError('Server bad response')
}
return;
})
.fail(function (response) {
const exception = new Error("Server failed response . . . :( ");
ycore.Alive_API.fail(response)
return;
})
}
export function GetUserData (values, callback) {
const prefix = '[YID SDCP]';
const offlineAPI = ycore.handlerYIDT.get();
const globalValue = values || {UserToken: offlineAPI.UserToken, UserID: offlineAPI.UserID};
const usertoken = globalValue.UserToken
const userid = globalValue.UserID
if (!globalValue) {
const message = 'Missing payload! Exception while request data... Maybe the user is not login';
ycore.yconsole.log(prefix, message)
return;
}
const ApiPayload = new FormData();
ApiPayload.append("server_key", ycore.yConfig.server_key);
ApiPayload.append("fetch", 'user_data');
ApiPayload.append("user_id", userid);
const urlOBJ = (`${ycore.endpoints.get_userData_endpoint}${usertoken}`)
const settings = {
"url": urlOBJ,
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": ApiPayload
}
jquery.ajax(settings)
.done(
function (response) {
let resString = JSON.stringify(response);
let resParsed = JSON.parse(resString);
callback(null, resParsed)
}
)
.fail(
function (response) {
ycore.yconsole.log(prefix, 'Server failure!', response)
ycore.Alive_API.fail(response)
callback(true, response )
}
)
} }
export const IsThisUser = { export const IsThisUser = {
admin: () => { admin: () => {
const a = ycore.userData() const a = ycore.userData()
return ycore.booleanFix(a.admin)? true : false return ycore.booleanFix(a.admin) ? true : false
}, },
dev: () => { dev: () => {
const a = ycore.userData() const a = ycore.userData()
return ycore.booleanFix(a.dev)? true : false return ycore.booleanFix(a.dev) ? true : false
}, },
pro: () => { pro: () => {
const a = ycore.userData() const a = ycore.userData()
return ycore.booleanFix(a.is_pro)? true : false return ycore.booleanFix(a.is_pro) ? true : false
}, },
same: (a) => { same: a => {
if(a == ycore.userData().UserID){ if (a == ycore.userData().UserID) {
return true return true
}
return false
} }
} return false
},
}

View File

@ -0,0 +1,45 @@
import * as ycore from 'ycore'
import Cookies from 'ts-cookies'
import keys from '../../../../config/keys.js'
var jwt = require('jsonwebtoken')
export const token_data = {
set: (value, callback) => {
jwt.sign(value, keys.secretOrKey, (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
}
ycore.yconsole.debug(final)
return final
},
remove: () => {
Cookies.remove('cid')
},
__token: () => {
return ycore.token_data.get().UserToken
},
__id: () => {
return ycore.token_data.get().UserID
},
}

View File

@ -0,0 +1,55 @@
import * as ycore from 'ycore'
import Cookies from 'ts-cookies'
var jwt = require('jsonwebtoken')
export const validate = {
session: callback => {
let validtoken = false
const a = Cookies.get('cid')
if (a) {
const modExp = ycore.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()
ycore.yconsole.log(
`TOKEN EXP => ${tokenExp} ${
modExp ? '( Infinite )' : `( ${tokenExpLocale} )`
} || NOW => ${now}`
)
if (modExp == false) {
if (tokenExp < now) {
ycore.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 = localStorage.getItem('last_backup')
if (LastestToken) {
let LastestTokenDC = jwt.decode(LastestToken)
if (LastestTokenDC) {
ValidBackupToken = true
}
}
return ValidBackupToken
},
}

View File

@ -1,330 +1,334 @@
/** /**
* @yCore_Worker * @yCore_Worker
* *
* @author rStudio© 2020 * @author rStudio© 2020
* @licensed Pending... * @licensed Pending...
*/ */
import {Endpoints} from "globals/endpoints.js"; import { Endpoints } from 'globals/endpoints.js'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import localforage from "localforage" import localforage from 'localforage'
import { format } from 'timeago.js'; import { format } from 'timeago.js'
import umiRouter from "umi/router"; import umiRouter from 'umi/router'
import * as antd from "antd"; import * as antd from 'antd'
import moment from 'moment' import moment from 'moment'
import React from "react"; import React from 'react'
import config from "config" import config from 'config'
import "./libs.js" import './libs.js'
import { func } from "prop-types";
export * from "../../config/app.settings.js" export * from '../../config/app.settings.js'
export * from "./libs.js" export * from './libs.js'
export var { router } = require("utils") export var { router } = require('utils')
export var yConfig = config.yConfig; export var yConfig = config.yConfig
export var endpoints = Endpoints; export var endpoints = Endpoints
var package_json = require("../../package.json"); var package_json = require('../../package.json')
export const UUAID = `${package_json.name}==${package_json.UUID}` export const UUAID = `${package_json.name}==${package_json.UUID}`
localforage.config({ localforage.config({
name : UUAID, name: UUAID,
version : 1.0, version: 1.0,
size : 4980736, size: 4980736,
storeName : package_json.name storeName: package_json.name,
}); })
export const AppInfo = {
apid: package_json.name,
name: package_json.title,
version: package_json.version,
logo: config.FullLogoPath,
logo_dark: config.DarkFullLogoPath,
}
/** /**
* Convert a base64 string in a Blob according to the data and contentType. * Convert a base64 string in a Blob according to the data and contentType.
* *
* @param b64Data {String} Pure base64 string without 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 contentType {String} the content type of the file i.e (image/jpeg - image/png - text/plain)
* @param sliceSize {Int} SliceSize to process the byteCharacters * @param sliceSize {Int} SliceSize to process the byteCharacters
* @return Blob * @return Blob
*/ */
export function b64toBlob(b64Data, contentType, sliceSize) { export function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || ''; contentType = contentType || ''
sliceSize = sliceSize || 512; sliceSize = sliceSize || 512
var byteCharacters = atob(b64Data); var byteCharacters = atob(b64Data)
var byteArrays = []; var byteArrays = []
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize); var slice = byteCharacters.slice(offset, offset + sliceSize)
var byteNumbers = new Array(slice.length); var byteNumbers = new Array(slice.length)
for (var i = 0; i < slice.length; i++) { for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i); byteNumbers[i] = slice.charCodeAt(i)
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
} }
var blob = new Blob(byteArrays, {type: contentType}); var byteArray = new Uint8Array(byteNumbers)
return blob;
}
export function ReadFileAsB64(file, callback){ byteArrays.push(byteArray)
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);
}
}
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);
} }
export const time = { var blob = new Blob(byteArrays, { type: contentType })
ago: (a) => { return blob
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();
}
}
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));
};
export function gotoBottom(id){
const element = document.getElementById(id);
element.scrollTop = element.scrollHeight - element.clientHeight;
}
export function gotoElement(element){
document.getElementById(element).scrollIntoView();
} }
/** /**
* Return parsed some information about this App * Convert a file in a B64 string according to the file.
* *
* @return {object} * @param file {object} Raw File object
* @return b64 {string}
*/ */
export const AppInfo = { export function ReadFileAsB64(file, callback) {
apid: package_json.name, if (file) {
name: package_json.title, var reader = new FileReader()
version: package_json.version, reader.onload = function(readerEvt) {
logo: config.FullLogoPath, var binaryString = readerEvt.target.result
logo_dark: config.DarkFullLogoPath const a = `data:image/png;base64, ${btoa(binaryString)}`
return callback(a)
}
reader.readAsBinaryString(file)
}
} }
/** /**
* Convert the localStorage values (AppSettings) parsed * 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)
}
/**
* (HELPER) Convert the localStorage values (AppSettings) parsed
*
* @param e {String} String of SettingID for search * @param e {String} String of SettingID for search
* @return {string} Boolean value * @return {string} Boolean value
*/ */
export function SettingStoragedValue(e){ export function SettingStoragedValue(e) {
try { try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings')) const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => { ycore.ReturnValueFromMap({ data: fromStorage, key: e })
return item.SettingID === e? item.value : null } catch (error) {
}) return null
const fr = Ite.filter(Boolean) }
return fr.toString() }
}
catch (error) { /**
return null * 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
}
try {
const Ite = payload.data.map(item => {
return item.key === payload.key ? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
} catch (error) {
return false
}
}
/**
* 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
})
} }
/** /**
* Global fix for convert '1, 0' to string boolean 'true, false' * Global fix for convert '1, 0' to string boolean 'true, false'
* *
* @param e {int} Numeric boolean reference * @param e {int} Numeric boolean reference
* @return {bool} Boolean value * @return {bool} Boolean value
*/ */
export function booleanFix(e){ export function booleanFix(e) {
if(e == 1){ if (e == 1) return true
return true return false
} }
return false
/**
* Go to bottom of an element by id
*
* @param id {string}
* @return null
*/
export function gotoBottom(id) {
const element = document.getElementById(id)
element.scrollTop = element.scrollHeight - element.clientHeight
}
/**
* Go to position of an element by id
*
* @param element {array}
* @return object
*/
export function gotoElement(element) {
document.getElementById(element).scrollIntoView()
}
/**
* 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()
},
} }
/** /**
* Framework functionality for navigate between pages (Router) * Framework functionality for navigate between pages (Router)
* *
*/ */
export const crouter = { export const crouter = {
native: (e) =>{ native: e => {
umiRouter.push({ umiRouter.push({
pathname: `/${e}`, pathname: `/${e}`,
search: window.location.search, search: window.location.search,
}); })
}, },
default: (e) =>{ default: e => {
router.push(e) router.push(e)
} },
} }
/**
* Framework functionality for show with interface an notification
*
*/
export const notify = { export const notify = {
success: (...res) => { success: (...res) => {
antd.notification.success({ antd.notification.success({
message: 'Well', message: 'Well',
description: (res.toString()), description: res.toString(),
placement: 'bottomLeft' placement: 'bottomLeft',
}) })
}, },
error: (...res) => { error: (...res) => {
antd.notification.error({
message: 'Wopss',
description: (<div><span>An wild error appear! : </span><br/><br/><div style={{ position: 'relative', width: '100%',backgroundColor: 'rgba(243, 19, 19, 0.329)', bottom: '0', color: 'black', padding: '3px' }} >{res.toString()}</div></div>),
placement: 'bottomLeft'
})
},
proccess: (...res) => {
antd.notification.open({
icon: <Icons.LoadingOutlined style={{ color: '#108ee9' }} />,
message: 'Please wait',
description: (<div>{res}</div>),
placement: 'bottomLeft'
})
}
}
/**
* Render User Notification about an Error
*
* @param err {String} String of error for show
*/
export function notifyError(err){
antd.notification.error({ antd.notification.error({
message: 'Wopss', message: 'Wopss',
description: (<div><span>An wild error appear! : </span><br/><br/><div style={{ position: 'relative', width: '100%',backgroundColor: 'rgba(243, 19, 19, 0.329)', bottom: '0', color: 'black', padding: '3px' }} >{err.toString()}</div></div>), description: (
placement: 'bottomLeft' <div>
<span>An wild error appear! : </span>
<br />
<br />
<div
style={{
position: 'relative',
width: '100%',
backgroundColor: 'rgba(243, 19, 19, 0.329)',
bottom: '0',
color: 'black',
padding: '3px',
}}
>
{res.toString()}
</div>
</div>
),
placement: 'bottomLeft',
}) })
} },
/** proccess: (...res) => {
* Render User Notification about an proccess
*
* @param cust {String} String of proccess for show
*/
export function notifyProccess(cust){
antd.notification.open({ antd.notification.open({
icon: <Icons.LoadingOutlined style={{ color: '#108ee9' }} />, icon: <Icons.LoadingOutlined style={{ color: '#108ee9' }} />,
message: 'Please wait', message: 'Please wait',
description: (<div>{cust}</div>), description: <div>{res}</div>,
placement: 'bottomLeft' placement: 'bottomLeft',
}) })
} },
export function arrayRemoveByID(arr, value) {
return arr.filter(function(ele){
return ele.id != value;
});
}
/**
* 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();
}
}
/**
* Request browser for refresh the windows
*
*/
export function RefreshONCE(){
window.location = "/"
}
/**
* Parse information about this App
*
* @param e1 {string} Declare type
* @return {any} JSX Component / Object information
*/
export function DetectNoNStableBuild(e1) {
switch (e1) {
case 'TagComponent':
if (package_json.DevBuild == true) {
return React.createElement(antd.Tag, { color: 'orange' }, " No Stable");
}
if (package_json.DevBuild == false) {
return React.createElement(antd.Tag, { color: 'blue' }, " Stable");
}
else {
return ('No Stable');
}
break;
default:
if (package_json.DevBuild == true) {
return ('No Stable');
}
if (package_json.DevBuild == false) {
return ('Stable');
}
else {
return ('No Stable');
}
break;
}
} }
/** /**
* User console with setting user permissions * User console with setting user permissions
* *
* @param ... {any} Use for type of console * @param ... {any} Use for type of console
*/ */
export const yconsole = { export const yconsole = {
log: (...cont)=>{ log: (...cont) => {
SettingStoragedValue('force_showDevLogs')? console.log(...cont) : null SettingStoragedValue('force_showDevLogs') ? console.log(...cont) : null
return return
}, },
debug: (...cont)=>{ debug: (...cont) => {
SettingStoragedValue('force_showDevLogs')? console.debug(...cont) : null SettingStoragedValue('force_showDevLogs') ? console.debug(...cont) : null
return return
}, },
error: (...cont)=>{ error: (...cont) => {
SettingStoragedValue('force_showDevLogs')? console.error(...cont) : null SettingStoragedValue('force_showDevLogs') ? console.error(...cont) : null
return return
}, },
warn: (...cont)=>{ warn: (...cont) => {
SettingStoragedValue('force_showDevLogs')? console.warn(...cont) : null SettingStoragedValue('force_showDevLogs') ? console.warn(...cont) : null
return return
} },
} }
/**
* 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()
}
}

View File

@ -1,10 +1,9 @@
import React, { Component } from 'react'; import React, { Component } from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import styles from './index.less' import styles from './index.less'
import classnames from 'classnames' import classnames from 'classnames'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons'
export const SetHeaderSearchType = { export const SetHeaderSearchType = {
disable: () => { disable: () => {
@ -18,58 +17,60 @@ export const SetHeaderSearchType = {
}, },
toSecondary: () => { toSecondary: () => {
window.HeaderSearchComponent.setState({ framelocation: 'secondary' }) window.HeaderSearchComponent.setState({ framelocation: 'secondary' })
} },
} }
export default class HeaderSearch extends Component { export default class HeaderSearch extends Component {
constructor(props) { constructor(props) {
super(props); super(props)
window.HeaderSearchComponent = this; window.HeaderSearchComponent = this
this.state = { this.state = {
value: '', value: '',
searchidden: false, searchidden: false,
framelocation: 'primary', framelocation: 'primary',
}; }
} }
sendToSearch = () => { sendToSearch = () => {
const { value } = this.state; const { value } = this.state
ycore.crouter.native(`s/${value}`) ycore.crouter.native(`s/${value}`)
} }
onChange = e => { onChange = e => {
const { value } = e.target; const { value } = e.target
this.setState({value: value}) this.setState({ value: value })
if (ycore.AppSettings.auto_search_ontype == 'true') { if (ycore.AppSettings.auto_search_ontype == 'true') {
this.autosend() this.autosend()
} }
}; }
autosend = () => { autosend = () => {
let timeout = null; let timeout = null
let input = document.getElementById('search_input'); let input = document.getElementById('search_input')
input.addEventListener('keyup', (e) => { input.addEventListener('keyup', e => {
clearTimeout(timeout); clearTimeout(timeout)
timeout = setTimeout(() => { timeout = setTimeout(() => {
const { value } = this.state; const { value } = this.state
ycore.crouter.native(`s/${value}`) ycore.crouter.native(`s/${value}`)
}, 500); }, 500)
}); })
} }
render() { render() {
const { searchidden } = this.state const { searchidden } = this.state
return ( return (
<div className={classnames( styles.HeaderSearchWrapper, {[styles.hidden]: searchidden})}> <div
<span className={styles.headerSearch}> className={classnames(styles.HeaderSearchWrapper, {
[styles.hidden]: searchidden,
})}
>
<span className={styles.headerSearch}>
<antd.Input <antd.Input
id='search_input' id="search_input"
prefix={<Icons.SearchOutlined />} prefix={<Icons.SearchOutlined />}
placeholder=' Search on Comty...' placeholder=" Search on Comty..."
onChange={ this.onChange } onChange={this.onChange}
onPressEnter={this.sendToSearch} onPressEnter={this.sendToSearch}
/> />
</span> </span>
</div> </div>
); )
} }
} }

View File

@ -1,24 +1,26 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.HeaderSearchWrapper{ .HeaderSearchWrapper {
z-index: 20; z-index: 20;
top: 0; top: 0;
display: flex; display: flex;
margin: auto; margin: auto;
width: 100%; width: 100%;
&.hidden{
&.hidden {
display: none; display: none;
} }
} }
.headerSearch { .headerSearch {
margin: auto; margin: auto;
:global{
:global {
.ant-input-affix-wrapper { .ant-input-affix-wrapper {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
padding: 0; padding: 0;
color: rgba(0,0,0,.65); color: rgba(0, 0, 0, .65);
font-size: 14px; font-size: 14px;
font-variant: tabular-nums; font-variant: tabular-nums;
line-height: 1.5; line-height: 1.5;
@ -31,19 +33,23 @@
} }
.ant-input-affix-wrapper .ant-input-prefix { .ant-input-affix-wrapper .ant-input-prefix {
left: 12px; left: 12px;
} }
.ant-input-affix-wrapper{
.ant-input-affix-wrapper {
background-color: transparent !important; background-color: transparent !important;
border-color: transparent; border-color: transparent;
border-radius: 12px; border-radius: 12px;
} }
.ant-input-affix-wrapper > input.ant-input {
.ant-input-affix-wrapper>input.ant-input {
padding: 0 0 0 30px; padding: 0 0 0 30px;
border: inherit; border: inherit;
outline: inherit; outline: inherit;
} }
.ant-input-affix-wrapper .ant-input-prefix, .ant-input-affix-wrapper .ant-input-suffix {
.ant-input-affix-wrapper .ant-input-prefix,
.ant-input-affix-wrapper .ant-input-suffix {
background-color: transparent !important; background-color: transparent !important;
border-color: transparent; border-color: transparent;
border-radius: 12px; border-radius: 12px;
@ -54,14 +60,14 @@
display: flex; display: flex;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
color: rgba(0,0,0,.65); color: rgba(0, 0, 0, .65);
line-height: 0; line-height: 0;
-ms-transform: translateY(-50%); -ms-transform: translateY(-50%);
transform: translateY(-50%); transform: translateY(-50%);
color: #9d9da7 !important; color: #9d9da7 !important;
} }
.ant-input{ .ant-input {
border-radius: 12px; border-radius: 12px;
color: #9D9DA7; color: #9D9DA7;
background-color: #FFFFFF; background-color: #FFFFFF;

View File

@ -6,37 +6,42 @@
@LDarkMode-color: #fff; @LDarkMode-color: #fff;
@LLightMode-color: #2F2E30; @LLightMode-color: #2F2E30;
.chatTitle{ .chatTitle {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
padding: 0 10px 0 0; padding: 0 10px 0 0;
float: right; float: right;
display: flex; display: flex;
h1{
h1 {
line-height: 1.2; line-height: 1.2;
margin-right: 5px; margin-right: 5px;
} }
svg{
svg {
font-size: 20px; font-size: 20px;
} }
} }
.something_thats_pulling_me_down{ .something_thats_pulling_me_down {
:global{ :global {
text-align: center; text-align: center;
bottom: 0; bottom: 0;
position: absolute; position: absolute;
width: 100%; width: 100%;
} }
} }
.siderhead{
.siderhead {
font-family: 'Source Sans Pro', sans-serif; font-family: 'Source Sans Pro', sans-serif;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
::first-letter{
::first-letter {
margin-left: 7px; margin-left: 7px;
} }
height: 60px; height: 60px;
font-size: 17px; font-size: 17px;
} }
@ -49,42 +54,55 @@
width: 100%; width: 100%;
left: 0; left: 0;
position: absolute; position: absolute;
:global { :global {
.ant-layout-sider-dark { .ant-layout-sider-dark {
background-color: @LDarkMode-backgroud; background-color: @LDarkMode-backgroud;
color: @DarkMode-color; color: @DarkMode-color;
h2{
h2 {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-item{
.ant-menu-item {
color: @DarkMode-color; color: @DarkMode-color;
} }
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
:hover { :hover {
background-color: rgb(80, 80, 80); background-color: rgb(80, 80, 80);
color: #fff; color: #fff;
} }
border-right: 1px solid transparent; border-right: 1px solid transparent;
} }
} }
.ant-layout-sider-light { .ant-layout-sider-light {
background-color: @Theme-SiderDeco-Backgroud; background-color: @Theme-SiderDeco-Backgroud;
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
h2{
h2 {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-item{
.ant-menu-item {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
:hover { :hover {
background-color: @Theme-Hover-Backgroud; background-color: @Theme-Hover-Backgroud;
color: #fff; color: #fff;
} }
border-right: 1px solid transparent; border-right: 1px solid transparent;
} }
} }
} }
} }
@ -94,93 +112,112 @@
border: 1px @LDarkMode-color solid; border: 1px @LDarkMode-color solid;
height: 100%; height: 100%;
z-index: 50; z-index: 50;
:global { :global {
.ant-menu-dark { .ant-menu-dark {
background-color: @LDarkMode-backgroud; background-color: @LDarkMode-backgroud;
color: @LDarkMode-color; color: @LDarkMode-color;
} }
.ant-menu-light {
background-color: @LLightMode-backgroud; .ant-menu-light {
color: @LLightMode-color; background-color: @LLightMode-backgroud;
color: @LLightMode-color;
} }
} }
.menuItems{
.menuItems {
background-color: transparent; background-color: transparent;
margin-bottom: 8px; margin-bottom: 8px;
width: 100%; width: 100%;
animation: fadein 0.5s; animation: fadein 0.5s;
:global {
.ant-menu-item-selected{ :global {
background-color: transparent; .ant-menu-item-selected {
} background-color: transparent;
} }
}
} }
.menuItemsCollapsed{
.menuItemsCollapsed {
background-color: transparent; background-color: transparent;
color: @LDarkMode-color; color: @LDarkMode-color;
width: 100%; width: 100%;
animation: fadein 0.5s; animation: fadein 0.5s;
:global {
.ant-menu-item { :global {
padding: 0 !important; .ant-menu-item {
margin: 2px 0 2px 0; padding: 0 !important;
width: 100%; margin: 2px 0 2px 0;
text-align: center; width: 100%;
font-size: 20px; text-align: center;
} font-size: 20px;
.ant-menu-item-selected{
background-color: rgba(82, 82, 82, 0.562);
}
} }
.ant-menu-item-selected {
background-color: rgba(82, 82, 82, 0.562);
}
}
} }
.chatContainer { .chatContainer {
height: 100%; height: 100%;
margin: 18px 0 8px 0; margin: 18px 0 8px 0;
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
} }
overflow-x: hidden; overflow-x: hidden;
flex: 1; flex: 1;
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: transparent; background-color: transparent;
} }
&:hover { &:hover {
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: rgba(59, 59, 59, 0.2); background-color: rgba(59, 59, 59, 0.2);
} }
} }
:global { :global {
.ant-layout-sider-children { .ant-layout-sider-children {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
} }
.ant-layout-sider-collapsed { .ant-layout-sider-collapsed {
.ant-menu-item { .ant-menu-item {
left: 0; left: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.ant-menu-inline-collapsed > .ant-menu-item{
.ant-menu-inline-collapsed>.ant-menu-item {
padding: 0; padding: 0;
left:0; left: 0;
} }
} }
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
} }
.ant-menu-inline .ant-menu-item { .ant-menu-inline .ant-menu-item {
font-size: 14px; font-size: 14px;
font-family: 'Source Sans Pro', sans-serif; font-family: 'Source Sans Pro', sans-serif;
} }
.ant-menu-dark .ant-menu-item a { .ant-menu-dark .ant-menu-item a {
color: rgb(197, 197, 197); color: rgb(197, 197, 197);
} }
} }
} }
} }
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
@ -197,7 +234,8 @@
opacity: 1; opacity: 1;
} }
} }
.search{
.search {
position: relative; position: relative;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
@ -205,10 +243,9 @@
} }
.chatbox{ .chatbox {
width:100%; width: 100%;
background: transparent; background: transparent;
border-radius:6px; border-radius: 6px;
height:100%; height: 100%;
} }

View File

@ -3,63 +3,65 @@ import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import styles from './Control.less' import styles from './Control.less'
import Radium, {StyleRoot}from 'radium'; import Radium, { StyleRoot } from 'radium'
import { fadeInUp, bounceOutDown } from 'react-animations' import { fadeInUp, bounceOutDown } from 'react-animations'
const animationStyles = { const animationStyles = {
fadeInUp: { fadeInUp: {
animation: 'x 0.5s', animation: 'x 0.5s',
animationName: Radium.keyframes(fadeInUp, 'fadeInUp') animationName: Radium.keyframes(fadeInUp, 'fadeInUp'),
}, },
bounceOutDown: { bounceOutDown: {
animation: 'x 1s', animation: 'x 1s',
animationName: Radium.keyframes(bounceOutDown, 'bounceOutDown') animationName: Radium.keyframes(bounceOutDown, 'bounceOutDown'),
} },
} }
export function SetControls(e){ export function SetControls(e) {
window.ControlComponent.DummySetControls(e); window.ControlComponent.DummySetControls(e)
return return
} }
export function CloseControls(){ export function CloseControls() {
window.ControlComponent.DummyCloseControls(); window.ControlComponent.DummyCloseControls()
return return
} }
class Control extends React.Component { class Control extends React.Component {
constructor(props){ constructor(props) {
super(props) super(props)
window.ControlComponent = this; window.ControlComponent = this
this.state = { this.state = {
Show: false, Show: false,
FadeIN: true, FadeIN: true,
}
} }
DummySetControls = (e) =>{ }
ycore.yconsole.log('Controls recived => ', e) DummySetControls = e => {
if (this.state.Show == false) { ycore.yconsole.log('Controls recived => ', e)
this.setState({ FadeIN: true }) if (this.state.Show == false) {
} this.setState({ FadeIN: true })
this.setState({Show: true, RenderFragment: e})
}
DummyCloseControls(){
ycore.yconsole.log('Closing Control Bar...')
this.setState({FadeIN: false})
setTimeout(() => this.setState({ Show: false, RenderFragment: null}), 1000)
}
render(){
const {RenderFragment, Show, FadeIN} = this.state
return(
Show? (
<StyleRoot>
<div style={FadeIN? animationStyles.fadeInUp : animationStyles.bounceOutDown }>
<antd.Card bordered={false} className={styles.ControlCard}>
<React.Fragment >{RenderFragment}</React.Fragment>
</antd.Card>
</div>
</StyleRoot>
) : null
)
} }
this.setState({ Show: true, RenderFragment: e })
}
DummyCloseControls() {
ycore.yconsole.log('Closing Control Bar...')
this.setState({ FadeIN: false })
setTimeout(() => this.setState({ Show: false, RenderFragment: null }), 1000)
}
render() {
const { RenderFragment, Show, FadeIN } = this.state
return Show ? (
<StyleRoot>
<div
style={
FadeIN ? animationStyles.fadeInUp : animationStyles.bounceOutDown
}
>
<antd.Card bordered={false} className={styles.ControlCard}>
<React.Fragment>{RenderFragment}</React.Fragment>
</antd.Card>
</div>
</StyleRoot>
) : null
}
} }
export default Control; export default Control

View File

@ -1,22 +1,25 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.ControlCard{
background-color: rgba(0, 0, 0, 0.1); .ControlCard {
width: auto; background-color: rgba(0, 0, 0, 0.1);
max-width: 60%; width: auto;
padding: 0 5px 0 5px; max-width: 60%;
margin: 0 0 0 50%; padding: 0 5px 0 5px;
height: auto; margin: 0 0 0 50%;
position: absolute; height: auto;
z-index: 10000; position: absolute;
bottom: 0; z-index: 10000;
text-align: center; bottom: 0;
:global { text-align: center;
.ant-card-body {
padding: 5px; :global {
} .ant-card-body {
.ant-btn { padding: 5px;
background-color: rgba(0, 0, 0, 0.1);
margin: 3px;
}
} }
.ant-btn {
background-color: rgba(0, 0, 0, 0.1);
margin: 3px;
}
}
} }

View File

@ -5,115 +5,133 @@ import * as Icons from '@ant-design/icons'
import styles from './index.less' import styles from './index.less'
import classnames from 'classnames' import classnames from 'classnames'
import {__priPost, __secComments} from './renders.js' import { __priPost, __secComments } from './renders.js'
export const SwapMode = { export const SwapMode = {
close: () => { close: () => {
SecondaryLayoutComponent.closeSwap() SecondaryLayoutComponent.closeSwap()
}, },
openPost: (a, b) => { openPost: (a, b) => {
SecondaryLayoutComponent.setState({ SecondaryLayoutComponent.setState({
swap: true, swap: true,
mode: 'post', mode: 'post',
global_raw: a, global_raw: a,
}) })
} },
} }
export default class Secondary extends React.PureComponent{ export default class Secondary extends React.PureComponent {
constructor(props){ constructor(props) {
super(props), super(props), (window.SecondaryLayoutComponent = this)
window.SecondaryLayoutComponent = this; this.state = {
this.state = { swap: false,
swap: false, mode: '',
mode: '', global_raw: '',
global_raw: '', pri_raw: '',
pri_raw: '', sec_raw: '',
sec_raw: '',
}
} }
}
closeSwap(){
this.setState({ closeSwap() {
swap: !this.state.swap, this.setState({
pri_raw: null, swap: !this.state.swap,
sec_raw: null, pri_raw: null,
mode: '' sec_raw: null,
}) mode: '',
})
}
SwapBalanceContent(container) {
switch (container) {
case '__pri': {
return this.__pri()
}
case '__sec': {
return this.__sec()
}
default:
return null
} }
}
SwapBalanceContent(container){ __pri() {
switch (container){ const dtraw = this.state.pri_raw
case '__pri': { switch (this.state.mode) {
return this.__pri() case 'post': {
} return this.renderPost(this.state.global_raw)
case '__sec': { }
return this.__sec() default:
} return null
default: return null
}
} }
}
__pri(){ __sec() {
const dtraw = this.state.pri_raw; const dtraw = this.state.sec_raw
switch (this.state.mode){ switch (this.state.mode) {
case 'post': { case 'post': {
return this.renderPost(this.state.global_raw) return this.renderComments(this.state.global_raw)
} }
default: return null default:
} return null
}
__sec(){
const dtraw = this.state.sec_raw;
switch (this.state.mode){
case 'post': {
return this.renderComments(this.state.global_raw)
}
default: return null
}
} }
}
renderPost = (payload) => { renderPost = payload => {
const post_data = JSON.parse(payload)['post_data'] const post_data = JSON.parse(payload)['post_data']
console.log(post_data) console.log(post_data)
return( return <__priPost payload={post_data} />
<__priPost payload={post_data} /> }
)
}
renderComments = (payload) => { renderComments = payload => {
const post_comments = JSON.parse(payload)['post_comments'] const post_comments = JSON.parse(payload)['post_comments']
const post_data = JSON.parse(payload)['post_data'] const post_data = JSON.parse(payload)['post_data']
console.log(post_comments) console.log(post_comments)
return( return <__secComments post_id={post_data.post_id} payload={post_comments} />
<__secComments post_id={post_data.post_id} payload={post_comments} /> }
)
}
render() {
const { userData } = this.props
return (
<div
className={classnames(styles.SecondaryWrapper, {
[styles.active]: this.state.swap,
})}
>
<div className={styles.UserHeader}>
<div className={styles.notif_box}></div>
<img
onClick={() => ycore.crouter.native(`@${userData.username}`)}
src={userData.avatar}
/>
</div>
render(){ <div
const { userData } = this.props className={classnames(styles.container, {
return( [styles.desktop_mode]: this.props.desktop_mode,
<div className={classnames(styles.SecondaryWrapper, {[styles.active]: this.state.swap })}> })}
>
<div className={styles.UserHeader}> <div className={styles.container_body}>
<div className={styles.notif_box}></div> {this.state.swap ? (
<img onClick={() => ycore.crouter.native(`@${userData.username}`)} src={userData.avatar} /> <antd.Button
</div> type="ghost"
icon={<Icons.LeftOutlined />}
onClick={() => this.closeSwap()}
>
{' '}
Back{' '}
</antd.Button>
) : null}
{this.SwapBalanceContent('__pri')}
</div>
</div>
<div className={classnames(styles.container, {[styles.desktop_mode]: this.props.desktop_mode})} > <div
<div className={styles.container_body}> className={classnames(styles.container_2, {
{this.state.swap? <antd.Button type="ghost" icon={<Icons.LeftOutlined />} onClick={() => this.closeSwap()} > Back </antd.Button> : null} [styles.active]: this.state.swap,
{this.SwapBalanceContent('__pri')} })}
</div> >
</div> {this.SwapBalanceContent('__sec')}
</div>
<div className={classnames(styles.container_2, {[styles.active]: this.state.swap})}> </div>
{this.SwapBalanceContent('__sec')} )
</div> }
}
</div>
)
}
}

View File

@ -1,110 +1,120 @@
@SwapAnimDuration: 340ms; @SwapAnimDuration: 340ms;
.SecondaryWrapper{ .SecondaryWrapper {
width: 27%; width: 27%;
height: 100vh; height: 100vh;
position: relative;
float: left;
overflow-y: hidden !important;
overflow-x: hidden;
display: flex; position: relative;
float: left;
overflow-y: hidden !important;
overflow-x: hidden;
&.active{ display: flex;
width: 96vw;
position: absolute; &.active {
right: 0; width: 96vw;
>.container{ position: absolute;
border-radius: 12px 12px 12px 12px; right: 0;
}
>.container {
border-radius: 12px 12px 12px 12px;
} }
}
transition: all @SwapAnimDuration ease-in-out;
transition: all @SwapAnimDuration ease-in-out;
}
.UserHeader {
right: 20px;
top: 25px;
display: flex;
position: absolute;
z-index: 52;
img {
border-radius: 15px;
width: 40px;
transition: all 150ms linear;
box-shadow: 0px 0px 0 0px rgba(255, 255, 255, 0);
} }
.UserHeader{ img:hover {
right: 20px; box-shadow: 0px 0px 10px 0px rgba(255, 255, 255, 0.205);
top: 25px; transition: all 150ms linear;
display: flex; }
position: absolute;
z-index: 52; transition: all 150ms linear;
img {
border-radius: 15px; .notif_box {
width: 40px; margin: 0 15px 0 5px;
transition: all 150ms linear; width: 40px;
box-shadow: 0px 0px 0 0px rgba(255, 255, 255, 0); height: 40px;
border-radius: 15px;
background-color: #78CFED;
}
}
.container {
z-index: 50;
position: relative;
background-color: #201F23;
color: @DarkMode-color_container !important;
&.desktop_mode {
border-radius: 0 12px 12px 0;
}
width: 100%;
height: 100vh;
:global {
h1 {
color: @DarkMode-color_container;
} }
img:hover{
.ant-btn {
color: #ffffff;
background-color: #4c4c4c;
border-color: transparent;
border-radius: 12px;
}
.ant-btn:hover {
box-shadow: 0px 0px 10px 0px rgba(255, 255, 255, 0.205); box-shadow: 0px 0px 10px 0px rgba(255, 255, 255, 0.205);
transition: all 150ms linear; transition: all 150ms linear;
} }
transition: all 150ms linear;
.notif_box {
margin: 0 15px 0 5px;
width: 40px;
height: 40px;
border-radius: 15px;
background-color: #78CFED;
}
} }
.container{ }
z-index: 50;
position: relative; .container_body {
background-color: #201F23; padding: 30px 375px 30px 75px;
color: @DarkMode-color_container !important; }
&.desktop_mode{
border-radius: 0 12px 12px 0; .container_2 {
} z-index: 51;
width: 100%;
height: 100vh; background-color: #fff;
:global{ border-radius: 32px 0 0 32px;
h1{ padding: 20px 15px 15px 15px;
color: @DarkMode-color_container;
} width: 0;
.ant-btn{ height: 100vh;
color: #ffffff; opacity: 0;
background-color: #4c4c4c;
border-color: transparent; position: absolute;
border-radius: 12px; right: -500px;
}
.ant-btn:hover{ &.active {
box-shadow: 0px 0px 10px 0px rgba(255, 255, 255, 0.205); width: 300px;
transition: all 150ms linear; opacity: 1;
} right: 0;
}
}
.container_body{
padding: 30px 375px 30px 75px;
} }
.container_2{ transition: all @SwapAnimDuration ease-in-out;
z-index: 51; }
background-color: #fff; .comments_body {}
border-radius: 32px 0 0 32px;
padding: 20px 15px 15px 15px;
width: 0;
height: 100vh;
opacity: 0;
position: absolute;
right: -500px;
&.active{
width: 300px;
opacity: 1;
right: 0;
}
transition: all @SwapAnimDuration ease-in-out;
}
.comments_body{
}

View File

@ -6,151 +6,196 @@ import * as ycore from 'ycore'
import * as Icons from '@ant-design/icons' import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import {MediaPlayer, PostCard} from 'components' import { MediaPlayer, PostCard } from 'components'
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>) 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 class __priPost extends React.Component{ export class __priPost extends React.Component {
renderContent(payload) {
renderContent(payload){ const { id, postText, postFile_full, post_time, publisher } = payload
const { id, postText, postFile_full, post_time, publisher} = payload if (!postFile_full) {
if (!postFile_full) { return (
return( <div className={styles.postContent_OnlyText}>
<div className={styles.postContent_OnlyText}> <PostCard payload={payload} />
<PostCard payload={payload} /> </div>
</div> )
)
}
return (
<div className={styles.contentWrapper}>
{postFile_full? <MediaPlayer file={postFile_full} /> : null}
{postText? <div className={styles.postContent}> <h3 dangerouslySetInnerHTML={{__html: postText }} /> </div> : null}
</div>
)
} }
return (
<div className={styles.contentWrapper}>
{postFile_full ? <MediaPlayer file={postFile_full} /> : null}
{postText ? (
<div className={styles.postContent}>
{' '}
<h3 dangerouslySetInnerHTML={{ __html: postText }} />{' '}
</div>
) : null}
</div>
)
}
render() {
render(){ const payload = this.props.payload
const payload = this.props.payload if (!payload) {
if (!payload) { return <h1>This post not exists!!!</h1>
return (
<h1>This post not exists!!!</h1>
)
}
const { id, postText, postFile_full, post_time, publisher} = payload
return(
<div className={styles.SecondaryBody}>
<div className={styles.UserContainer}>
<div className={styles.UserContainer_text}>
<h4 className={styles.titleUser}>{publisher.username} {ycore.booleanFix(publisher.verified)? <Icon style={{ color: 'blue' }} component={VerifiedBadge} /> : null}</h4>
<p> {post_time} {ycore.IsThisUser.dev()? `| #${id}` : null} </p>
</div>
<antd.Avatar shape="square" size={50} src={publisher.avatar} />
</div>
{this.renderContent(payload)}
</div>
)
} }
const { id, postText, postFile_full, post_time, publisher } = payload
return (
<div className={styles.SecondaryBody}>
<div className={styles.UserContainer}>
<div className={styles.UserContainer_text}>
<h4 className={styles.titleUser}>
{publisher.username}{' '}
{ycore.booleanFix(publisher.verified) ? (
<Icon style={{ color: 'blue' }} component={VerifiedBadge} />
) : null}
</h4>
<p>
{' '}
{post_time} {ycore.IsThisUser.dev() ? `| #${id}` : null}{' '}
</p>
</div>
<antd.Avatar shape="square" size={50} src={publisher.avatar} />
</div>
{this.renderContent(payload)}
</div>
)
}
} }
export class __secComments extends React.Component { export class __secComments extends React.Component {
state = { state = {
comment_data: this.props.payload, comment_data: this.props.payload,
raw_comment: '', raw_comment: '',
loading: false loading: false,
} }
handleDeleteComment(id){ handleDeleteComment(id) {
console.log(`Removing Comment with id => ${id}`) console.log(`Removing Comment with id => ${id}`)
ycore.Post_Comments.delete((err, res) => { if(err){return false} return this.reloadComments() }, {comment_id: id}) ycore.comty_post_comment.delete(
} (err, res) => {
handleNewComment(){ if (err) {
const { raw_comment } = this.state return false
const { post_id } = this.props
if (raw_comment) {
const payload = { post_id: post_id, raw_text: raw_comment }
ycore.Post_Comments.new((err,res) =>{
if (err) {
ycore.notify.error('This action could not be performed.', err)
}
this.setState({ raw_comment: '' })
return this.reloadComments()
}, payload)
} }
return false return this.reloadComments()
} },
{ comment_id: id }
renderComment = (a) => { )
const {id, time, Orginaltext, publisher} = a }
const CommentMenu = ( handleNewComment() {
<antd.Menu> const { raw_comment } = this.state
<antd.Menu.Item key="remove_comment" onClick={()=> this.handleDeleteComment(id)}><Icons.DeleteOutlined /> Delete</antd.Menu.Item> const { post_id } = this.props
</antd.Menu> if (raw_comment) {
); const payload = { post_id: post_id, raw_text: raw_comment }
return ( ycore.comty_post_comment.new((err, res) => {
<div className={styles.comment_card}> if (err) {
<div className={styles.comment_title}> ycore.notify.error('This action could not be performed.', err)
<img src={publisher.avatar} />
<p className={styles.comment_user_username}>@{publisher.username} {ycore.booleanFix(publisher.verified)? <Icon style={{ color: 'black' }} component={VerifiedBadge} /> : null}</p>
<antd.Dropdown disabled={ycore.IsThisPost.owner(publisher.id)? false : true} overlay={CommentMenu} trigger={['click']}>
<p onClick={e => e.preventDefault()} className={styles.comment_user_ago}>{ycore.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 }
ycore.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
} }
this.setState({ raw_comment: '' })
return this.reloadComments()
}, payload)
} }
return false
}
renderComment = a => {
render(){ const { id, time, Orginaltext, publisher } = a
const {comment_data, loading} = this.state const CommentMenu = (
<antd.Menu>
return( <antd.Menu.Item
<div className={styles.comments_body}> key="remove_comment"
<div className={styles.comments_body_title}> onClick={() => this.handleDeleteComment(id)}
<h1>Comments ({comment_data.length})</h1> >
</div> <Icons.DeleteOutlined /> Delete
<div className={styles.comments_cards_wrapper}> </antd.Menu.Item>
{loading? <antd.Skeleton active/> : </antd.Menu>
<antd.List )
itemLayout="horizontal" return (
dataSource={comment_data} <div className={styles.comment_card}>
renderItem={item => ( <div className={styles.comment_title}>
this.renderComment(item) <img src={publisher.avatar} />
)} <p className={styles.comment_user_username}>
/> @{publisher.username}{' '}
} {ycore.booleanFix(publisher.verified) ? (
</div> <Icon style={{ color: 'black' }} component={VerifiedBadge} />
<div className={styles.comment_box}> ) : null}
<div className={styles.comment_box_body}> </p>
<antd.Input value={this.state.raw_comment} onPressEnter={() => this.handleNewComment()} placeholder="Write a comment..." allowClear onChange={this.HandleCommentInput} /> <antd.Dropdown
</div> disabled={ycore.IsThisPost.owner(publisher.id) ? false : true}
</div> overlay={CommentMenu}
trigger={['click']}
>
</div> <p
) onClick={e => e.preventDefault()}
className={styles.comment_user_ago}
>
{ycore.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 }
ycore.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,189 +1,223 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.SecondaryBody{ .SecondaryBody {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.UserContainer{ .UserContainer {
display: flex; display: flex;
position: relative; position: relative;
float: right; float: right;
z-index: 150; z-index: 150;
transform: translate(0, -40px); transform: translate(0, -40px);
.UserContainer_text{
margin: 0 8px; .UserContainer_text {
h4 { text-align: right; } margin: 0 8px;
p { word-break: break-all; text-align: right; font-size: 11px; color: #eeeeee!important; }
h4 {
text-align: right;
} }
} p {
word-break: break-all;
.postAvatar{ text-align: right;
position: absolute; font-size: 11px;
left: -8px; color: #eeeeee !important;
top: -8px;
display: flex;
}
.titleUser{
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
color: #ffffff!important;
}
.textAgo{
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags{
float: right;
width: 100%;
z-index: 10;
:global {
.anticon{
color:rgb(249, 179, 64);
float: right;
margin: -0 6px 0 0;;
font-size: 17px;
}
.MoreMenu{
color: #2d2d2d !important;
}
} }
}
} }
.titleWrapper{
display: flex; .postAvatar {
h4{ position: absolute;
cursor: pointer; left: -8px;
top: -8px;
display: flex;
}
.titleUser {
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
color: #ffffff !important;
}
.textAgo {
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags {
float: right;
width: 100%;
z-index: 10;
:global {
.anticon {
color: rgb(249, 179, 64);
float: right;
margin: -0 6px 0 0;
;
font-size: 17px;
} }
color: #ffffff!important;
} .MoreMenu {
.contentWrapper{ color: #2d2d2d !important;
margin: auto;
width: 100%;
padding: 20px;
}
.postContent{
word-break: break-all;
position: absolute;
vertical-align: bottom;
border-radius: 7px;
bottom: 0;
max-width: 50vw;
background-color: #2d2d2d4b;
padding: 10px;
h3{
font-family: "Poppins", sans-serif;
color: #ffffff;
font-weight: 400;
font-size: 15px;
letter-spacing: -0.3px;
} }
}
} }
.postContent_OnlyText{
padding: 25% 0 0 0; .titleWrapper {
position: relative; display: flex;
vertical-align: middle;
h4 {
cursor: pointer;
}
color: #ffffff !important;
} }
.contentWrapper {
.likebtn{ margin: auto;
:global{ width: 100%;
svg{ padding: 20px;
color:rgba(0, 0, 0, 0.45);
}
svg:hover{
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
} }
.comments_body{
.postContent {
word-break: break-all;
position: absolute;
vertical-align: bottom;
border-radius: 7px;
bottom: 0;
max-width: 50vw;
background-color: #2d2d2d4b;
padding: 10px;
h3 {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
padding: 75px 10px 10px 20px; color: #ffffff;
font-weight: 400;
.comments_body_title{ font-size: 15px;
font-size: 12px; letter-spacing: -0.3px;
h1{ }
font-weight: 550; }
letter-spacing: 0.01px;
}
}
.comments_cards_wrapper{ .postContent_OnlyText {
z-index: 50; padding: 25% 0 0 0;
overflow: scroll; position: relative;
:global{ vertical-align: middle;
overflow: scroll;
}
.comment_card{
position: relative;
width: 100%;
background-color: #ffffff;
word-break: break-all;
.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_text{
margin: 10px 0 0 0;
}
}
}
.comment_box{
width: 100%;
bottom: 0;
right: 0;
position: absolute;
z-index: 100;
background-color: #ffffffd7;
padding-top: 20px;
padding-bottom: 40px;
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;
}
}
}
}
} }
.likebtn {
:global {
svg {
color: rgba(0, 0, 0, 0.45);
}
svg:hover {
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
}
.comments_body {
font-family: "Poppins", sans-serif;
padding: 75px 10px 10px 20px;
.comments_body_title {
font-size: 12px;
h1 {
font-weight: 550;
letter-spacing: 0.01px;
}
}
.comments_cards_wrapper {
z-index: 50;
overflow: scroll;
:global {
overflow: scroll;
}
.comment_card {
position: relative;
width: 100%;
background-color: #ffffff;
word-break: break-all;
.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_text {
margin: 10px 0 0 0;
}
}
}
.comment_box {
width: 100%;
bottom: 0;
right: 0;
position: absolute;
z-index: 100;
background-color: #ffffffd7;
padding-top: 20px;
padding-bottom: 40px;
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

@ -2,46 +2,46 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import { withI18n, Trans } from '@lingui/react' import { withI18n, Trans } from '@lingui/react'
import ScrollBar from '../ScrollBar' import ScrollBar from '../ScrollBar'
import { config } from 'utils' import { config } from 'utils'
import styles from './Sider.less' import styles from './Sider.less'
import * as ycore from 'ycore'; import * as ycore from 'ycore'
import router from 'umi/router'; import router from 'umi/router'
import {CustomIcons} from 'components' import { CustomIcons } from 'components'
@withI18n() @withI18n()
class Sider extends PureComponent { class Sider extends PureComponent {
constructor(props) { constructor(props) {
super(props); super(props)
this.state = { this.state = {
isHover: false, isHover: false,
collapsedWidth: '30', collapsedWidth: '30',
}; }
} }
StrictMode = () =>{ StrictMode = () => {
const { theme } = this.props; const { theme } = this.props
if (ycore.AppSettings.StrictLightMode == false) { if (ycore.AppSettings.StrictLightMode == false) {
return "dark" return 'dark'
} }
return theme return theme
} }
handleClickMenu = e => { handleClickMenu = e => {
e.key === 'SignOut' && ycore.LogoutCall() e.key === 'SignOut' && ycore.app_session.logout()
e.key === 'general_settings' && ycore.crouter.native('settings') e.key === 'general_settings' && ycore.crouter.native('settings')
e.key === 'accountpage' && router.push('/account') e.key === 'accountpage' && router.push('/account')
e.key === 'explore' && router.push('main') e.key === 'explore' && router.push('main')
e.key === 'admin_area' && router.push('__m') e.key === 'admin_area' && router.push('__m')
} }
isDarkMode(){ isDarkMode() {
const { theme } = this.props const { theme } = this.props
if (theme == 'dark'){ if (theme == 'dark') {
return true return true
} }
return false return false
@ -56,82 +56,143 @@ class Sider extends PureComponent {
onCollapseChange, onCollapseChange,
} = this.props } = this.props
return ( return (
<div className={styles.siderwrapper}> <div className={styles.siderwrapper}>
<antd.Layout.Sider <antd.Layout.Sider
breakpoint="lg" breakpoint="lg"
trigger={null} trigger={null}
collapsible collapsible
defaultCollapsed="true" defaultCollapsed="true"
collapsedWidth={this.state.collapsedWidth} collapsedWidth={this.state.collapsedWidth}
theme={this.StrictMode()} theme={this.StrictMode()}
width="180" width="180"
collapsed={collapsed} collapsed={collapsed}
className={classnames(styles.sider, {[styles.darkmd]: this.isDarkMode(), [styles.desktop_mode]: this.props.desktop_mode} )} className={classnames(styles.sider, {
onMouseEnter={() => this.setState({ collapsedWidth: '90' })} [styles.darkmd]: this.isDarkMode(),
onMouseLeave={() => this.setState({ collapsedWidth: '35' })} [styles.desktop_mode]: this.props.desktop_mode,
> })}
<div className={styles.brand}><img onClick={() => ycore.crouter.native('main')} src={collapsed? config.LogoPath : config.FullLogoPath } /></div> onMouseEnter={() => this.setState({ collapsedWidth: '90' })}
<div className={this.StrictMode()? styles.CollapserWrapperLight : styles.CollapserWrapperDark} ><antd.Button width={'20px'} onClick={() => onCollapseChange(!collapsed)} icon={collapsed? <Icons.RightOutlined/> : <Icons.DoubleLeftOutlined/> } /></div> onMouseLeave={() => this.setState({ collapsedWidth: '35' })}
<div className={styles.menuContainer}> >
<ScrollBar options={{ suppressScrollX: true, }} > <div className={styles.brand}>
<antd.Menu className={collapsed? styles.menuItemsCollapsed : styles.menuItems} mode="vertical" onClick={this.handleClickMenu}> <img
<antd.Menu.Item key="explore"> onClick={() => ycore.crouter.native('main')}
<Icons.CompassOutlined /> src={collapsed ? config.LogoPath : config.FullLogoPath}
<Trans><span>Explore</span></Trans> />
</antd.Menu.Item> </div>
<div
className={
this.StrictMode()
? styles.CollapserWrapperLight
: styles.CollapserWrapperDark
}
>
<antd.Button
width={'20px'}
onClick={() => onCollapseChange(!collapsed)}
icon={
collapsed ? (
<Icons.RightOutlined />
) : (
<Icons.DoubleLeftOutlined />
)
}
/>
</div>
<div className={styles.menuContainer}>
<ScrollBar options={{ suppressScrollX: true }}>
<antd.Menu
className={
collapsed ? styles.menuItemsCollapsed : styles.menuItems
}
mode="vertical"
onClick={this.handleClickMenu}
>
<antd.Menu.Item key="explore">
<Icons.CompassOutlined />
<Trans>
<span>Explore</span>
</Trans>
</antd.Menu.Item>
<antd.Menu.Item key="journal_page"> <antd.Menu.Item key="journal_page">
<Icons.ReadOutlined /> <Icons.ReadOutlined />
<Trans><span>Journal</span></Trans> <Trans>
</antd.Menu.Item> <span>Journal</span>
</Trans>
<antd.Menu.Item key="marketplace_page"> </antd.Menu.Item>
<Icons.ReconciliationOutlined />
<Trans><span>Marketplace</span></Trans> <antd.Menu.Item key="marketplace_page">
</antd.Menu.Item> <Icons.ReconciliationOutlined />
<Trans>
<span>Marketplace</span>
</antd.Menu> </Trans>
</antd.Menu.Item>
<div className={styles.something_thats_pulling_me_down}> </antd.Menu>
<antd.Menu selectable={false} className={collapsed ? styles.menuItemsCollapsed : styles.menuItems} mode="vertical" onClick={this.handleClickMenu}>
<div className={styles.something_thats_pulling_me_down}>
<antd.Menu.Item key="general_settings"> <antd.Menu
<Icons.SettingOutlined/> selectable={false}
<Trans><span>Settings</span></Trans> className={
</antd.Menu.Item> collapsed ? styles.menuItemsCollapsed : styles.menuItems
{ycore.booleanFix(userData.admin)? }
<antd.Menu.Item key="admin_area"> mode="vertical"
<Icons.ThunderboltOutlined /> onClick={this.handleClickMenu}
<Trans><span>{userData.username}</span></Trans> >
</antd.Menu.Item> <antd.Menu.Item key="general_settings">
: <Icons.SettingOutlined />
undefined <Trans>
} <span>Settings</span>
<antd.Menu.Item style={{ fontSize: '15px' }} key="LightMode" disabled={false} > </Trans>
{collapsed? <Icons.BulbOutlined /> : </antd.Menu.Item>
<div className={styles.themeSwitcher}> {ycore.booleanFix(userData.admin) ? (
<antd.Switch <antd.Menu.Item key="admin_area">
onChange={onThemeChange.bind( <Icons.ThunderboltOutlined />
this, <Trans>
theme === 'light' ? 'dark' : 'light' <span>{userData.username}</span>
)} </Trans>
checkedChildren={<CustomIcons.MoonSVG style={{ vertialAlign: 'middle'}} />} </antd.Menu.Item>
unCheckedChildren={<CustomIcons.SunSVG style={{ vertialAlign: 'middle'}}/>} ) : (
defaultChecked={theme === 'dark'} undefined
/> )}
</div>} <antd.Menu.Item
</antd.Menu.Item> style={{ fontSize: '15px' }}
<antd.Menu.Item key="SignOut"> key="LightMode"
<Icons.LogoutOutlined style={{ color: 'red' }} /> disabled={false}
{collapsed ? null : <Trans>Logout</Trans>} >
</antd.Menu.Item> {collapsed ? (
</antd.Menu> <Icons.BulbOutlined />
</div> ) : (
<div className={styles.themeSwitcher}>
<antd.Switch
onChange={onThemeChange.bind(
this,
theme === 'light' ? 'dark' : 'light'
)}
checkedChildren={
<CustomIcons.MoonSVG
style={{ vertialAlign: 'middle' }}
/>
}
unCheckedChildren={
<CustomIcons.SunSVG
style={{ vertialAlign: 'middle' }}
/>
}
defaultChecked={theme === 'dark'}
/>
</div>
)}
</antd.Menu.Item>
<antd.Menu.Item key="SignOut">
<Icons.LogoutOutlined style={{ color: 'red' }} />
{collapsed ? null : <Trans>Logout</Trans>}
</antd.Menu.Item>
</antd.Menu>
</div>
</ScrollBar> </ScrollBar>
</div> </div>
</antd.Layout.Sider> </antd.Layout.Sider>
</div> </div>
) )
} }
} }

View File

@ -6,16 +6,17 @@
@LDarkMode-color: #fff; @LDarkMode-color: #fff;
@LLightMode-color: #2F2E30; @LLightMode-color: #2F2E30;
.CollapserWrapperLight{ .CollapserWrapperLight {
height: 100%; height: 100%;
position: absolute; position: absolute;
float: left; float: left;
top: 0; top: 0;
left: 0; left: 0;
z-index: 200; z-index: 200;
vertical-align: middle; vertical-align: middle;
:global{
:global {
.ant-btn { .ant-btn {
border: none; border: none;
border-radius: unset; border-radius: unset;
@ -27,23 +28,25 @@
box-shadow: none; box-shadow: none;
transition: all 1s ease-in; transition: all 1s ease-in;
} }
.ant-btn:hover{
.ant-btn:hover {
background: rgba(121, 121, 121, 0.247); background: rgba(121, 121, 121, 0.247);
background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(252, 252, 252, 0.13) 95%); background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(252, 252, 252, 0.13) 95%);
transition: all 1s ease-in; transition: all 1s ease-in;
} }
} }
} }
.CollapserWrapperDark{ .CollapserWrapperDark {
height: 100%; height: 100%;
position: absolute; position: absolute;
float: left; float: left;
top: 0; top: 0;
left: 0; left: 0;
z-index: 200; z-index: 200;
vertical-align: middle; vertical-align: middle;
:global{
:global {
.ant-btn { .ant-btn {
border: none; border: none;
border-radius: unset; border-radius: unset;
@ -55,17 +58,19 @@
box-shadow: none; box-shadow: none;
transition: all 1s ease-in; transition: all 1s ease-in;
} }
.ant-btn:hover{
.ant-btn:hover {
background: rgba(121, 121, 121, 0.247); background: rgba(121, 121, 121, 0.247);
background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(121, 121, 121, 0.13) 95%); background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(121, 121, 121, 0.13) 95%);
transition: all 1s ease-in; transition: all 1s ease-in;
} }
} }
} }
.brand { .brand {
cursor: pointer; cursor: pointer;
img{
img {
display: flex; display: flex;
vertical-align: middle; vertical-align: middle;
padding: 5px; padding: 5px;
@ -76,31 +81,34 @@
} }
.avatarFull{ .avatarFull {
width: 120px; width: 120px;
} }
.avatar{ .avatar {
margin: 0 0 15px 0; margin: 0 0 15px 0;
} }
.something_thats_pulling_me_down{ .something_thats_pulling_me_down {
:global{ :global {
text-align: center; text-align: center;
bottom: 0; bottom: 0;
position: absolute; position: absolute;
width: 100%; width: 100%;
} }
} }
.siderhead{
.siderhead {
cursor: pointer; cursor: pointer;
font-family: 'Source Sans Pro', sans-serif; font-family: 'Source Sans Pro', sans-serif;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
::first-letter{
::first-letter {
margin-left: 7px; margin-left: 7px;
} }
height: 60px; height: 60px;
font-size: 17px; font-size: 17px;
} }
@ -113,155 +121,192 @@
z-index: 100; z-index: 100;
float: left; float: left;
position: relative; position: relative;
:global { :global {
.ant-layout-sider-dark { .ant-layout-sider-dark {
background-color: @LDarkMode-backgroud; background-color: @LDarkMode-backgroud;
color: @DarkMode-color; color: @DarkMode-color;
h2{
h2 {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-item{
.ant-menu-item {
color: @DarkMode-color; color: @DarkMode-color;
} }
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
:hover { :hover {
background-color: rgb(80, 80, 80); background-color: rgb(80, 80, 80);
color: #fff; color: #fff;
} }
border-right: 1px solid transparent; border-right: 1px solid transparent;
} }
} }
.ant-layout-sider-light { .ant-layout-sider-light {
background-color: @Theme-SiderDeco-Backgroud; background-color: @Theme-SiderDeco-Backgroud;
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
h2{
h2 {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-item{
.ant-menu-item {
color: @Theme-SiderDeco-Color; color: @Theme-SiderDeco-Color;
} }
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
:hover { :hover {
background-color: @Theme-Hover-Backgroud; background-color: @Theme-Hover-Backgroud;
color: #fff; color: #fff;
} }
border-right: 1px solid transparent; border-right: 1px solid transparent;
} }
} }
} }
} }
.sider { .sider {
border-right: transparent; border-right: transparent;
&.desktop_mode{
&.desktop_mode {
border-radius: 12px 0 0 12px; border-radius: 12px 0 0 12px;
} }
height: 100%; height: 100%;
z-index: 50; z-index: 50;
:global { :global {
.ant-menu-sub { .ant-menu-sub {
font-size: 14px; font-size: 14px;
-webkit-box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005); -webkit-box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005);
-moz-box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005); -moz-box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005);
box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005); box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005);
}
.ant-menu-dark {
background-color: @LDarkMode-backgroud;
color: @LDarkMode-color;
} }
.ant-menu-light {
background-color: @LLightMode-backgroud; .ant-menu-dark {
color: @LLightMode-color; background-color: @LDarkMode-backgroud;
color: @LDarkMode-color;
}
.ant-menu-light {
background-color: @LLightMode-backgroud;
color: @LLightMode-color;
} }
} }
.menuItems{
.menuItems {
background-color: transparent; background-color: transparent;
margin-bottom: 8px; margin-bottom: 8px;
width: 100%; width: 100%;
font-weight: 500; font-weight: 500;
animation: fadein 0.5s; animation: fadein 0.5s;
:global {
.ant-menu-item-selected{ :global {
background-color: transparent; .ant-menu-item-selected {
} background-color: transparent;
.ant-menu-item .anticon, .ant-menu-submenu-title .anticon {
font-weight: 500;
min-width: 14px;
margin: 0 10px 0 10px;
font-size: 16px;
line-height: 1;
}
} }
.ant-menu-item .anticon,
.ant-menu-submenu-title .anticon {
font-weight: 500;
min-width: 14px;
margin: 0 10px 0 10px;
font-size: 16px;
line-height: 1;
}
}
} }
.menuItemsCollapsed{
.menuItemsCollapsed {
background-color: transparent; background-color: transparent;
margin-bottom: 8px; margin-bottom: 8px;
width: 100%; width: 100%;
font-weight: 500; font-weight: 500;
animation: fadein 0.5s; animation: fadein 0.5s;
:global {
.ant-menu-item-selected{ :global {
background-color: transparent; .ant-menu-item-selected {
} background-color: transparent;
.ant-menu-item {
padding: 0 !important;
margin: 2px 0 2px 0;
width: 100%;
text-align: center;
}
} }
.ant-menu-item {
padding: 0 !important;
margin: 2px 0 2px 0;
width: 100%;
text-align: center;
}
}
} }
.menuContainer { .menuContainer {
height: 100%; height: 100%;
margin: 18px 0 8px 0; margin: 18px 0 8px 0;
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
} }
overflow-x: hidden; overflow-x: hidden;
flex: 1; flex: 1;
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: transparent; background-color: transparent;
} }
&:hover { &:hover {
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: rgba(59, 59, 59, 0.2); background-color: rgba(59, 59, 59, 0.2);
} }
} }
:global { :global {
.ant-layout-sider-children { .ant-layout-sider-children {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
} }
.ant-layout-sider-collapsed { .ant-layout-sider-collapsed {
.ant-menu-item { .ant-menu-item {
left: 0; left: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.ant-menu-inline-collapsed > .ant-menu-item{
.ant-menu-inline-collapsed>.ant-menu-item {
padding: 0; padding: 0;
left:0; left: 0;
} }
} }
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
} }
.ant-menu-inline .ant-menu-item { .ant-menu-inline .ant-menu-item {
font-size: 14px; font-size: 14px;
font-family: 'Source Sans Pro', sans-serif; font-family: 'Source Sans Pro', sans-serif;
} }
.ant-menu-dark .ant-menu-item a { .ant-menu-dark .ant-menu-item a {
color: rgb(197, 197, 197); color: rgb(197, 197, 197);
} }
} }
} }
} }
.scrollbar-container { .scrollbar-container {
position: initial; position: initial;
height: 100%; height: 100%;
@ -285,10 +330,12 @@
background-color: #2F2E30; background-color: #2F2E30;
} }
} }
svg { svg {
height: 100%; height: 100%;
vertical-align: middle; vertical-align: middle;
} }
span { span {
line-height: 10px; line-height: 10px;
} }

View File

@ -1,38 +0,0 @@
import React from 'react'
import styles from './WindowAppBar.less'
import * as Icons from '@ant-design/icons'
const remote = {
getCurrentWindow: () =>{
return
},
handleFullRescale: () => {
return
},
app: {
quit: () => {
return
}
}
}
export default class WindowAppBar extends React.PureComponent {
handleFullRescale(){
return
// const currentWindow = remote.getCurrentWindow()
// if(currentWindow.isMaximized()) {
// currentWindow.unmaximize()
// } else {
// currentWindow.maximize()
// }
}
render(){
return(
<div className={styles.WindowAppBar}>
<div className={styles.WindowControl}>
<Icons.MinusOutlined onClick={() => remote.getCurrentWindow().minimize() } id="minimize-button" />
<Icons.FullscreenOutlined onClick={() => this.handleFullRescale()} />
<Icons.CloseOutlined onClick={() => remote.app.quit()} id="close-button" />
</div>
</div>
)
}
}

View File

@ -1,31 +0,0 @@
.WindowAppBar {
-webkit-app-region: drag;
position: relative;
vertical-align: top;
width: 100%;
height: 25px;
z-index: 5000;
background-color: #2d2d2d;
}
.WindowControl {
float: right;
height: 100%;
padding: 0 20px 0 0;
transition: all 140ms linear;
:global {
color: #747474;
.anticon {
margin: 0 15px 0 15px;
display: inline-block;
color: inherit;
font-style: normal;
vertical-align: middle;
text-align: center;
}
}
}
.WindowControl:hover{
:global{
color: #ffffff;
}
}

View File

@ -1,6 +1,5 @@
import Sider from './Sider' import Sider from './Sider'
import Control from './Control' import Control from './Control'
import Secondary from './Secondary/index.js' import Secondary from './Secondary/index.js'
import WindowAppBar from './WindowAppBar'
export { Sider, Control, Secondary,WindowAppBar } export { Sider, Control, Secondary }

View File

@ -1,79 +0,0 @@
import React from 'react'
import styles from './index.scss'
import * as ycore from 'ycore'
import classnames from 'classnames'
class LikeBTN 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
ycore.yconsole.log(`Dispatch ${type} to post id => ${e}`)
this.setState({ clicked: true })
setTimeout(() => {
this.setState({ clicked: false })
}, 500);
ycore.ActionPost('like', e, null, (exception, response) => {
if (exception) {
ycore.notifyError(response)
return
}
if (type == 'like') {
this.SumLike()
}
if (type == 'dislike') {
this.RestLike()
}
})
}
render(){
const { id } = this.props
const { likes, liked, clicked } = this.state
if (!id){
ycore.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 LikeBTN

View File

@ -0,0 +1,106 @@
import React from 'react'
import styles from './index.scss'
import * as ycore from 'ycore'
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
ycore.yconsole.log(`Dispatch ${type} to post id => ${e}`)
this.setState({ clicked: true })
setTimeout(() => {
this.setState({ clicked: false })
}, 500)
const payload = { post_id: e }
ycore.comty_post.like((err, res) => {
if (err) {
ycore.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) {
ycore.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,17 +1,22 @@
.like_button, .like_button:before, .like_button:after { .like_button,
position: relative; .like_button:before,
box-sizing: border-box; .like_button:after {
}
.ripple, .ripple:before, .ripple:after {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
} }
.btnWrapper{ .ripple,
.ripple:before,
.ripple:after {
position: relative;
box-sizing: border-box;
}
.btnWrapper {
display: flex; display: flex;
} }
.likeCounter{ .likeCounter {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
line-height: 70px; line-height: 70px;
margin: 0 0 0 10px; margin: 0 0 0 10px;
@ -20,26 +25,28 @@
transform: perspective(100px) translateZ(10px); transform: perspective(100px) translateZ(10px);
filter: blur(10px); filter: blur(10px);
letter-spacing: 0.1em; letter-spacing: 0.1em;
&.active{
&.active {
opacity: 1; opacity: 1;
transform: perspective(100px) translateZ(0px); transform: perspective(100px) translateZ(0px);
filter: blur(0px); filter: blur(0px);
letter-spacing: 0.15em; letter-spacing: 0.15em;
transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear; transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear;
} }
&.past{
&.past {
opacity: 0; opacity: 0;
transform: perspective(100px) translateZ(-10px); transform: perspective(100px) translateZ(-10px);
filter: blur(10px); filter: blur(10px);
letter-spacing: 0.2em; letter-spacing: 0.2em;
transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear; transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear;
} }
} }
.like_button { .like_button {
--color-heart: #EA442B; --color-heart: #EA442B;
--easing: cubic-bezier(.7,0,.3,1); --easing: cubic-bezier(.7, 0, .3, 1);
--duration: .5s; --duration: .5s;
font-size: 40px; font-size: 40px;
@ -54,7 +61,7 @@
z-index: 2; z-index: 2;
transition: transform var(--duration) var(--easing); transition: transform var(--duration) var(--easing);
cursor: pointer; cursor: pointer;
&:before { &:before {
z-index: -1; z-index: -1;
content: ''; content: '';
@ -66,7 +73,7 @@
border-radius: inherit; border-radius: inherit;
transition: inherit; transition: inherit;
} }
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
@ -78,55 +85,62 @@
border-radius: inherit; border-radius: inherit;
z-index: -1; z-index: -1;
} }
@keyframes depress { @keyframes depress {
from, to {
from,
to {
transform: none; transform: none;
} }
50% { 50% {
transform: translateY(5%) scale(0.9); transform: translateY(5%) scale(0.9);
} }
} }
@keyframes depress-shadow { @keyframes depress-shadow {
from, to {
from,
to {
transform: none; transform: none;
} }
50% { 50% {
transform: scale(0.5); transform: scale(0.5);
} }
} }
} }
.like_wrapper { .like_wrapper {
display: grid; display: grid;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 1; z-index: 1;
> * {
>* {
margin: auto; margin: auto;
grid-area: 1 / 1; grid-area: 1 / 1;
} }
} }
.heart { .heart {
width: .5em; width: .5em;
height: .5em; height: .5em;
display: block; display: block;
transform-origin: center 80%; transform-origin: center 80%;
> path { >path {
stroke: var(--color-heart); stroke: var(--color-heart);
stroke-width: 2; stroke-width: 2;
transition: fill var(--duration) var(--easing); transition: fill var(--duration) var(--easing);
fill: var(--color-heart); fill: var(--color-heart);
} }
&.empty{ &.empty {
> path { >path {
stroke: var(--color-heart); stroke: var(--color-heart);
stroke-width: 2; stroke-width: 2;
transition: fill var(--duration) var(--easing); transition: fill var(--duration) var(--easing);
@ -134,18 +148,23 @@
} }
} }
&.clickanim{ &.clickanim {
animation: heart-bounce var(--duration) var(--easing); animation: heart-bounce var(--duration) var(--easing);
@keyframes heart-bounce { @keyframes heart-bounce {
40% { transform: scale(0.7); } 40% {
0%, 80%, 100% { transform: scale(1); } transform: scale(0.7);
}
0%,
80%,
100% {
transform: scale(1);
}
} }
} }
animation: none; animation: none;
} }
.ripple { .ripple {
@ -154,7 +173,7 @@
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
z-index: 1; z-index: 1;
&:before { &:before {
content: ''; content: '';
position: absolute; position: absolute;
@ -166,16 +185,21 @@
border-radius: inherit; border-radius: inherit;
transform: scale(0); transform: scale(0);
} }
&.clickanim{
&.clickanim {
&:before { &:before {
animation: ripple-out var(--duration) var(--easing); animation: ripple-out var(--duration) var(--easing);
@keyframes ripple-out { @keyframes ripple-out {
from { transform: scale(0); } from {
to { transform: scale(5); } transform: scale(0);
}
to {
transform: scale(5);
}
} }
} }
} }
}
}

View File

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import {CoreLoader} from 'components' import { CoreLoader } from 'components'
import { AppSettings } from 'ycore' import { AppSettings } from 'ycore'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import classNames from 'classnames' import classNames from 'classnames'
@ -11,14 +11,14 @@ const Loader = ({ spinning = true, fullScreen }) => {
<div className={styles.loader}> <div className={styles.loader}>
<div className={styles.warpper}> <div className={styles.warpper}>
<div className={styles.newloader}> <div className={styles.newloader}>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
</div> </div>
</div> </div>
</div> </div>
@ -32,15 +32,17 @@ const Loader = ({ spinning = true, fullScreen }) => {
})} })}
> >
<div className={styles.warpper}> <div className={styles.warpper}>
<div className={classNames(styles.newloader, {[styles.end]: !spinning}) }> <div
<div></div> className={classNames(styles.newloader, { [styles.end]: !spinning })}
<div></div> >
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div>
<div></div>
</div> </div>
</div> </div>
</div> </div>
@ -51,4 +53,4 @@ Loader.propTypes = {
fullScreen: PropTypes.bool, fullScreen: PropTypes.bool,
} }
export default Loader; export default Loader

View File

@ -1,4 +1,5 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.loader { .loader {
background-color: transparent; //rgba(44, 44, 44, 0.74); background-color: transparent; //rgba(44, 44, 44, 0.74);
width: 100%; width: 100%;
@ -16,7 +17,7 @@
position: fixed; position: fixed;
} }
&.hidden{ &.hidden {
z-index: -1; z-index: -1;
opacity: 0; opacity: 0;
transition: opacity 3s ease 0.5s, z-index 0.1s ease 1.5s; transition: opacity 3s ease 0.5s, z-index 0.1s ease 1.5s;
@ -39,18 +40,20 @@
height: 0px; height: 0px;
margin: 0 auto; margin: 0 auto;
position: relative; position: relative;
&.end{
&.end {
.loader { .loader {
z-index: -1; z-index: -1;
opacity: 0; opacity: 0;
} }
>div { >div {
animation: newloader 0.8s linear; animation: newloader 0.8s linear;
}
} }
}
} }
.newloader > div { .newloader>div {
background-color: rgb(34, 34, 34); background-color: rgb(34, 34, 34);
width: 6px; width: 6px;
height: 20px; height: 20px;
@ -62,52 +65,64 @@
transform: rotate(0deg); transform: rotate(0deg);
animation: newloader 0.8s infinite; animation: newloader 0.8s infinite;
} }
.newloader > div:nth-child(2) {
.newloader>div:nth-child(2) {
transform: rotate(45deg); transform: rotate(45deg);
animation-delay: 0.1s; animation-delay: 0.1s;
} }
.newloader > div:nth-child(3) {
.newloader>div:nth-child(3) {
transform: rotate(90deg); transform: rotate(90deg);
animation-delay: 0.2s; animation-delay: 0.2s;
} }
.newloader > div:nth-child(4) {
.newloader>div:nth-child(4) {
transform: rotate(135deg); transform: rotate(135deg);
animation-delay: 0.3s; animation-delay: 0.3s;
} }
.newloader > div:nth-child(5) {
.newloader>div:nth-child(5) {
transform: rotate(180deg); transform: rotate(180deg);
animation-delay: 0.4s; animation-delay: 0.4s;
} }
.newloader > div:nth-child(6) {
.newloader>div:nth-child(6) {
transform: rotate(225deg); transform: rotate(225deg);
animation-delay: 0.5s; animation-delay: 0.5s;
} }
.newloader > div:nth-child(7) {
.newloader>div:nth-child(7) {
transform: rotate(270deg); transform: rotate(270deg);
animation-delay: 0.6s; animation-delay: 0.6s;
} }
.newloader > div:nth-child(8) {
.newloader>div:nth-child(8) {
transform: rotate(315deg); transform: rotate(315deg);
animation-delay: 0.7s; animation-delay: 0.7s;
} }
@keyframes unshow { @keyframes unshow {
0%{ 0% {
opacity: 1; opacity: 1;
} }
100%{
100% {
opacity: 0; opacity: 0;
z-index: -1; z-index: -1;
} }
} }
@keyframes newloader { @keyframes newloader {
0% { 0% {
background: transparent; background: transparent;
left: -10px; left: -10px;
transform-origin: 10px 35px; transform-origin: 10px 35px;
} }
30% { 30% {
background: #fff; background: #fff;
} }
100% { 100% {
background: transparent; background: transparent;
left: 10px; left: 10px;
@ -115,4 +130,3 @@
} }
} }
} }

View File

@ -3,165 +3,194 @@ import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as Icons from '@ant-design/icons' import * as Icons from '@ant-design/icons'
import {PostCard} from 'components' import { PostCard } from 'components'
export const RenderFeed = { export const RenderFeed = {
RefreshFeed: () => { RefreshFeed: () => {
window.MainFeedComponent.FirstGet(); window.MainFeedComponent.FirstGet()
return return
}, },
killByID: (post_id) => { killByID: post_id => {
window.MainFeedComponent.killByID(post_id); window.MainFeedComponent.killByID(post_id)
return return
}, },
addToRend: (payload) => { addToRend: payload => {
window.MainFeedComponent.addToRend(payload); window.MainFeedComponent.addToRend(payload)
return return
} },
} }
class MainFeed extends React.Component { class MainFeed extends React.Component {
constructor(props){ constructor(props) {
super(props) super(props)
window.MainFeedComponent = this; window.MainFeedComponent = this
this.state = { this.state = {
invalid: false, invalid: false,
loading: false, loading: false,
data: [], data: [],
fkey: 0 fkey: 0,
}
}
componentDidMount() {
this.FirstGet()
}
toogleLoader() {
this.setState({ loading: !this.state.loading })
}
killByID(post_id) {
const a = this.state.data
const b = ycore.arrayRemoveByID(a, post_id)
this.setState({ data: b })
}
addToRend(payload) {
let a = this.state.data
a.unshift(payload)
this.setState({ data: a })
}
FirstGet() {
try {
const { get, uid, filters } = this.props
if (this.props.custompayload) {
this.setState({
isEnd: true,
data: this.props.custompayload,
loading: false,
})
return
}
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
this.toogleLoader()
const payload = { fkey: 0, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
ycore.notify.error('Error when get data from this input')
return
} }
} if (JSON.parse(res).api_status == '400') {
this.setState({ invalid: true })
return
}
const parsed = JSON.parse(res)['data']
componentDidMount(){ const isEnd =
this.FirstGet() parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: parsed, loading: false })
}, payload)
} catch (err) {
ycore.notify.error('err')
} }
}
toogleLoader(){ GetMore(fkey) {
this.setState({ loading: !this.state.loading }) try {
} const { get, uid, filters } = this.props
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
if (!fkey) {
ycore.yconsole.warn(
'Please, provide a fkey for offset the feed, default using => 0'
)
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
killByID(post_id){ const payload = { fkey: getLastPost.id, type: get, id: uid }
const a = this.state.data ycore.comty_post.getFeed((err, res) => {
const b = ycore.arrayRemoveByID(a, post_id) if (err) {
this.setState({data: b}) return false
}
const oldData = this.state.data
const parsed = JSON.parse(res)['data']
const mix = oldData.concat(parsed)
const isEnd =
parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () =>
ycore.gotoElement(getLastPost.id)
)
return true
}, payload)
} catch (err) {
ycore.notify.error(err)
} }
}
addToRend(payload){ renderFeedPosts = () => {
let a = this.state.data const { data, loading, isEnd } = this.state
a.unshift(payload)
this.setState({ data: a })
}
FirstGet() { const loadMore =
try{ !isEnd && !loading ? (
const { get, uid, filters } = this.props; <div
if (this.props.custompayload) { style={{
this.setState({ isEnd: true, data: this.props.custompayload, loading: false }) textAlign: 'center',
return marginTop: 12,
} height: 32,
if (!get) { lineHeight: '32px',
ycore.yconsole.error('Please, fill params with an catch type...') }}
return >
} <antd.Button
this.toogleLoader() type="ghost"
const payload = { fkey: 0, type: get, id: uid } icon={<Icons.DownSquareOutlined />}
ycore.comty_post.getFeed((err,res) => { onClick={() => this.GetMore()}
if (err) { />
ycore.notifyError('Error when get data from this input') </div>
return ) : null
} try {
if (JSON.parse(res).api_status == '400') { ycore.yconsole.log(data)
this.setState({ invalid: true }) return (
return <antd.List
} loadMore={loadMore}
const parsed = JSON.parse(res)['data'] dataSource={data}
renderItem={item => (
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false <div id={item.id}>
this.setState({ isEnd: isEnd, data: parsed, loading: false }) <PostCard payload={item} key={item.id} />
}, payload) </div>
)}
/>
)
} catch (err) {
return false
}
}
}catch(err){ render() {
ycore.notifyError('err') const { loading, invalid } = this.state
} return (
} <div id="mainfeed">
{invalid ? (
GetMore(fkey){ <antd.Card
try{ style={{
const { get, uid, filters } = this.props; borderRadius: '10px',
if (!get) { maxWidth: '26.5vw',
ycore.yconsole.error('Please, fill params with an catch type...') margin: 'auto',
return
}
if (!fkey) {
ycore.yconsole.warn('Please, provide a fkey for offset the feed, default using => 0');
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
ycore.comty_post.getFeed((err,res) => {
if (err){return false}
const oldData = this.state.data
const parsed = JSON.parse(res)['data']
const mix = oldData.concat(parsed)
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () => ycore.gotoElement(getLastPost.id) )
return true
}, payload)
}catch(err){
ycore.notifyError(err)
}
}
renderFeedPosts = () =>{
const {data, loading, isEnd} = this.state
const loadMore =
!isEnd && !loading ? (
<div style={{
textAlign: 'center', textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}} }}
> >
<antd.Button type="ghost" icon={<Icons.DownSquareOutlined />} onClick={() => this.GetMore()} /> <h2>
</div> <Icons.ExclamationCircleOutlined /> Invalid Data{' '}
) : null; </h2>
try { <span>
ycore.yconsole.log(data) If this error has occurred several times, try restarting the app
return ( </span>
<antd.List </antd.Card>
loadMore={loadMore} ) : loading ? (
dataSource={data} <antd.Card style={{ maxWidth: '26.5vw', margin: 'auto' }}>
renderItem={item => (<div id={item.id}><PostCard payload={item} key={item.id} /></div>)} <antd.Skeleton avatar paragraph={{ rows: 4 }} active />
/> </antd.Card>
) ) : (
} catch (err) { this.renderFeedPosts()
return false )}
} </div>
} )
}
render(){
const { loading, invalid } = this.state;
return (
<div id='mainfeed'>
{invalid?
<antd.Card style={{ borderRadius: "10px", maxWidth: '26.5vw', margin: 'auto', textAlign: 'center' }} >
<h2><Icons.ExclamationCircleOutlined /> Invalid Data </h2>
<span>If this error has occurred several times, try restarting the app</span>
</antd.Card>
:
loading?
<antd.Card style={{ maxWidth: '26.5vw', margin: 'auto' }} >
<antd.Skeleton avatar paragraph={{ rows: 4 }} active />
</antd.Card>
: this.renderFeedPosts()
}
</div>
)
}
} }
export default MainFeed; export default MainFeed

View File

@ -2,48 +2,45 @@ import React from 'react'
import styles from './index.less' import styles from './index.less'
export default class MediaPlayer extends React.PureComponent { export default class MediaPlayer extends React.PureComponent {
renderPostPlayer(payload){ renderPostPlayer(payload) {
const ident = payload const ident = payload
if (ident.includes('.mp4')) { if (ident.includes('.mp4')) {
return ( return (
<video id="player" playsInline controls > <video id="player" playsInline controls>
<source src={`${payload}`} type="video/mp4"/> <source src={`${payload}`} type="video/mp4" />
</video> </video>
) )
}
if (ident.includes('.webm')) {
return (
<video id="player" playsInline controls >
<source src={payload} type="video/webm"/>
</video>
)
}
if (ident.includes('.mp3')){
return (
<audio id="player" controls>
<source src={payload} type="audio/mp3" />
</audio>
)
}
if (ident.includes('.ogg')){
return (
<audio id="player" controls>
<source src={payload} type="audio/ogg" />
</audio>
)
}
else {
return (
<img src={payload} />
)
}
} }
render(){ if (ident.includes('.webm')) {
const {file} = this.props return (
return ( <video id="player" playsInline controls>
<div className={styles.PlayerContainer}> <source src={payload} type="video/webm" />
{this.renderPostPlayer(file)} </video>
</div> )
)
} }
} if (ident.includes('.mp3')) {
return (
<audio id="player" controls>
<source src={payload} type="audio/mp3" />
</audio>
)
}
if (ident.includes('.ogg')) {
return (
<audio id="player" controls>
<source src={payload} type="audio/ogg" />
</audio>
)
} else {
return <img src={payload} />
}
}
render() {
const { file } = this.props
return (
<div className={styles.PlayerContainer}>
{this.renderPostPlayer(file)}
</div>
)
}
}

View File

@ -1,28 +1,31 @@
.PlayerContainer{ .PlayerContainer {
max-width: 100vw; max-width: 100vw;
max-height: 75vh; max-height: 75vh;
img {
object-fit: contain; img {
position: absolute; object-fit: contain;
top: 50%; position: absolute;
left: 47%; top: 50%;
width: 500px; left: 47%;
height: 500px; width: 500px;
margin-top: -250px; height: 500px;
margin-left: -350px; margin-top: -250px;
} margin-left: -350px;
video { }
object-fit: contain;
position: absolute; video {
top: 50%; object-fit: contain;
left: 47%; position: absolute;
width: 500px; top: 50%;
height: 500px; left: 47%;
margin-top: -250px; width: 500px;
margin-left: -350px; height: 500px;
} margin-top: -250px;
h3{ margin-left: -350px;
color: rgb(85, 85, 85); }
font-weight: 470;
} h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
} }

View File

@ -1,40 +0,0 @@
import React from 'react'
import * as ycore from 'ycore'
import * as antd from 'antd'
import styles from './index.less'
import { HandleVisibility } from 'components/PostCreator'
export function HandleShow(){
window.MicroHeaderComponent.toogleShow();
return
}
class MicroHeader extends React.Component {
constructor(props){
super(props),
window.MicroHeaderComponent = this;
this.state = {
FadeIN: false,
Show: true
}
}
toogleShow(){
this.setState({FadeIN: !this.state.FadeIN})
this.state.FadeIN? this.setState({ Show: true }) : setTimeout(() => this.setState({ Show: false }), 1000)
}
render(){
const { Show } = this.state
return(
Show? (
<div>
<antd.Card bordered={false} className={styles.MicroHeader}>
<antd.Button icon="notification" />
<antd.Button icon="plus" onClick={() => HandleVisibility()} />
<antd.Button icon="filter" />
</antd.Card>
</div>
) : null
)
}
}
export default MicroHeader

View File

@ -1,31 +0,0 @@
@import '~themes/vars.less';
.MicroHeader{
background-color: transparent !important;
padding: 0 5px 0 5px;
width: 100%;
height: auto;
position: absolute;
z-index: 1000;
top: 0;
text-align: center;
:global {
.ant-card-body {
background-color: rgba(0, 0, 0, 0.1);
max-width: 10%;
margin: auto;
padding: 5px;
border-radius: 0 0 13px 13px;
transform: translate(0, -30px);
transition: all 150ms ease-in;
}
.ant-card-body:hover {
transform: translate(0, 0px);
transition: all 150ms ease-in;
}
.ant-btn {
background-color: transparent;
margin: 3px;
}
}
}

View File

@ -3,36 +3,46 @@ import styles from './index.less'
import store from 'store' import store from 'store'
import * as antd from 'antd' import * as antd from 'antd'
export default class MobileWarning extends React.PureComponent{ export default class MobileWarning extends React.PureComponent {
state = {
resbypass: store.get('resbypass') || false,
}
state = { ResByPassHandler = () => {
resbypass: store.get('resbypass') || false, this.setState({ resbypass: true })
}
render() {
const { resbypass } = this.state
if (resbypass == false) {
return (
<div className={styles.mobilewarning}>
<antd.Result
status="warning"
title="Low resolution warning"
extra={
<div style={{ color: 'white' }}>
<h3 style={{ color: 'white' }}>
This version of the application is not fully compatible with
the resolution of this screen, a higher resolution is
recommended for an optimal experience
</h3>
<span>Please choose an option to continue</span>
<br />
<br />
<antd.Button
type="dashed"
onClick={() => this.ResByPassHandler()}
>
Continue
</antd.Button>
</div>
}
/>
</div>
)
} }
return null
ResByPassHandler = () => { }
this.setState({resbypass: true}) }
}
render(){
const { resbypass } = this.state
if (resbypass == false) {
return(
<div className={styles.mobilewarning}>
<antd.Result status="warning" title="Low resolution warning"
extra={
<div style={{ color: "white" }}>
<h3 style={{ color: "white" }}>This version of the application is not fully compatible with the resolution of this screen, a higher resolution is recommended for an optimal experience</h3>
<span>Please choose an option to continue</span>
<br /><br /><antd.Button type="dashed" onClick={() => this.ResByPassHandler()}>Continue</antd.Button>
</div>
}/>
</div>
)
}
return null
}
}

View File

@ -1,18 +1,18 @@
.mobilewarning {
background-color: rgba(0, 0, 0, 0.975);
color: white;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
z-index: 100000;
display: flex;
justify-content: center;
text-align: center;
.mobilewarning{ :global {
background-color: rgba(0, 0, 0, 0.975); .ant-result-title {
color: white; color: white;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
z-index: 100000;
display: flex;
justify-content: center;
text-align: center;
:global {
.ant-result-title {
color: white;
}
} }
} }
}

View File

@ -1,33 +0,0 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Loader from '../Loader/Loader.js'
import styles from './Page.less'
export default class Page extends Component {
render() {
const { className, children, loading = false, inner = false } = this.props
const loadingStyle = {
height: 'calc(100vh - 184px)',
overflow: 'hidden',
}
return (
<div
className={classnames(className, {
[styles.contentInner]: inner,
})}
style={loading ? loadingStyle : null}
>
{loading ? <Loader spinning /> : ''}
{children}
</div>
)
}
}
Page.propTypes = {
className: PropTypes.string,
children: PropTypes.node,
loading: PropTypes.bool,
inner: PropTypes.bool,
}

View File

@ -1,16 +0,0 @@
@import '~themes/vars.less';
.contentInner {
background: #fff;
padding: 24px;
box-shadow: @shadow-1;
min-height: ~'calc(100vh - 230px)';
position: relative;
}
@media (max-width: 767px) {
.contentInner {
padding: 12px;
min-height: ~'calc(100vh - 160px)';
}
}

View File

@ -1,6 +0,0 @@
{
"name": "Page",
"version": "0.0.0",
"private": true,
"main": "./Page.js"
}

View File

@ -1,4 +1,4 @@
import { keyframes } from 'styled-components'; import { keyframes } from 'styled-components'
export default { export default {
moveToLeft: { moveToLeft: {
@ -8,7 +8,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromLeft: { moveFromLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -16,7 +16,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToRight: { moveToRight: {
keyframes: keyframes` keyframes: keyframes`
@ -25,7 +25,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromRight: { moveFromRight: {
keyframes: keyframes` keyframes: keyframes`
@ -33,7 +33,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToTop: { moveToTop: {
keyframes: keyframes` keyframes: keyframes`
@ -42,7 +42,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromTop: { moveFromTop: {
keyframes: keyframes` keyframes: keyframes`
@ -50,7 +50,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToBottom: { moveToBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -59,7 +59,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromBottom: { moveFromBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -67,7 +67,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
fade: { fade: {
keyframes: keyframes` keyframes: keyframes`
@ -76,7 +76,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToLeftFade: { moveToLeftFade: {
keyframes: keyframes` keyframes: keyframes`
@ -85,7 +85,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromLeftFade: { moveFromLeftFade: {
keyframes: keyframes` keyframes: keyframes`
@ -93,7 +93,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToRightFade: { moveToRightFade: {
keyframes: keyframes` keyframes: keyframes`
@ -102,7 +102,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromRightFade: { moveFromRightFade: {
keyframes: keyframes` keyframes: keyframes`
@ -110,7 +110,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToTopFade: { moveToTopFade: {
keyframes: keyframes` keyframes: keyframes`
@ -119,7 +119,7 @@ export default {
`, `,
duration: 600, duration: 600,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromTopFade: { moveFromTopFade: {
keyframes: keyframes` keyframes: keyframes`
@ -127,7 +127,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveToBottomFade: { moveToBottomFade: {
keyframes: keyframes` keyframes: keyframes`
@ -136,7 +136,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
moveFromBottomFade: { moveFromBottomFade: {
keyframes: keyframes` keyframes: keyframes`
@ -144,7 +144,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleDown: { scaleDown: {
keyframes: keyframes` keyframes: keyframes`
@ -153,7 +153,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleUp: { scaleUp: {
keyframes: keyframes` keyframes: keyframes`
@ -161,7 +161,7 @@ export default {
`, `,
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleUpDown: { scaleUpDown: {
keyframes: keyframes` keyframes: keyframes`
@ -169,7 +169,7 @@ export default {
`, `,
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleDownUp: { scaleDownUp: {
keyframes: keyframes` keyframes: keyframes`
@ -178,7 +178,7 @@ export default {
`, `,
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleDownCenter: { scaleDownCenter: {
keyframes: keyframes` keyframes: keyframes`
@ -187,7 +187,7 @@ export default {
`, `,
duration: 400, duration: 400,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
scaleUpCenter: { scaleUpCenter: {
keyframes: keyframes` keyframes: keyframes`
@ -195,7 +195,7 @@ export default {
`, `,
duration: 400, duration: 400,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
rotateRightSideFirst: { rotateRightSideFirst: {
keyframes: keyframes` keyframes: keyframes`
@ -206,7 +206,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateLeftSideFirst: { rotateLeftSideFirst: {
keyframes: keyframes` keyframes: keyframes`
@ -217,7 +217,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateTopSideFirst: { rotateTopSideFirst: {
keyframes: keyframes` keyframes: keyframes`
@ -228,7 +228,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateBottomSideFirst: { rotateBottomSideFirst: {
keyframes: keyframes` keyframes: keyframes`
@ -239,7 +239,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
flipOutRight: { flipOutRight: {
keyframes: keyframes` keyframes: keyframes`
@ -249,7 +249,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipInLeft: { flipInLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -258,7 +258,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-out', timing: 'ease-out',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipOutLeft: { flipOutLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -268,7 +268,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipInRight: { flipInRight: {
keyframes: keyframes` keyframes: keyframes`
@ -277,7 +277,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-out', timing: 'ease-out',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipOutTop: { flipOutTop: {
keyframes: keyframes` keyframes: keyframes`
@ -287,7 +287,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipInBottom: { flipInBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -296,7 +296,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-out', timing: 'ease-out',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipOutBottom: { flipOutBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -306,7 +306,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
flipInTop: { flipInTop: {
keyframes: keyframes` keyframes: keyframes`
@ -315,7 +315,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-out', timing: 'ease-out',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
rotateFall: { rotateFall: {
keyframes: keyframes` keyframes: keyframes`
@ -328,7 +328,7 @@ export default {
duration: 1000, duration: 1000,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 0%' origin: '0% 0%',
}, },
rotateOutNewspaper: { rotateOutNewspaper: {
keyframes: keyframes` keyframes: keyframes`
@ -338,7 +338,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
rotateInNewspaper: { rotateInNewspaper: {
keyframes: keyframes` keyframes: keyframes`
@ -347,7 +347,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-out', timing: 'ease-out',
fill: 'both', fill: 'both',
origin: '50% 50%' origin: '50% 50%',
}, },
rotatePushLeft: { rotatePushLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -357,7 +357,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotatePushRight: { rotatePushRight: {
keyframes: keyframes` keyframes: keyframes`
@ -367,7 +367,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotatePushTop: { rotatePushTop: {
keyframes: keyframes` keyframes: keyframes`
@ -377,7 +377,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotatePushBottom: { rotatePushBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -387,7 +387,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotatePullRight: { rotatePullRight: {
keyframes: keyframes` keyframes: keyframes`
@ -396,7 +396,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotatePullLeft: { rotatePullLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -405,7 +405,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotatePullTop: { rotatePullTop: {
keyframes: keyframes` keyframes: keyframes`
@ -414,7 +414,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotatePullBottom: { rotatePullBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -423,7 +423,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateFoldRight: { rotateFoldRight: {
keyframes: keyframes` keyframes: keyframes`
@ -433,7 +433,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateFoldLeft: { rotateFoldLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -443,7 +443,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateFoldTop: { rotateFoldTop: {
keyframes: keyframes` keyframes: keyframes`
@ -453,7 +453,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateFoldBottom: { rotateFoldBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -463,7 +463,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateUnfoldLeft: { rotateUnfoldLeft: {
keyframes: keyframes` keyframes: keyframes`
@ -472,7 +472,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateUnfoldRight: { rotateUnfoldRight: {
keyframes: keyframes` keyframes: keyframes`
@ -481,7 +481,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateUnfoldTop: { rotateUnfoldTop: {
keyframes: keyframes` keyframes: keyframes`
@ -490,7 +490,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateUnfoldBottom: { rotateUnfoldBottom: {
keyframes: keyframes` keyframes: keyframes`
@ -499,7 +499,7 @@ export default {
duration: 700, duration: 700,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateRoomLeftOut: { rotateRoomLeftOut: {
keyframes: keyframes` keyframes: keyframes`
@ -509,7 +509,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateRoomLeftIn: { rotateRoomLeftIn: {
keyframes: keyframes` keyframes: keyframes`
@ -518,7 +518,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateRoomRightOut: { rotateRoomRightOut: {
keyframes: keyframes` keyframes: keyframes`
@ -528,7 +528,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateRoomRightIn: { rotateRoomRightIn: {
keyframes: keyframes` keyframes: keyframes`
@ -537,7 +537,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateRoomTopOut: { rotateRoomTopOut: {
keyframes: keyframes` keyframes: keyframes`
@ -547,7 +547,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateRoomTopIn: { rotateRoomTopIn: {
keyframes: keyframes` keyframes: keyframes`
@ -556,7 +556,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateRoomBottomOut: { rotateRoomBottomOut: {
keyframes: keyframes` keyframes: keyframes`
@ -566,7 +566,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateRoomBottomIn: { rotateRoomBottomIn: {
keyframes: keyframes` keyframes: keyframes`
@ -575,7 +575,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateCubeLeftOut: { rotateCubeLeftOut: {
keyframes: keyframes` keyframes: keyframes`
@ -586,7 +586,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateCubeLeftIn: { rotateCubeLeftIn: {
keyframes: keyframes` keyframes: keyframes`
@ -596,7 +596,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateCubeRightOut: { rotateCubeRightOut: {
keyframes: keyframes` keyframes: keyframes`
@ -607,7 +607,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateCubeRightIn: { rotateCubeRightIn: {
keyframes: keyframes` keyframes: keyframes`
@ -617,7 +617,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateCubeTopOut: { rotateCubeTopOut: {
keyframes: keyframes` keyframes: keyframes`
@ -628,7 +628,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateCubeTopIn: { rotateCubeTopIn: {
keyframes: keyframes` keyframes: keyframes`
@ -638,7 +638,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateCubeBottomOut: { rotateCubeBottomOut: {
keyframes: keyframes` keyframes: keyframes`
@ -649,7 +649,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateCubeBottomIn: { rotateCubeBottomIn: {
keyframes: keyframes` keyframes: keyframes`
@ -659,7 +659,7 @@ export default {
duration: 600, duration: 600,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateCarouselLeftOut: { rotateCarouselLeftOut: {
keyframes: keyframes` keyframes: keyframes`
@ -669,7 +669,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateCarouselLeftIn: { rotateCarouselLeftIn: {
keyframes: keyframes` keyframes: keyframes`
@ -678,7 +678,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateCarouselRightOut: { rotateCarouselRightOut: {
keyframes: keyframes` keyframes: keyframes`
@ -688,7 +688,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '0% 50%' origin: '0% 50%',
}, },
rotateCarouselRightIn: { rotateCarouselRightIn: {
keyframes: keyframes` keyframes: keyframes`
@ -697,7 +697,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '100% 50%' origin: '100% 50%',
}, },
rotateCarouselTopOut: { rotateCarouselTopOut: {
keyframes: keyframes` keyframes: keyframes`
@ -707,7 +707,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateCarouselTopIn: { rotateCarouselTopIn: {
keyframes: keyframes` keyframes: keyframes`
@ -716,7 +716,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateCarouselBottomOut: { rotateCarouselBottomOut: {
keyframes: keyframes` keyframes: keyframes`
@ -726,7 +726,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 0%' origin: '50% 0%',
}, },
rotateCarouselBottomIn: { rotateCarouselBottomIn: {
keyframes: keyframes` keyframes: keyframes`
@ -735,7 +735,7 @@ export default {
duration: 800, duration: 800,
timing: 'ease', timing: 'ease',
fill: 'both', fill: 'both',
origin: '50% 100%' origin: '50% 100%',
}, },
rotateSidesOut: { rotateSidesOut: {
keyframes: keyframes` keyframes: keyframes`
@ -745,7 +745,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '-50% 50%' origin: '-50% 50%',
}, },
rotateSidesIn: { rotateSidesIn: {
keyframes: keyframes` keyframes: keyframes`
@ -754,7 +754,7 @@ export default {
duration: 500, duration: 500,
timing: 'ease-in', timing: 'ease-in',
fill: 'both', fill: 'both',
origin: '150% 50%' origin: '150% 50%',
}, },
rotateSlideOut: { rotateSlideOut: {
keyframes: keyframes` keyframes: keyframes`
@ -765,7 +765,7 @@ export default {
`, `,
duration: 1000, duration: 1000,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
}, },
rotateSlideIn: { rotateSlideIn: {
keyframes: keyframes` keyframes: keyframes`
@ -775,6 +775,6 @@ export default {
`, `,
duration: 1000, duration: 1000,
timing: 'ease', timing: 'ease',
fill: 'both' fill: 'both',
} },
}; }

View File

@ -1,8 +1,8 @@
import React, { memo } from 'react'; import React, { memo } from 'react'
import { Transition, TransitionGroup } from 'react-transition-group'; import { Transition, TransitionGroup } from 'react-transition-group'
import animations from './animations'; import animations from './animations'
import presets from './presets'; import presets from './presets'
import * as Styles from './styles'; import * as Styles from './styles'
function PageTransition({ function PageTransition({
children, children,
@ -15,48 +15,48 @@ function PageTransition({
const selectEnterAnimation = () => { const selectEnterAnimation = () => {
if (enterAnimationOverride) { if (enterAnimationOverride) {
if (typeof enterAnimationOverride === 'string') { if (typeof enterAnimationOverride === 'string') {
return animations[enterAnimationOverride]; return animations[enterAnimationOverride]
} }
return { return {
...animations[enterAnimationOverride.name], ...animations[enterAnimationOverride.name],
delay: enterAnimationOverride.delay, delay: enterAnimationOverride.delay,
onTop: enterAnimationOverride.onTop onTop: enterAnimationOverride.onTop,
}; }
} }
if (preset) { if (preset) {
return { return {
...animations[presets[preset].enter.name], ...animations[presets[preset].enter.name],
delay: presets[preset].enter.delay, delay: presets[preset].enter.delay,
onTop: presets[preset].enter.onTop onTop: presets[preset].enter.onTop,
}; }
} }
return 'rotateSlideIn'; return 'rotateSlideIn'
}; }
const selectExitAnimation = () => { const selectExitAnimation = () => {
if (exitAnimationOverride) { if (exitAnimationOverride) {
if (typeof exitAnimationOverride === 'string') { if (typeof exitAnimationOverride === 'string') {
return animations[exitAnimationOverride]; return animations[exitAnimationOverride]
} }
return { return {
...animations[exitAnimationOverride.name], ...animations[exitAnimationOverride.name],
delay: exitAnimationOverride.delay, delay: exitAnimationOverride.delay,
onTop: exitAnimationOverride.onTop onTop: exitAnimationOverride.onTop,
}; }
} }
if (preset) { if (preset) {
return { return {
...animations[presets[preset].exit.name], ...animations[presets[preset].exit.name],
delay: presets[preset].exit.delay, delay: presets[preset].exit.delay,
onTop: presets[preset].exit.onTop onTop: presets[preset].exit.onTop,
}; }
} }
return 'rotateSlideIn'; return 'rotateSlideIn'
}; }
const enterAnimation = selectEnterAnimation(); const enterAnimation = selectEnterAnimation()
const exitAnimation = selectExitAnimation(); const exitAnimation = selectExitAnimation()
const timeout = Math.max(enterAnimation.duration, exitAnimation.duration); const timeout = Math.max(enterAnimation.duration, exitAnimation.duration)
return ( return (
<Styles.PageTransitionGroup {...rest}> <Styles.PageTransitionGroup {...rest}>
@ -74,7 +74,7 @@ function PageTransition({
</Transition> </Transition>
</TransitionGroup> </TransitionGroup>
</Styles.PageTransitionGroup> </Styles.PageTransitionGroup>
); )
} }
export default memo(PageTransition); export default memo(PageTransition)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components'
const createAnimationStyles = ({ const createAnimationStyles = ({
keyframes, keyframes,
@ -7,7 +7,7 @@ const createAnimationStyles = ({
timing, timing,
fill, fill,
origin, origin,
onTop onTop,
}) => css` }) => css`
animation-name: ${keyframes}; animation-name: ${keyframes};
animation-delay: ${delay}; animation-delay: ${delay};
@ -19,27 +19,27 @@ const createAnimationStyles = ({
css` css`
z-index: 1; z-index: 1;
`} `}
`; `
const stateMap = { const stateMap = {
entering: ({ enterAnimation }) => { entering: ({ enterAnimation }) => {
return css` return css`
${createAnimationStyles(enterAnimation)}; ${createAnimationStyles(enterAnimation)};
`; `
}, },
exiting: ({ exitAnimation }) => { exiting: ({ exitAnimation }) => {
return css` return css`
${createAnimationStyles(exitAnimation)}; ${createAnimationStyles(exitAnimation)};
`; `
} },
}; }
export const PageTransitionGroup = styled.div` export const PageTransitionGroup = styled.div`
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
perspective: 1200px; perspective: 1200px;
`; `
export const PageTransition = styled.div` export const PageTransition = styled.div`
backface-visibility: hidden; backface-visibility: hidden;
@ -51,4 +51,4 @@ export const PageTransition = styled.div`
transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);
width: 100%; width: 100%;
${({ state }) => stateMap[state]}; ${({ state }) => stateMap[state]};
`; `

View File

@ -1,135 +1,296 @@
import React from 'react' import React from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import styles from './index.less' import styles from './index.less'
import {CustomIcons, LikeBTN} from 'components' import { CustomIcons, Like_button } from 'components'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import classnames from 'classnames' import classnames from 'classnames'
import * as MICON from '@material-ui/icons'; import * as MICON from '@material-ui/icons'
const { Meta } = antd.Card
const { Meta } = antd.Card;
// Set default by configuration // Set default by configuration
const emptyPayload = {user: 'Post Empty', ago: 'This Post is empty', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', content: 'Test Test' } const emptyPayload = {
user: 'Post Empty',
class PostCard extends React.PureComponent{ ago: 'This Post is empty',
constructor(props){ avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
super(props), content: 'Test Test',
this.state = {
FadeIN: true
}
}
renderPostPlayer(payload){
const ident = payload
if (ident.includes('.mp4')) {
return (
<video id="player" playsInline controls >
<source src={`${payload}`} type="video/mp4"/>
</video>
)
}
if (ident.includes('.webm')) {
return (
<video id="player" playsInline controls >
<source src={payload} type="video/webm"/>
</video>
)
}
if (ident.includes('.mp3')){
return (
<audio id="player" controls>
<source src={payload} type="audio/mp3" />
</audio>
)
}
if (ident.includes('.ogg')){
return (
<audio id="player" controls>
<source src={payload} type="audio/ogg" />
</audio>
)
}
else {
return (
<img src={payload} />
)
}
}
goToPost(postID){
localStorage.setItem('p_back_uid', postID)
const payload = {post_id: postID}
ycore.comty_post.get((err,res)=>{
if (err) { return false }
ycore.SecondarySwap.openPost(res)
}, payload)
}
render(){
const { payload, customActions } = this.props
const ActShowMode = ycore.AppSettings.force_show_postactions
const { id, post_time, postText, postFile, publisher, post_likes, is_post_pinned, is_liked, post_comments } = payload || emptyPayload;
const handlePostActions = {
delete: (post_id) => {
const payload = {post_id: post_id}
ycore.comty_post.delete((err,res)=> {
if (err) {
return false
}
ycore.FeedHandler.killByID(post_id)
}, payload)
},
save: () => {
}
}
const defaultActions = [
<div><LikeBTN count={post_likes} id={id} liked={ycore.booleanFix(is_liked)? true : false} key="like" /></div>,
<antd.Badge dot={post_comments > 0 ? true : false}><MICON.InsertComment key="comments" onClick={ ()=> this.goToPost(id) } /></antd.Badge>
]
const actions = customActions || defaultActions;
const MoreMenu = (
<antd.Menu>
{ycore.IsThisPost.owner(publisher.id)?
<antd.Menu.Item onClick={ ()=> handlePostActions.delete(id) } key="remove_post">
<Icons.DeleteOutlined /> Remove post
</antd.Menu.Item>
: null
}
<antd.Menu.Item key="save_post">
<Icons.SaveOutlined /> Save post
</antd.Menu.Item>
</antd.Menu>
);
return(
<div className={styles.cardWrapper}>
<antd.Card onDoubleClick={ ()=> this.goToPost(id) } hoverable className={ActShowMode? styles.showMode : null} actions={actions} >
<Meta
avatar={<div className={styles.postAvatar}><antd.Avatar shape="square" size={50} src={publisher.avatar} /></div>}
title={
<div className={styles.titleWrapper} >
<h4 onClick={() => ycore.crouter.native(`@${publisher.username}`)} className={styles.titleUser}>@{publisher.username} {ycore.booleanFix(publisher.verified)? <Icon style={{ color: 'blue' }} component={CustomIcons.VerifiedBadge} /> : null}{ycore.booleanFix(publisher.nsfw_flag)? <antd.Tag style={{ margin: '0 0 0 13px' }} color="volcano" >NSFW</antd.Tag> : null} </h4>
<div className={styles.PostTags}>
<div className={styles.MoreMenu} ><antd.Dropdown overlay={MoreMenu} trigger={['click']}><Icons.MoreOutlined key="actionMenu" /></antd.Dropdown></div>
{ycore.booleanFix(is_post_pinned)? (<Icons.PushpinFilled /> ): null }
</div>
</div>}
description={<span className={styles.textAgo}>{post_time}</span>}
bordered="false"
/>
{postText? <div className={styles.postContent}> <h3 dangerouslySetInnerHTML={{__html: postText }} /> </div> : null}
{postFile? <div className={styles.postContentFILE}>{this.renderPostPlayer(postFile)}</div> : null }
<div className={styles.ellipsisIcon}><Icons.EllipsisOutlined /></div>
</antd.Card>
</div>
)
}
} }
export default PostCard
class PostCard extends React.PureComponent {
constructor(props) {
super(props),
(this.state = {
FadeIN: true,
postPinned: this.props.payload.is_post_pinned,
postSaved: this.props.payload.is_post_saved,
postReported: this.props.payload.is_post_reported,
postBoosted: this.props.payload.is_post_boosted,
ReportIgnore: false,
})
}
renderPostPlayer(payload) {
const ident = payload
if (ident.includes('.mp4')) {
return (
<video id="player" playsInline controls>
<source src={`${payload}`} type="video/mp4" />
</video>
)
}
if (ident.includes('.webm')) {
return (
<video id="player" playsInline controls>
<source src={payload} type="video/webm" />
</video>
)
}
if (ident.includes('.mp3')) {
return (
<audio id="player" controls>
<source src={payload} type="audio/mp3" />
</audio>
)
}
if (ident.includes('.ogg')) {
return (
<audio id="player" controls>
<source src={payload} type="audio/ogg" />
</audio>
)
} else {
return <img src={payload} />
}
}
goToPost(postID) {
localStorage.setItem('p_back_uid', postID)
const payload = { post_id: postID }
ycore.comty_post.get((err, res) => {
if (err) {
return false
}
ycore.SecondarySwap.openPost(res)
}, payload)
}
render() {
const { payload, customActions } = this.props
const ActShowMode = ycore.AppSettings.force_show_postactions
const {
id,
post_time,
postText,
postFile,
publisher,
post_likes,
is_post_pinned,
is_liked,
post_comments,
} = payload || emptyPayload
const handlePostActions = {
delete: post_id => {
const payload = { post_id: post_id }
ycore.comty_post.delete((err, res) => {
if (err) {
return false
}
ycore.FeedHandler.killByID(post_id)
}, payload)
},
save: post_id => {
const payload = { post_id: post_id }
ycore.comty_post.save((err, res) => {
if (err) {
return false
}
if (this.state.postSaved == false) {
ycore.notify.success('Post Saved')
this.setState({ postSaved: true })
return
} else {
ycore.notify.success('Removed from Saved')
this.setState({ postSaved: false })
}
}, payload)
},
report: post_id => {
const payload = { post_id: post_id }
ycore.comty_post.__report((err, res) => {
if (err) {
return false
}
ycore.notify.success('Post Reported')
}, payload)
},
boost: post_id => {
const payload = { post_id: post_id }
ycore.comty_post.__boost((err, res) => {
if (err) {
return false
}
if (this.state.postBoosted == false) {
ycore.notify.success('Post Boosted')
this.setState({ postBoosted: true })
return
} else {
ycore.notify.success('Post Unboosted')
this.setState({ postBoosted: false })
}
}, payload)
},
}
const defaultActions = [
<div>
<Like_button
count={post_likes}
id={id}
liked={ycore.booleanFix(is_liked) ? true : false}
key="like"
/>
</div>,
<antd.Badge dot={post_comments > 0 ? true : false}>
<MICON.InsertComment key="comments" onClick={() => this.goToPost(id)} />
</antd.Badge>,
]
const actions = customActions || defaultActions
const MoreMenu = (
<antd.Menu>
{ycore.IsThisPost.owner(publisher.id) ? (
<antd.Menu.Item
onClick={() => handlePostActions.delete(id)}
key="remove_post"
>
<Icons.DeleteOutlined /> Remove post
</antd.Menu.Item>
) : null}
{ycore.IsThisPost.owner(publisher.id) ? (
ycore.IsThisUser.pro(publisher.id) ? (
<antd.Menu.Item
onClick={() => handlePostActions.boost(id)}
key="boost_post"
>
<Icons.RocketOutlined />{' '}
{this.state.postBoosted ? 'Unboost' : 'Boost'}
</antd.Menu.Item>
) : null
) : null}
{ycore.IsThisPost.owner(publisher.id) ? <hr /> : null}
<antd.Menu.Item
onClick={() => handlePostActions.save(id)}
key="save_post"
>
<Icons.SaveOutlined />{' '}
{this.state.postSaved ? 'Unsave post' : 'Save Post'}
</antd.Menu.Item>
<antd.Menu.Item
onClick={() => handlePostActions.report(id)}
key="report_post"
>
<Icons.FlagOutlined /> Report post
</antd.Menu.Item>
</antd.Menu>
)
return (
<div className={styles.cardWrapper}>
<antd.Card
onDoubleClick={() => this.goToPost(id)}
hoverable
className={ActShowMode ? styles.showMode : null}
actions={actions}
>
{this.state.ReportIgnore ? null : this.state.postReported ? (
<div className={styles.flaggedWarning}>
<Icons.FlagOutlined />
<h3>It seems that this post has been reported</h3>
<p>The content may be inappropriate or compromising</p>
<antd.Button
onClick={() => {
this.setState({ ReportIgnore: true })
}}
>
Ignore
</antd.Button>
</div>
) : null}
<div
className={classnames(styles.post_include, {
[styles.blur]: this.state.ReportIgnore
? false
: this.state.postReported,
})}
>
<Meta
avatar={
<div className={styles.postAvatar}>
<antd.Avatar
shape="square"
size={50}
src={publisher.avatar}
/>
</div>
}
title={
<div className={styles.titleWrapper}>
<h4
onClick={() =>
ycore.crouter.native(`@${publisher.username}`)
}
className={styles.titleUser}
>
@{publisher.username}{' '}
{ycore.booleanFix(publisher.verified) ? (
<Icon
style={{ color: 'blue' }}
component={CustomIcons.VerifiedBadge}
/>
) : null}
{ycore.booleanFix(publisher.nsfw_flag) ? (
<antd.Tag
style={{ margin: '0 0 0 13px' }}
color="volcano"
>
NSFW
</antd.Tag>
) : null}{' '}
</h4>
<div className={styles.PostTags}>
<div className={styles.MoreMenu}>
<antd.Dropdown overlay={MoreMenu} trigger={['click']}>
<Icons.MoreOutlined key="actionMenu" />
</antd.Dropdown>
</div>
{ycore.booleanFix(is_post_pinned) ? (
<Icons.PushpinFilled />
) : null}
</div>
</div>
}
description={<span className={styles.textAgo}>{post_time}</span>}
bordered="false"
/>
{postText ? (
<div className={styles.postContent}>
{' '}
<h3 dangerouslySetInnerHTML={{ __html: postText }} />{' '}
</div>
) : null}
{postFile ? (
<div className={styles.postContentFILE}>
{this.renderPostPlayer(postFile)}
</div>
) : null}
<div className={styles.ellipsisIcon}>
<Icons.EllipsisOutlined />
</div>
</div>
</antd.Card>
</div>
)
}
}
export default PostCard

View File

@ -1,191 +1,245 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.cardWrapper{
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px;
max-width: 510px;
min-width: 265px;
width: auto;
margin: 23px auto 50px auto;
:global{ .flaggedWarning {
.ant-card-meta-detail > div:not(:last-child){ border-radius: 7px;
margin: 0 width: 100%;
} text-align: center;
.ant-card { position: absolute;
border-radius: 7px; z-index: 20;
border: 0; background: #ffffff60;
border-top: 1px solid #4646460c; font-family: "Poppins", sans-serif;
} padding: 20px 15px 25px 15px;
.ant-card-body {
padding: 13px 0 5px 0; :global {
.anticon {
font-size: 40px;
}
}
}
.cardWrapper {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px;
max-width: 510px;
min-width: 265px;
width: auto;
margin: 23px auto 50px auto;
:global {
.ant-card-meta-detail>div:not(:last-child) {
margin: 0
}
.ant-card {
border-radius: 7px;
border: 0;
border-top: 1px solid #4646460c;
}
.ant-card-body {
padding: 0;
}
.ant-card-actions {
border-top: 0;
background: #EBEBEB;
height: 30px;
position: relative;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
border-radius: 0 0 10px 10px;
opacity: 0;
&.showMode {
opacity: 1;
transform: translate(0, 15px);
}
}
.ant-card-actions:hover {
opacity: 1;
transform: translate(0, 15px);
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
}
.ant-card-actions>li>.anticon {
font-size: 16px;
line-height: 22px;
width: 40px;
height: 40px;
background: white;
border-radius: 23px;
}
.ant-card-actions>li {
margin: -20px 0 0 0;
border-right: 0;
.ant-badge-count {
width: 20px;
text-align: left;
span {
font-size: 12px;
} }
.ant-card-actions { .ant-scroll-number-only>p.ant-scroll-number-only-unit {
border-top: 0; height: 20px;
background: #EBEBEB; width: 20px;
height: 30px; margin: 0;
position: relative; line-height: 20px;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear; padding: 0 0 0 1px;
border-radius: 0 0 10px 10px;
opacity: 0;
&.showMode{
opacity: 1;
transform: translate(0, 15px);
}
} }
}
.ant-card-actions:hover { span {
opacity: 1; font-size: 16px;
transform: translate(0, 15px); line-height: 22px;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear; width: 40px;
} height: 40px;
.ant-card-actions > li > .anticon { background: white;
font-size: 16px; border-radius: 23px;
line-height: 22px;
width: 40px;
height: 40px;
background: white;
border-radius: 23px;
}
.ant-card-actions > li {
margin: -20px 0 0 0 ;
border-right: 0;
.ant-badge-count{
width: 20px;
text-align: left;
span {
font-size: 12px;
}
.ant-scroll-number-only > p.ant-scroll-number-only-unit {
height: 20px;
width: 20px;
margin: 0;
line-height: 20px;
padding: 0 0 0 1px;
}
}
span {
font-size: 16px;
line-height: 22px;
width: 40px;
height: 40px;
background: white;
border-radius: 23px;
margin: auto;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
}
}
}
.showMode{
:global{
ul {
opacity: 1 !important;
transform: translate(0, 15px);
}
}
}
.postAvatar{
position: absolute;
left: -8px;
top: -8px;
display: flex;
}
.titleUser{
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
}
.textAgo{
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags{
float: right;
width: 100%;
z-index: 10;
:global {
.anticon{
color:rgb(249, 179, 64);
float: right;
margin: -0 6px 0 0;;
font-size: 17px;
}
.MoreMenu{
color: #2d2d2d !important;
}
}
}
.titleWrapper{
display: flex;
h4{
cursor: pointer;
}
}
.postContent{
word-break: break-all;
display: flex;
border-radius: 3px;
margin: 23px 24px 23px 24px;
h3{
font-family: "Poppins", sans-serif;
color: #555555;
font-weight: 400;
font-size: 15px;
letter-spacing: -0.3px;
}
}
.postContentFILE{
display: flex;
margin: 23px 0 5px 0;
max-height: 600px;
overflow: hidden;
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto; margin: auto;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
} }
video { }
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
h3{
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.likebtn{
:global{
svg{
color:rgba(0, 0, 0, 0.45);
}
svg:hover{
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
} }
.ellipsisIcon{ .post_include {
color:rgba(0, 0, 0, 0.45); padding: 13px 0 5px 0;
width: 100%; transition: all 150ms linear;
position: absolute;
text-align: center; &.blur {
margin: auto; filter: blur(10px);
font-size: 30px; }
transition: opacity 150ms linear;
} }
.ellipsisIcon:hover{
opacity: 0; .showMode {
transition: opacity 150ms linear; :global {
ul {
opacity: 1 !important;
transform: translate(0, 15px);
}
}
}
.postAvatar {
position: absolute;
left: -8px;
top: -8px;
display: flex;
}
.titleUser {
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
}
.textAgo {
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags {
float: right;
width: 100%;
z-index: 10;
:global {
.anticon {
color: rgb(249, 179, 64);
float: right;
margin: -0 6px 0 0;
;
font-size: 17px;
}
.MoreMenu {
color: #2d2d2d !important;
}
}
}
.titleWrapper {
display: flex;
h4 {
cursor: pointer;
}
}
.postContent {
word-break: break-all;
display: flex;
border-radius: 3px;
margin: 23px 24px 23px 24px;
h3 {
font-family: "Poppins", sans-serif;
color: #555555;
font-weight: 400;
font-size: 15px;
letter-spacing: -0.3px;
}
}
.postContentFILE {
display: flex;
margin: 23px 0 5px 0;
max-height: 600px;
overflow: hidden;
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto;
}
video {
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.likebtn {
:global {
svg {
color: rgba(0, 0, 0, 0.45);
}
svg:hover {
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
}
.ellipsisIcon {
color: rgba(0, 0, 0, 0.45);
width: 100%;
position: absolute;
text-align: center;
margin: auto;
font-size: 30px;
transition: opacity 150ms linear;
}
.ellipsisIcon:hover {
opacity: 0;
transition: opacity 150ms linear;
} }

View File

@ -2,276 +2,388 @@ import React from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import styles from './index.less' import styles from './index.less'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import $ from 'jquery' import $ from 'jquery'
import * as MICONS from '@material-ui/icons' import * as MICONS from '@material-ui/icons'
import Post_options from './local_components/post_options' import Post_options from './local_components/post_options'
import {toogleOptionsBox} from './local_components/post_options' import { optionBox } from './local_components/post_options'
function getBase64(img, callback) { function getBase64(img, callback) {
const reader = new FileReader(); const reader = new FileReader()
reader.addEventListener('load', () => callback(reader.result)); reader.addEventListener('load', () => callback(reader.result))
reader.readAsDataURL(img); reader.readAsDataURL(img)
} }
export function HandleVisibility(){ export function HandleVisibility() {
window.PostCreatorComponent.ToogleVisibility(); window.PostCreatorComponent.ToogleVisibility()
return return
} }
class PostCreator extends React.PureComponent{ class PostCreator extends React.PureComponent {
constructor(props){ constructor(props) {
super(props), super(props), (window.PostCreatorComponent = this)
window.PostCreatorComponent = this; this.state = {
this.state = { visible: true,
visible: true, FadeIN: true,
FadeIN: true, keys_remaining: ycore.AppSettings.MaxLengthPosts,
keys_remaining: ycore.AppSettings.MaxLengthPosts, rawtext: '',
rawtext: '', posting: false,
posting: false, posting_ok: false,
posting_ok: false, shareWith: 'any',
shareWith: 'any', uploader: false,
uploader: false, Schedule: false,
Schedule: false,
}
} }
}
renderPostPlayer(payload){
const {file, fileURL} = this.state
const videofilter = file.type === 'video/mp4'
const imagefilter = file.type === 'image/jpeg' || file.type === 'image/png'
if (imagefilter) {
return (
<div className={styles.imagePreviewWrapper}>
<div className={styles.imageOverlay}>
<antd.Button onClick={() => this.handleDeleteFile()} icon={<Icons.DeleteOutlined />} />
</div>
<div className={styles.imagePreview}>
<img className={styles.imagePreview} src={fileURL} />
</div>
</div>
)
}
if (videofilter) {
return (
<div className={styles.imagePreviewWrapper}>
<div className={styles.imageOverlay}>
<antd.Button onClick={() => this.handleDeleteFile()} icon={<Icons.DeleteOutlined />} />
</div>
<div className={styles.imagePreview}>
<video id="player" playsInline controls >
<source className={styles.imagePreview} src={fileURL} type={file.type}/>
</video>
</div>
</div>
)
}
return null
}
ToogleVisibility(){
this.setState({ visible: !this.state.visible })
}
ToogleUpload(){
this.setState({ uploader: !this.state.uploader })
}
handleDeleteFile = () =>{
this.setState({ fileURL: null })
}
handleFileUpload = info => {
if (info.file.status === 'uploading') {
this.setState({ loading: true, });
return;
}
if (info.file.status === 'done') {
this.setState({ file: info.file.originFileObj, uploader: false })
getBase64(info.file.originFileObj, fileURL =>{
this.setState({fileURL,loading: false})
});
}
};
beforeUpload = (file) => { renderPostPlayer(payload) {
const filter = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/gif' || file.type === 'video/mp4'; const { file, fileURL } = this.state
if (!filter) { const videofilter = file.type === 'video/mp4'
antd.message.error(`${file.type} This file is not valid!`); const imagefilter = file.type === 'image/jpeg' || file.type === 'image/png'
} if (imagefilter) {
const maxsize = file.size / 1024 / 1024 < ycore.AppSettings.MaximunAPIPayload; return (
if (!maxsize) { <div className={styles.imagePreviewWrapper}>
antd.message.error(`Image must smaller than ${ycore.AppSettings.MaximunAPIPayload} KB!`); <div className={styles.imageOverlay}>
} <antd.Button
return filter && maxsize; onClick={() => this.handleDeleteFile()}
} icon={<Icons.DeleteOutlined />}
/>
handleChanges = ({ target: { value } }) => {
this.setState({ rawtext: value, keys_remaining: (ycore.AppSettings.MaxLengthPosts - value.length) })
}
handleKeysProgressBar(){
const { keys_remaining } = this.state;
if (keys_remaining <= (ycore.AppSettings.MaxLengthPosts/100*30)) {
return 'exception'
}else return('active')
}
handleToggleToolbox = () =>{
toogleOptionsBox()
}
FlushPostState(){
this.setState({
posting_ok: true,
posting: false,
rawtext: '',
fileURL: '',
file: ''
})
setTimeout( () => {this.setState({ posting_ok: false }) }, 1000)
ycore.FeedHandler.refresh()
return true
}
handlePublishPost = (e) => {
const { rawtext, shareWith, file } = this.state;
if(!rawtext){
return null
}
this.setState({ posting: true, keys_remaining: ycore.AppSettings.MaxLengthPosts })
const payload = { privacy: ycore.GetPostPrivacy.bool(shareWith), text: rawtext, file: file }
ycore.comty_post.new((err,res)=>{
if (err) {
ycore.notify.error(err)
return false
}
this.FlushPostState()
},payload)
}
dropRef = React.createRef()
handleDragIn = (e) => {
e.preventDefault()
e.stopPropagation()
if (this.state.uploader == true) {
return
}
this.setState({ uploader: true })
}
handleDragOut = (e) => {
e.preventDefault()
e.stopPropagation()
if (this.state.uploader == false) {
return
}
this.setState({ uploader: false })
}
componentDidMount() {
const _this = this
$("body").bind('paste', function(je){
var e = je.originalEvent;
for (var i = 0; i < e.clipboardData.items.length; i++) {
var item = e.clipboardData.items[i];
ycore.yconsole.log('Item: ' + item.type);
if (item.type.indexOf('image') != -1) {
//item.
let a = item.getAsFile()
a
_this.setState({ file: a })
ycore.ReadFileAsB64(a, (res) =>{
_this.setState({ fileURL: res })
})
} else {
// ignore not images
ycore.yconsole.log('Discarding not image paste data');
}
}
}
)
let div = this.dropRef.current
div.addEventListener('dragenter', this.handleDragIn)
div.addEventListener('dragleave', this.handleDragOut)
}
componentWillUnmount() {
let div = this.dropRef.current
div.removeEventListener('dragenter', this.handleDragIn)
div.removeEventListener('dragleave', this.handleDragOut)
}
canPost(){
const { fileURL, keys_remaining, } = this.state
const isTypedSomething = (keys_remaining < ycore.AppSettings.MaxLengthPosts)
const isUploadedFile = (fileURL? true : false)
return isUploadedFile || isTypedSomething
}
render(){
const {userData} = this.props
const { keys_remaining, visible, fileURL } = this.state;
const percent = (((keys_remaining/ycore.AppSettings.MaxLengthPosts) * 100).toFixed(2) )
const changeShare = ({ key }) => {
this.setState({ shareWith: key })
}
const shareOptionsMenu = (
<antd.Menu onClick={changeShare}>
<antd.Menu.Item key="any">{ycore.GetPostPrivacy.decorator("any")}</antd.Menu.Item>
<antd.Menu.Item key="only_follow">{ycore.GetPostPrivacy.decorator("only_follow")}</antd.Menu.Item>
<antd.Menu.Item key="only_followers">{ycore.GetPostPrivacy.decorator("only_followers")}</antd.Menu.Item>
<antd.Menu.Item key="private">{ycore.GetPostPrivacy.decorator("private")}</antd.Menu.Item>
</antd.Menu>
)
if (visible) {
return(
<div className={styles.cardWrapper}>
<antd.Card bordered="false">
<div ref={this.dropRef} className={styles.inputWrapper}>
{this.state.uploader?
<div className={styles.uploader}>
<antd.Upload.Dragger
multiple={false}
listType="picture"
showUploadList={false}
beforeUpload={this.beforeUpload}
onChange={this.handleFileUpload}
>
<Icons.CloudUploadOutlined />
<span>Drop your file here o click for upload</span>
</antd.Upload.Dragger>
</div>
: <>
<div className={styles.titleAvatar}><img src={userData.avatar} /></div>
<antd.Input.TextArea disabled={this.state.posting? true : false} onPressEnter={this.handlePublishPost} value={this.state.rawtext} autoSize={{ minRows: 3, maxRows: 5 }} dragable="false" placeholder="What are you thinking?" onChange={this.handleChanges} allowClear maxLength={ycore.AppSettings.MaxLengthPosts} rows={8} />
<div><antd.Button disabled={this.state.posting? true : !this.canPost() } onClick={this.handlePublishPost} type="primary" icon={this.state.posting_ok? <Icons.CheckCircleOutlined/> : (this.state.posting? <Icons.LoadingOutlined /> : <Icons.ExportOutlined /> )} /></div>
</> }
</div>
<div className={styles.progressHandler}><antd.Progress strokeWidth="4px" className={this.state.posting? styles.proccessUnset : (keys_remaining < 512? styles.proccessSet : styles.proccessUnset)} status={this.handleKeysProgressBar()} showInfo={false} percent={percent} /></div>
{fileURL? this.renderPostPlayer(this.state.fileURL) : null}
<div className={styles.postExtra} >
<antd.Button styles={this.state.uploader? {fontSize: '20px'} : null} type="ghost" onClick={() => this.ToogleUpload()} > {this.state.uploader? <MICONS.Cancel /> : <MICONS.AddCircle />} </antd.Button>
<antd.Button type="ghost" onClick={this.handleToggleToolbox} ><MICONS.Tune /></antd.Button>
<antd.Dropdown overlay={shareOptionsMenu}>
<a className={styles.shareWith} onClick={e => e.preventDefault()}>
{ycore.GetPostPrivacy.decorator(this.state.shareWith)}
</a>
</antd.Dropdown>
</div>
</antd.Card>
<Post_options visible={this.state.toolbox_open} />
</div> </div>
) <div className={styles.imagePreview}>
} <img className={styles.imagePreview} src={fileURL} />
return null </div>
</div>
)
} }
} if (videofilter) {
export default PostCreator return (
<div className={styles.imagePreviewWrapper}>
<div className={styles.imageOverlay}>
<antd.Button
onClick={() => this.handleDeleteFile()}
icon={<Icons.DeleteOutlined />}
/>
</div>
<div className={styles.imagePreview}>
<video id="player" playsInline controls>
<source
className={styles.imagePreview}
src={fileURL}
type={file.type}
/>
</video>
</div>
</div>
)
}
return null
}
ToogleVisibility() {
this.setState({ visible: !this.state.visible })
}
ToogleUpload() {
this.setState({ uploader: !this.state.uploader })
}
handleDeleteFile = () => {
this.setState({ fileURL: null })
}
handleFileUpload = info => {
if (info.file.status === 'uploading') {
this.setState({ loading: true })
return
}
if (info.file.status === 'done') {
this.setState({ file: info.file.originFileObj, uploader: false })
getBase64(info.file.originFileObj, fileURL => {
this.setState({ fileURL, loading: false })
})
}
}
beforeUpload = file => {
const filter =
file.type === 'image/jpeg' ||
file.type === 'image/png' ||
file.type === 'image/jpg' ||
file.type === 'image/gif' ||
file.type === 'video/mp4'
if (!filter) {
antd.message.error(`${file.type} This file is not valid!`)
}
const maxsize =
file.size / 1024 / 1024 < ycore.AppSettings.MaximunAPIPayload
if (!maxsize) {
antd.message.error(
`Image must smaller than ${ycore.AppSettings.MaximunAPIPayload} KB!`
)
}
return filter && maxsize
}
handleChanges = ({ target: { value } }) => {
this.setState({
rawtext: value,
keys_remaining: ycore.AppSettings.MaxLengthPosts - value.length,
})
}
handleKeysProgressBar() {
const { keys_remaining } = this.state
if (keys_remaining <= (ycore.AppSettings.MaxLengthPosts / 100) * 30) {
return 'exception'
} else return 'active'
}
FlushPostState() {
this.setState({
posting_ok: true,
posting: false,
rawtext: '',
fileURL: '',
file: '',
})
setTimeout(() => {
this.setState({ posting_ok: false })
}, 1000)
ycore.FeedHandler.refresh()
return true
}
handlePublishPost = e => {
const { rawtext, shareWith, file } = this.state
if (!rawtext) {
return null
}
this.setState({
posting: true,
keys_remaining: ycore.AppSettings.MaxLengthPosts,
})
const post_options = optionBox.get()
const payload = {
privacy: ycore.GetPostPrivacy.bool(shareWith),
text: rawtext,
file: file,
}
ycore.comty_post.new((err, res) => {
if (err) {
ycore.notify.error(err)
return false
}
const id_temp_parse = JSON.parse(res)['data'].id
if (ycore.ReturnValueFromMap({ data: post_options, key: 'pro_boost' })) {
ycore.yconsole.log(`Boosting post with ID => ${id_temp_parse}`)
ycore.comty_post.__boost(
(err, res) => {
return true
},
{ post_id: id_temp_parse }
)
}
if (
ycore.ReturnValueFromMap({ data: post_options, key: 'allow_comments' })
) {
ycore.yconsole.log(`Disabling comments with ID => ${id_temp_parse}`)
ycore.comty_post.__disableComments(
(err, res) => {
return true
},
{ post_id: id_temp_parse }
)
}
this.FlushPostState()
// ycore.FeedHandler.addToRend(JSON.parse(res)['data'])
}, payload)
}
dropRef = React.createRef()
handleDragIn = e => {
e.preventDefault()
e.stopPropagation()
if (this.state.uploader == true) {
return
}
this.setState({ uploader: true })
}
handleDragOut = e => {
e.preventDefault()
e.stopPropagation()
if (this.state.uploader == false) {
return
}
this.setState({ uploader: false })
}
componentDidMount() {
const _this = this
$('body').bind('paste', function(je) {
var e = je.originalEvent
for (var i = 0; i < e.clipboardData.items.length; i++) {
var item = e.clipboardData.items[i]
ycore.yconsole.log('Item: ' + item.type)
if (item.type.indexOf('image') != -1) {
//item.
let a = item.getAsFile()
a
_this.setState({ file: a })
ycore.ReadFileAsB64(a, res => {
_this.setState({ fileURL: res })
})
} else {
// ignore not images
ycore.yconsole.log('Discarding not image paste data')
}
}
})
let div = this.dropRef.current
div.addEventListener('dragenter', this.handleDragIn)
div.addEventListener('dragleave', this.handleDragOut)
}
componentWillUnmount() {
let div = this.dropRef.current
div.removeEventListener('dragenter', this.handleDragIn)
div.removeEventListener('dragleave', this.handleDragOut)
}
canPost() {
const { fileURL, keys_remaining } = this.state
const isTypedSomething = keys_remaining < ycore.AppSettings.MaxLengthPosts
const isUploadedFile = fileURL ? true : false
return isUploadedFile || isTypedSomething
}
render() {
const { userData } = this.props
const { keys_remaining, visible, fileURL } = this.state
const percent = (
(keys_remaining / ycore.AppSettings.MaxLengthPosts) *
100
).toFixed(2)
const changeShare = ({ key }) => {
this.setState({ shareWith: key })
}
const shareOptionsMenu = (
<antd.Menu onClick={changeShare}>
<antd.Menu.Item key="any">
{ycore.GetPostPrivacy.decorator('any')}
</antd.Menu.Item>
<antd.Menu.Item key="only_follow">
{ycore.GetPostPrivacy.decorator('only_follow')}
</antd.Menu.Item>
<antd.Menu.Item key="only_followers">
{ycore.GetPostPrivacy.decorator('only_followers')}
</antd.Menu.Item>
<antd.Menu.Item key="private">
{ycore.GetPostPrivacy.decorator('private')}
</antd.Menu.Item>
</antd.Menu>
)
if (visible) {
return (
<div className={styles.cardWrapper}>
<antd.Card bordered="false">
<div ref={this.dropRef} className={styles.inputWrapper}>
{this.state.uploader ? (
<div className={styles.uploader}>
<antd.Upload.Dragger
multiple={false}
listType="picture"
showUploadList={false}
beforeUpload={this.beforeUpload}
onChange={this.handleFileUpload}
>
<Icons.CloudUploadOutlined />
<span>Drop your file here o click for upload</span>
</antd.Upload.Dragger>
</div>
) : (
<>
<div className={styles.titleAvatar}>
<img src={userData.avatar} />
</div>
<antd.Input.TextArea
disabled={this.state.posting ? true : false}
onPressEnter={this.handlePublishPost}
value={this.state.rawtext}
autoSize={{ minRows: 3, maxRows: 5 }}
dragable="false"
placeholder="What are you thinking?"
onChange={this.handleChanges}
allowClear
maxLength={ycore.AppSettings.MaxLengthPosts}
rows={8}
/>
<div>
<antd.Button
disabled={this.state.posting ? true : !this.canPost()}
onClick={this.handlePublishPost}
type="primary"
icon={
this.state.posting_ok ? (
<Icons.CheckCircleOutlined />
) : this.state.posting ? (
<Icons.LoadingOutlined />
) : (
<Icons.ExportOutlined />
)
}
/>
</div>
</>
)}
</div>
<div className={styles.progressHandler}>
<antd.Progress
strokeWidth="4px"
className={
this.state.posting
? styles.proccessUnset
: keys_remaining < 512
? styles.proccessSet
: styles.proccessUnset
}
status={this.handleKeysProgressBar()}
showInfo={false}
percent={percent}
/>
</div>
{fileURL ? this.renderPostPlayer(this.state.fileURL) : null}
<div className={styles.postExtra}>
<antd.Button
styles={this.state.uploader ? { fontSize: '20px' } : null}
type="ghost"
onClick={() => this.ToogleUpload()}
>
{' '}
{this.state.uploader ? (
<MICONS.Cancel />
) : (
<MICONS.AddCircle />
)}{' '}
</antd.Button>
<antd.Button type="ghost" onClick={() => optionBox.toogle()}>
<MICONS.Tune />
</antd.Button>
<antd.Dropdown overlay={shareOptionsMenu}>
<a
className={styles.shareWith}
onClick={e => e.preventDefault()}
>
{ycore.GetPostPrivacy.decorator(this.state.shareWith)}
</a>
</antd.Dropdown>
</div>
</antd.Card>
<Post_options visible={this.state.toolbox_open} />
</div>
)
}
return null
}
}
export default PostCreator

View File

@ -1,270 +1,313 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.cardWrapper{ .cardWrapper {
// box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15); // box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px; border-radius: 7px;
max-width: 510px; max-width: 510px;
min-width: 265px; min-width: 265px;
width: auto; width: auto;
margin: 7px auto 50px auto; margin: 7px auto 50px auto;
:global{
textarea{ :global {
font-weight: 500; textarea {
resize: none; font-weight: 500;
} resize: none;
textarea:focus {
outline: none !important;
border: 0 !important;
}
textarea:hover {
outline: none !important;
border: 0 !important;
}
.ant-card-meta-detail > div:not(:last-child){
margin: 0
}
.ant-card {
border-radius: 7px;
border: 0;
border-top: 1px solid #4646460c;
}
.ant-card-body {
padding: 5px 15px 5px 15px;
}
.ant-card-actions {
border-top: 0;
background: #EBEBEB;
opacity: 0;
height: 30px;
position: relative;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
border-radius: 0 0 10px 10px;
}
.ant-card-actions:hover {
opacity: 1;
transform: translate(0, 15px);
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
}
.ant-card-actions > li {
margin: -20px 0 0 0 ;
border-right: 0;
i{
vertical-align: middle;
height: 40px;
width: 40px;
background-color: #fff;
border-radius: 24px;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
}
} }
textarea:focus {
outline: none !important;
border: 0 !important;
}
textarea:hover {
outline: none !important;
border: 0 !important;
}
.ant-card-meta-detail>div:not(:last-child) {
margin: 0
}
.ant-card {
border-radius: 7px;
border: 0;
border-top: 1px solid #4646460c;
}
.ant-card-body {
padding: 5px 15px 5px 15px;
}
.ant-card-actions {
border-top: 0;
background: #EBEBEB;
opacity: 0;
height: 30px;
position: relative;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
border-radius: 0 0 10px 10px;
}
.ant-card-actions:hover {
opacity: 1;
transform: translate(0, 15px);
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
}
.ant-card-actions>li {
margin: -20px 0 0 0;
border-right: 0;
i {
vertical-align: middle;
height: 40px;
width: 40px;
background-color: #fff;
border-radius: 24px;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
}
}
} }
.titleAvatar{ .titleAvatar {
width: 45px; width: 45px;
height: 45px; height: 45px;
display: flex; display: flex;
:global{
img{ :global {
width: 45px; img {
height: 45px; width: 45px;
border-radius: 12px; height: 45px;
} border-radius: 12px;
} }
}
} }
.inputWrapper{ .inputWrapper {
display: flex; display: flex;
z-index: 10; z-index: 10;
position: relative; position: relative;
width: 100%; width: 100%;
padding: 18px 7px 0 7px; padding: 18px 7px 0 7px;
transition: height 150ms linear; transition: height 150ms linear;
:global{
.ant-btn-primary { :global {
z-index: 10; .ant-btn-primary {
position: relative; z-index: 10;
border-radius: 0 10px 10px 0; position: relative;
height: 100%; border-radius: 0 10px 10px 0;
vertical-align: bottom; height: 100%;
border: none; vertical-align: bottom;
box-shadow: none; border: none;
} box-shadow: none;
.ant-input {
z-index: 10;
position: relative;
border-color: transparent !important;
box-shadow: none;
border-radius: 3px 0 0 0;
height: 100%;
padding: 5px 10px 5px 10px;
transition: height 150ms linear;
width: 100%;
}
.ant-input:hover{
border-color: #1890ff;
}
.ant-input-affix-wrapper{
height: 100%;
}
} }
.ant-input {
z-index: 10;
position: relative;
border-color: transparent !important;
box-shadow: none;
border-radius: 3px 0 0 0;
height: 100%;
padding: 5px 10px 5px 10px;
transition: height 150ms linear;
width: 100%;
}
.ant-input:hover {
border-color: #1890ff;
}
.ant-input-affix-wrapper {
height: 100%;
}
}
} }
.progressHandler{ .progressHandler {
z-index: 10; z-index: 10;
position: relative; position: relative;
margin: 0 7px 0 7px; margin: 0 7px 0 7px;
:global{
.ant-progress-bg{ :global {
border-radius: 0 0 10px 10px; .ant-progress-bg {
} border-radius: 0 0 10px 10px;
.ant-progress-inner{
border-radius: 0 0 14px 14px;
width: calc(100% - 32px);
vertical-align: top;
}
} }
.ant-progress-inner {
border-radius: 0 0 14px 14px;
width: calc(100% - 32px);
vertical-align: top;
}
}
} }
.postExtra{ .postExtra {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative; position: relative;
margin: 0 0 40px 0; margin: 0 0 40px 0;
.shareWith{
color: rgb(53, 53, 53); .shareWith {
float: right; color: rgb(53, 53, 53);
font-size: 11px; float: right;
line-height: 30px; font-size: 11px;
line-height: 30px;
}
:global {
.MuiSvgIcon-root {
width: 1em;
height: 1em;
display: inline-block;
font-size: 18px;
transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
flex-shrink: 0;
margin: 8px;
line-height: 1px;
user-select: none;
} }
:global{
.MuiSvgIcon-root { .ant-btn .anticon {
width: 1em; transition: margin-left 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
height: 1em; margin: 8px;
display: inline-block;
font-size: 18px;
transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
flex-shrink: 0;
margin: 8px;
line-height: 1px;
user-select: none;
}
.ant-btn .anticon {
transition: margin-left 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
margin: 8px;
}
.ant-btn{
width: 35px;
height: 35px;
float: left;
padding: 0;
border-radius: 11px;
margin: 0 10px;
background-color: #eeeeee;
border-color: transparent;
}
.ant-btn:hover{
border-color: transparent;
}
} }
.ant-btn {
width: 35px;
height: 35px;
float: left;
padding: 0;
border-radius: 11px;
margin: 0 10px;
background-color: #eeeeee;
border-color: transparent;
}
.ant-btn:hover {
border-color: transparent;
}
}
} }
.uploader { .uploader {
display: flex; display: flex;
position: relative; position: relative;
border-radius: 10px; border-radius: 10px;
z-index: 30; z-index: 30;
width: 100%;
height: 100%;
span {
width: 100%; width: 100%;
height: 100%; }
span{
width: 100%; :global {
.ant-upload.ant-upload-drag {
background: #fafafa;
border: 1px dashed #d9d9d9;
border-radius: 12px;
transition: border-color 0.3s;
} }
:global{
.ant-upload.ant-upload-drag { .anticon svg {
background: #fafafa; display: inline-block;
border: 1px dashed #d9d9d9; font-size: 30px;
border-radius: 12px;
transition: border-color 0.3s;
}
.anticon svg {
display: inline-block;
font-size: 30px;
}
} }
}
} }
.imagePreviewWrapper{ .imagePreviewWrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
// top: -100px; // top: -100px;
margin: 0 0 15px 0; margin: 0 0 15px 0;
background-color: #eeeeee; background-color: #eeeeee;
.imagePreview{
z-index: 5;
position: relative;
width: 50%;
margin: auto;
border-radius: 8px;
transition: all 150ms linear;
img{
width: 100%;
border: 0.5px rgba(56, 56, 56, 0.459) solid;
}
video{
width: 100%;
border: 0.5px rgba(56, 56, 56, 0.459) solid;
}
transition: all 150ms linear;
} .imagePreview {
.imageOverlay{ z-index: 5;
z-index: 10; position: relative;
position: relative; width: 50%;
opacity: 0; margin: auto;
transition: all 150ms linear; border-radius: 8px;
margin: auto;
}
}
.imagePreviewWrapper:hover .imagePreview{
opacity: 0.5;
transition: all 150ms linear;
}
.imagePreviewWrapper:hover .imageOverlay{
opacity: 1;
transition: all 150ms linear; transition: all 150ms linear;
} img {
width: 100%;
border: 0.5px rgba(56, 56, 56, 0.459) solid;
}
.proccessUnset{ video {
width: 100%;
border: 0.5px rgba(56, 56, 56, 0.459) solid;
}
transition: all 150ms linear;
}
.imageOverlay {
z-index: 10;
position: relative;
opacity: 0; opacity: 0;
transition: opacity 250ms linear; transition: all 150ms linear;
animation: proccessUnset 250ms linear; margin: auto;
}
} }
.proccessSet{ .imagePreviewWrapper:hover .imagePreview {
transition: opacity 250ms linear; opacity: 0.5;
animation: proccessSet 250ms linear; transition: all 150ms linear;
}
.imagePreviewWrapper:hover .imageOverlay {
opacity: 1;
transition: all 150ms linear;
}
.proccessUnset {
opacity: 0;
transition: opacity 250ms linear;
animation: proccessUnset 250ms linear;
}
.proccessSet {
transition: opacity 250ms linear;
animation: proccessSet 250ms linear;
} }
@keyframes proccessSet { @keyframes proccessSet {
0% { opacity: 0; } 0% {
100% { opacity: 1; } opacity: 0;
}
100% {
opacity: 1;
}
} }
@keyframes proccessUnset { @keyframes proccessUnset {
0% { opacity: 1; } 0% {
100% { opacity: 0; } opacity: 1;
} }
.fontct{ 100% {
font-family: "Poppins", sans-serif; opacity: 0;
} }
}
.fontct {
font-family: "Poppins", sans-serif;
}

View File

@ -5,121 +5,146 @@ import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import { Post_Options } from 'globals/post_options.js' import { Post_Options } from 'globals/post_options.js'
import styles from './post_options.less' import styles from './post_options.less'
import moment from 'moment';
export const optionBox = {
const dateFormat = 'YYYY-MM-DD'; toogle: () => {
const { MonthPicker, RangePicker } = antd.DatePicker; window.postoptions_box_class.handleToggleToolbox()
export function toogleOptionsBox(){
window.postoptions_box_class.setState({
options_box: !window.postoptions_box_class.state.options_box
})
return true return true
},
get: () => {
return window.postoptions_box_class.state.options_repo
},
} }
export default class Post_options extends React.Component {
constructor(props) {
super(props), (window.postoptions_box_class = this)
this.state = {
options_repo: Post_Options,
options_box: false,
}
}
onChangeOption(checked, id) {
console.log(`${id} to ${checked}`)
}
export default class Post_options extends React.Component{ handleToggleToolbox = () => {
constructor(props){ this.setState({ options_box: !this.state.options_box })
super(props), }
window.postoptions_box_class = this;
this.state = { onChangeSwitch(item) {
options_repo: Post_Options, try {
options_box: false, const to = !item.value
Schedule: false, const updatedValue = [...this.state.options_repo].map(ita =>
ita === item ? Object.assign(ita, { value: to }) : ita
)
this.setState({ options_repo: updatedValue, forSave: true })
ycore.yconsole.log(`Changing ${item.key} to value ${to}`)
} catch (err) {
console.log(err)
}
}
require(i) {
if (i) {
try {
switch (i) {
case 'pro':
return ycore.IsThisUser.pro() ? false : true
case 'dev':
return ycore.IsThisUser.dev() ? false : true
default:
break
} }
} catch (err) {
ycore.notify.error(err)
return true
}
} }
return false
onChangeOption(checked, id) { }
console.log(`${id} to ${checked}`);
}
handleToggleToolbox = () =>{ rendersets = item => {
this.setState({ options_box: !this.state.options_box }) let e = item.type
} switch (e) {
case 'switch':
onChangeSwitch(item) {
try {
const to = !item.value
const updatedValue = [...this.state.options_repo]
.map(ita => ita === item? Object.assign(ita, { "value": to }) : ita);
this.setState({options_repo: updatedValue, forSave: true})
ycore.yconsole.log(`Changing ${item.option} to value ${to}`)
} catch (err) {
console.log(err)
}
}
require(i){
if (i) {
try {
switch (i) {
case 'pro':
return ycore.IsThisUser.pro()? false : true
case 'dev':
return ycore.IsThisUser.dev()? false : true
default:
break;
}
} catch (err) {
ycore.notifyError(err)
return true
}
}
return false
}
rendersets = (item) => {
let e = item.type
switch (e) {
case 'switch':
return <antd.Switch disabled={this.require(item.require)} checkedChildren={'Enabled'} unCheckedChildren={'Disabled'} checked={item.value} onChange={() => this.onChangeSwitch(item)} />
default:
break;
}
}
renderSettings = () => {
return ( return (
<antd.List <antd.Switch
itemLayout="horizontal" disabled={this.require(item.require)}
split="true" checkedChildren={'Enabled'}
dataSource={this.state.options_repo} unCheckedChildren={'Disabled'}
renderItem={item => ( checked={item.value}
<antd.List.Item actions={item.actions} key={item.SettingID} > onChange={() => this.onChangeSwitch(item)}
<div className={styles.optionItemIcon}> {item.icon} </div>
<antd.List.Item.Meta title={item.title} description={item.description} />
{this.require(item.require)? `You need ${item.require}` : this.rendersets(item)}
</antd.List.Item>
)}
/> />
) )
default:
break
} }
render(){ }
return(
<div className={styles.optionsWrapper}> renderSettings = () => {
<antd.Drawer return (
className={styles.optionsWrapper} <antd.List
placement="top" itemLayout="horizontal"
closable={true} split="true"
onClose={this.handleToggleToolbox} dataSource={this.state.options_repo}
visible={this.state.options_box} renderItem={item => (
> <antd.List.Item actions={item.actions} key={item.key}>
<h1><Icons.SendOutlined /> Post Options</h1><br/> <div className={styles.optionItemIcon}> {item.icon} </div>
<div className={styles.PostOptionsWrapper}> <antd.List.Item.Meta
<div className={styles.optionItem}> title={item.title}
<h3>Share Options</h3> description={item.description}
{this.renderSettings()} />
</div> {this.require(item.require)
<div className={styles.optionItem}> ? `You need ${item.require}`
<h3>Add some Extra</h3> : this.rendersets(item)}
<antd.Button icon={<Icons.ProfileOutlined />} disabled={true} type="primary"> Insert an Poll </antd.Button> </antd.List.Item>
<antd.Button icon={<Icons.ProfileOutlined />} disabled={true} type="primary" > Insert an Background </antd.Button> )}
</div> />
</div> )
</antd.Drawer> }
render() {
return (
<div className={styles.optionsWrapper}>
<antd.Drawer
className={styles.optionsWrapper}
placement="top"
closable={true}
onClose={this.handleToggleToolbox}
visible={this.state.options_box}
>
<h1>
<Icons.SendOutlined /> Post Options
</h1>
<br />
<div className={styles.PostOptionsWrapper}>
<div className={styles.optionItem}>
<h3>Share Options</h3>
{this.renderSettings()}
</div> </div>
) <div className={styles.optionItem}>
} <h3>Add some Extra</h3>
} <antd.Button
icon={<Icons.ProfileOutlined />}
disabled={true}
type="primary"
>
{' '}
Insert an Poll{' '}
</antd.Button>
<antd.Button
icon={<Icons.ProfileOutlined />}
disabled={true}
type="primary"
>
{' '}
Insert an Background{' '}
</antd.Button>
</div>
</div>
</antd.Drawer>
</div>
)
}
}

View File

@ -1,47 +1,57 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.optionsWrapper{ .optionsWrapper {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
:global{
.ant-drawer-body { :global {
-ms-flex-positive: 1; .ant-drawer-body {
flex-grow: 1; -ms-flex-positive: 1;
padding: 12px; flex-grow: 1;
overflow: auto; padding: 12px;
font-size: 14px; overflow: auto;
line-height: 1.5715; font-size: 14px;
word-wrap: break-word; line-height: 1.5715;
} word-wrap: break-word;
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
}
.ant-list-item {
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 8px 0;
}
} }
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0;
margin-bottom: 0;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
}
.ant-list-item {
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 8px 0;
}
}
} }
.PostOptionsWrapper{ .PostOptionsWrapper {
margin: 0 10px 0 10px; margin: 0 10px 0 10px;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
grid-column-gap: 20px; grid-column-gap: 20px;
grid-row-gap: 20px; grid-row-gap: 20px;
justify-items: stretch; justify-items: stretch;
align-items: stretch; align-items: stretch;
.optionItem{
display: inline; .optionItem {
} display: inline;
}
} }
.optionItemIcon{
margin: 0 5px 0 0; .optionItemIcon {
margin: 0 5px 0 0;
} }

View File

@ -1,18 +1,20 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
:global { :global {
.ps--active-x > .ps__rail-x,
.ps--active-y > .ps__rail-y { .ps--active-x>.ps__rail-x,
.ps--active-y>.ps__rail-y {
background-color: red; background-color: red;
} }
.ps__rail-x:hover > .ps__thumb-x, .ps__rail-x:hover>.ps__thumb-x,
.ps__rail-x:focus > .ps__thumb-x { .ps__rail-x:focus>.ps__thumb-x {
height: 8px; height: 8px;
} }
.ps__rail-y:hover > .ps__thumb-y, .ps__rail-y:hover>.ps__thumb-y,
.ps__rail-y:focus > .ps__thumb-y { .ps__rail-y:focus>.ps__thumb-y {
width: 8px; width: 8px;
} }

View File

@ -2,63 +2,87 @@ import React from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import styles from './index.less' import styles from './index.less'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import { CustomIcons } from 'components' import { CustomIcons } from 'components'
const { Meta } = antd.Card; const { Meta } = antd.Card
class SearchCard extends React.PureComponent {
render() {
const { source } = this.props
const { username, avatar, about, id } = source
const DevInfo = `ID #${id} | Dev ${
ycore.booleanFix(source.dev) ? 'yes' : 'no'
} | `
const AdminInfo = `RID #${source.country_id} | IP ${source.ip_address} | `
class SearchCard extends React.PureComponent{ const DataStrip = {
render(){ title: e => {
const { source, } = this.props if (this.props.type == 'Users') {
const { username, avatar, about, id } = source; return `@${username}`
const DevInfo = `ID #${id} | Dev ${ycore.booleanFix(source.dev)? 'yes' : 'no'} | `
const AdminInfo = `RID #${source.country_id} | IP ${source.ip_address} | `
const DataStrip = {
title: (e) => {
if( this.props.type == 'Users'){
return (`@${username}`)
}
if( this.props.type == 'Groups'){
return (`${source.name}`)
}
return null
},
description: (e) => {
if( this.props.type == 'Users'){
return (`${DevInfo}${AdminInfo}`)
}
if( this.props.type == 'Groups'){
return (`GID #${source.group_id} | Created ${source.registered} | CAT ID #${source.category_id} / ${source.category} |`)
}
return null
},
about: (e) => {
return( about )
}
} }
return( if (this.props.type == 'Groups') {
<div className={styles.cardWrapper}> return `${source.name}`
<antd.Card > }
<Meta return null
avatar={<div className={styles.postAvatar}><antd.Avatar shape="square" size={50} src={avatar} /></div>} },
title={ description: e => {
<div className={styles.titleWrapper} > if (this.props.type == 'Users') {
<h4 onClick={() => ycore.crouter.native(`@${username}`)} className={styles.titleUser}>{DataStrip.title()}</h4> return `${DevInfo}${AdminInfo}`
<antd.Tooltip title="User Verified">{ycore.booleanFix(source.verified)? <Icon style={{ color: 'blue', verticalAlign:'top' }} component={CustomIcons.VerifiedBadge} /> : null} </antd.Tooltip> }
</div>} if (this.props.type == 'Groups') {
description={ycore.IsThisUser.dev()? <span className={styles.textAgo}>{DataStrip.description()}</span> : null} return `GID #${source.group_id} | Created ${source.registered} | CAT ID #${source.category_id} / ${source.category} |`
bordered="false" }
/> return null
<div className={styles.postContent}> <h3 dangerouslySetInnerHTML={{__html: DataStrip.about() }} /> </div> },
about: e => {
return about
},
</antd.Card>
</div>
)
} }
return (
<div className={styles.cardWrapper}>
<antd.Card>
<Meta
avatar={
<div className={styles.postAvatar}>
<antd.Avatar shape="square" size={50} src={avatar} />
</div>
}
title={
<div className={styles.titleWrapper}>
<h4
onClick={() => ycore.crouter.native(`@${username}`)}
className={styles.titleUser}
>
{DataStrip.title()}
</h4>
<antd.Tooltip title="User Verified">
{ycore.booleanFix(source.verified) ? (
<Icon
style={{ color: 'blue', verticalAlign: 'top' }}
component={CustomIcons.VerifiedBadge}
/>
) : null}{' '}
</antd.Tooltip>
</div>
}
description={
ycore.IsThisUser.dev() ? (
<span className={styles.textAgo}>
{DataStrip.description()}
</span>
) : null
}
bordered="false"
/>
<div className={styles.postContent}>
{' '}
<h3 dangerouslySetInnerHTML={{ __html: DataStrip.about() }} />{' '}
</div>
</antd.Card>
</div>
)
}
} }
export default SearchCard export default SearchCard

View File

@ -1,143 +1,169 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.cardWrapper{
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15); .cardWrapper {
display: flex; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px; display: flex;
max-width: 510px; border-radius: 7px;
min-width: 265px; max-width: 510px;
width: auto; min-width: 265px;
margin: 23px auto 50px auto; width: auto;
:global{ margin: 23px auto 50px auto;
.ant-card-meta-detail > div:not(:last-child){
margin: 0 :global {
} .ant-card-meta-detail>div:not(:last-child) {
.ant-card { margin: 0
border-radius: 7px;
border: 0;
border-top: 1px solid #4646460c;
}
.ant-card-body {
padding: 13px 0 5px 0;
}
.ant-card-actions {
border-top: 0;
background: #EBEBEB;
opacity: 0;
height: 30px;
position: relative;
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
border-radius: 0 0 10px 10px;
}
.ant-card-actions:hover {
opacity: 1;
transform: translate(0, 15px);
transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
}
.ant-card-actions > li {
margin: -20px 0 0 0 ;
border-right: 0;
i{
vertical-align: middle;
height: 40px;
width: 40px;
background-color: #fff;
border-radius: 24px;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
}
} }
}
.postAvatar{ .ant-card {
position: absolute; border-radius: 7px;
left: -8px; border: 0;
top: -8px; border-top: 1px solid #4646460c;
display: flex;
}
.titleUser{
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
}
.textAgo{
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags{
float: right;
color:rgb(249, 179, 64);
width: 100%;
z-index: 10;
i{
float: right;
margin: -0 6px 0 0;;
font-size: 17px;
} }
}
.titleWrapper{ .ant-card-body {
display: flex; padding: 13px 0 5px 0;
h4{
cursor: pointer;
} }
}
.postContent{ .ant-card-actions {
word-break: break-all; border-top: 0;
display: flex; background: #EBEBEB;
border-radius: 3px; opacity: 0;
margin: 23px 24px 23px 24px; height: 30px;
h3{ position: relative;
color: rgb(85, 85, 85); transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
font-weight: 470; border-radius: 0 0 10px 10px;
} }
}
.postContentFILE{ .ant-card-actions:hover {
display: flex; opacity: 1;
margin: 23px 0 5px 0; transform: translate(0, 15px);
max-height: 600px; transition: opacity 150ms linear, position 150ms linear, transform 150ms linear;
overflow: hidden;
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto;
} }
video {
max-height: 600px; .ant-card-actions>li {
width: calc(100% + 30px); margin: -20px 0 0 0;
overflow: hidden; border-right: 0;
i {
vertical-align: middle;
height: 40px;
width: 40px;
background-color: #fff;
border-radius: 24px;
}
svg {
height: 20px;
width: 20px;
height: 100%;
vertical-align: middle;
}
} }
h3{ }
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.likebtn{
:global{
svg{
color:rgba(0, 0, 0, 0.45);
}
svg:hover{
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
} }
.ellipsisIcon{ .postAvatar {
color:rgba(0, 0, 0, 0.45); position: absolute;
width: 100%; left: -8px;
position: absolute; top: -8px;
text-align: center; display: flex;
margin: auto;
font-size: 30px;
transition: opacity 150ms linear;
} }
.ellipsisIcon:hover{
opacity: 0; .titleUser {
transition: opacity 150ms linear; display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
}
.textAgo {
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags {
float: right;
color: rgb(249, 179, 64);
width: 100%;
z-index: 10;
i {
float: right;
margin: -0 6px 0 0;
;
font-size: 17px;
}
}
.titleWrapper {
display: flex;
h4 {
cursor: pointer;
}
}
.postContent {
word-break: break-all;
display: flex;
border-radius: 3px;
margin: 23px 24px 23px 24px;
h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.postContentFILE {
display: flex;
margin: 23px 0 5px 0;
max-height: 600px;
overflow: hidden;
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto;
}
video {
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.likebtn {
:global {
svg {
color: rgba(0, 0, 0, 0.45);
}
svg:hover {
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
}
.ellipsisIcon {
color: rgba(0, 0, 0, 0.45);
width: 100%;
position: absolute;
text-align: center;
margin: auto;
font-size: 30px;
transition: opacity 150ms linear;
}
.ellipsisIcon:hover {
opacity: 0;
transition: opacity 150ms linear;
} }

View File

@ -5,15 +5,25 @@ import * as ycore from 'ycore'
import { BadgesType } from 'globals/badges_list' import { BadgesType } from 'globals/badges_list'
export default class UserBadges extends React.Component { export default class UserBadges extends React.Component {
render(){ render() {
const { values } = this.props; const { values } = this.props
console.log(BadgesType) console.log(BadgesType)
return( return (
<div className={styles.TagWrappers}> <div className={styles.TagWrappers}>
{ycore.booleanFix(values.nsfw_flag)? <antd.Tag color="volcano" >NSFW</antd.Tag> : null} {ycore.booleanFix(values.nsfw_flag) ? (
{ycore.booleanFix(values.is_pro)? <antd.Tag color="purple">CPRO <Icons.RocketOutlined /></antd.Tag> : null} <antd.Tag color="volcano">NSFW</antd.Tag>
{ycore.booleanFix(values.dev)? <antd.Tag color="default">DEVELOPER <Icons.CodeOutlined /></antd.Tag> : null} ) : null}
</div> {ycore.booleanFix(values.is_pro) ? (
) <antd.Tag color="purple">
} CPRO <Icons.RocketOutlined />
} </antd.Tag>
) : null}
{ycore.booleanFix(values.dev) ? (
<antd.Tag color="default">
DEVELOPER <Icons.CodeOutlined />
</antd.Tag>
) : null}
</div>
)
}
}

View File

@ -2,10 +2,16 @@ import React from 'react'
import styles from './Follow_btn.scss' import styles from './Follow_btn.scss'
import classnames from 'classnames' import classnames from 'classnames'
export default class Follow_btn extends React.Component{ export default class Follow_btn extends React.Component {
render(){ render() {
return( return (
<a className={classnames(styles.like_btn, {[styles.nofollowed]: !this.props.followed})} ><span>{this.props.followed? 'Following' : 'Follow'}</span></a> <a
) className={classnames(styles.like_btn, {
} [styles.nofollowed]: !this.props.followed,
} })}
>
<span>{this.props.followed ? 'Following' : 'Follow'}</span>
</a>
)
}
}

View File

@ -1,4 +1,4 @@
$width: 120px; $width: 120px;
$height: 40px; $height: 40px;
$border: 0; $border: 0;
@ -7,36 +7,36 @@ $orange: #ff7159;
$border-radius: 8px; $border-radius: 8px;
$deg: 120deg; $deg: 120deg;
$size: 400%; $size: 400%;
$dur: 15s; $dur: 15s;
@mixin clip-frame($width, $height, $border) { @mixin clip-frame($width, $height, $border) {
-webkit-clip-path: polygon(0% 100%, $border 100%, $border $border, $width - $border $border, $width - $border $height - $border, $border $height - $border, $border 100%, 100% 100%, 100% 0%, 0% 0%); -webkit-clip-path: polygon(0% 100%, $border 100%, $border $border, $width - $border $border, $width - $border $height - $border, $border $height - $border, $border 100%, 100% 100%, 100% 0%, 0% 0%);
} }
.like_btn { .like_btn {
width: 100px; width: 100px;
height: 30px; height: 30px;
line-height: 28px; line-height: 28px;
padding: 5px 15px 5px 15px; padding: 5px 15px 5px 15px;
@extend .text-formatting; @extend .text-formatting;
&:hover {
color: #7e7e7e;
}
&.nofollowed {
&:hover { &:hover {
color: #7e7e7e; border: none;
} content: '';
color: white;
&.nofollowed{ border-radius: $border-radius;
&:hover { background: linear-gradient($deg, $violet, $orange, $violet);
border: none; background-size: $size $size;
content: ''; animation: gradient $dur ease-in-out infinite, border 1s forwards ease-in-out reverse;
color: white;
border-radius: $border-radius;
background: linear-gradient($deg, $violet, $orange, $violet);
background-size: $size $size;
animation: gradient $dur ease-in-out infinite, border 1s forwards ease-in-out reverse;
}
} }
}
} }
/* helpers */ /* helpers */
@ -50,8 +50,16 @@ $dur: 15s;
/* motion */ /* motion */
@keyframes gradient { @keyframes gradient {
0% { background-position: 14% 0%; } 0% {
50% { background-position: 87% 100%; } background-position: 14% 0%;
100% { background-position: 14% 0%; } }
50% {
background-position: 87% 100%;
}
100% {
background-position: 14% 0%;
}
} }

View File

@ -2,126 +2,171 @@ import React from 'react'
import styles from './styles.less' import styles from './styles.less'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {CustomIcons, MainFeed, PostCreator} from 'components' import { CustomIcons, MainFeed, PostCreator } from 'components'
import { SetHeaderSearchType } from 'components/HeaderSearch' import { SetHeaderSearchType } from 'components/HeaderSearch'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import Follow_btn from './components/Follow_btn.js' import Follow_btn from './components/Follow_btn.js'
class UserProfile extends React.Component { class UserProfile extends React.Component {
constructor(props){ constructor(props) {
super(props), super(props),
this.state = { (this.state = {
invalid: false, invalid: false,
UUID: '', UUID: '',
RenderValue: {}, RenderValue: {},
loading: true, loading: true,
Followed: '', Followed: '',
})
}
handleFollowUser = () => {
const payload = { user_id: this.state.UUID }
ycore.comty_user.follow((err, res) => {
if (err) {
return false
} }
} this.setState({ Followed: !this.state.Followed })
return
}, payload)
}
handleFollowUser = () => { componentDidMount() {
const payload = { user_id: this.state.UUID } const { regx } = this.props
ycore.comty_user.follow((err,res)=> { this.initUser(regx)
if (err) { return false } SetHeaderSearchType.disable()
this.setState({Followed: !this.state.Followed}) }
return
}, payload)
}
componentDidMount(){ initUser = e => {
const { regx } = this.props const parsed = e.shift()
this.initUser(regx) const raw = parsed.toString()
SetHeaderSearchType.disable() const string = raw.replace('/@', '')
}
initUser = (e) => { const payload = { key: string }
const parsed = e.shift() ycore.comty_user.find((err, res) => {
const raw = parsed.toString() err ? ycore.notify.error(err) : null
const string = raw.replace('/@', "") try {
const rp = JSON.parse(res)
ycore.yconsole.log(rp)
if (!rp['0']) {
ycore.yconsole.log('Bad response / User not found')
const val = { id: null, username: 'User not found!' }
this.setState({ invalid: true, RenderValue: val, loading: false })
ycore.crouter.native(`main`)
antd.message.warning(`Its seams like @${string} not exist`)
return
}
const c1 = rp['0'].username.toLowerCase()
const c2 = string.toLowerCase()
if (c1 !== c2) {
ycore.yconsole.log(`Using aproximate user! => ${c1} / ${c2}`)
ycore.crouter.native(`@${c1}`)
}
const payload = { key: string } const payload = { id: rp['0'].user_id }
ycore.comty_user.find((err,res)=>{ ycore.comty_user.__tags((err, res) => {
err? ycore.notifyError(err) : null if (err) {
try { ycore.notify.error(err)
const rp = JSON.parse(res) return
ycore.yconsole.log(rp) }
if (!rp['0']) { }, payload)
ycore.yconsole.log('Bad response / User not found')
const val = { id: null, username: 'User not found!'}
this.setState({ invalid: true, RenderValue: val, loading: false })
ycore.crouter.native(`main`)
antd.message.warning(`Its seams like @${string} not exist`);
return
}
const c1 = rp['0'].username.toLowerCase()
const c2 = string.toLowerCase()
if (c1 !== c2) {
ycore.yconsole.log(`Using aproximate user! => ${c1} / ${c2}`)
ycore.crouter.native(`@${c1}`)
}
const payload = { id: rp['0'].user_id } this.setState({
ycore.comty_user.__tags((err,res)=>{ UUID: rp['0'].user_id,
if (err) { RenderValue: rp['0'],
ycore.notifyError(err) loading: false,
return Followed: ycore.booleanFix(rp['0'].is_following),
} })
},payload) } catch (err) {
ycore.notify.error(err)
this.setState({ UUID: rp['0'].user_id, RenderValue: rp['0'], loading: false , Followed: ycore.booleanFix(rp['0'].is_following)}) }
} catch (err) { }, payload)
ycore.notifyError(err) }
}
},payload)
}
UserHeader = (values) => { UserHeader = values => {
return ( return (
<div className={styles.userWrapper}> <div className={styles.userWrapper}>
<div className={styles.UserCover}> <div className={styles.UserCover}>
<img src={values.cover} /> <img src={values.cover} />
</div> </div>
<PageHeaderWrapper content={ <PageHeaderWrapper
content={
<div className={styles.pageHeaderContent}> <div className={styles.pageHeaderContent}>
<div className={styles.avatar}> <div className={styles.avatar}>
<antd.Avatar shape="square" src={values.avatar} /> <antd.Avatar shape="square" src={values.avatar} />
</div> </div>
<div className={styles.content}> <div className={styles.content}>
<div className={styles.TagWrappers}> <div className={styles.TagWrappers}>
{ycore.booleanFix(values.nsfw_flag)? <antd.Tag color="volcano" >NSFW</antd.Tag> : null} {ycore.booleanFix(values.nsfw_flag) ? (
{ycore.booleanFix(values.is_pro)? <antd.Tag color="purple">CPRO <Icons.RocketOutlined /></antd.Tag> : null} <antd.Tag color="volcano">NSFW</antd.Tag>
{ycore.booleanFix(values.dev)? <antd.Tag color="default">DEVELOPER <Icons.CodeOutlined /></antd.Tag> : null} ) : null}
{ycore.booleanFix(values.is_pro) ? (
<antd.Tag color="purple">
CPRO <Icons.RocketOutlined />
</antd.Tag>
) : null}
{ycore.booleanFix(values.dev) ? (
<antd.Tag color="default">
DEVELOPER <Icons.CodeOutlined />
</antd.Tag>
) : null}
</div> </div>
{ycore.IsThisUser.same(values.id)? null : <div className={styles.follow_wrapper} onClick={() => this.handleFollowUser()} ><Follow_btn followed={this.state.Followed? true : false} /></div>} {ycore.IsThisUser.same(values.id) ? null : (
<div
className={styles.follow_wrapper}
onClick={() => this.handleFollowUser()}
>
<Follow_btn followed={this.state.Followed ? true : false} />
</div>
)}
<div className={styles.contentTitle}> <div className={styles.contentTitle}>
<h1 style={{ marginBottom: '0px' }} >{values.username}<antd.Tooltip title="User Verified">{ycore.booleanFix(values.verified)? <Icon style={{ color: 'blue', verticalAlign:'top' }} component={CustomIcons.VerifiedBadge} /> : null}</antd.Tooltip></h1> <h1 style={{ marginBottom: '0px' }}>
<span style={{ fontSize: '14px', fontWeight: '100', lineHeight: '0', marginBottom: '5px' }} dangerouslySetInnerHTML={{__html: values.about }} /> {values.username}
<antd.Tooltip title="User Verified">
{ycore.booleanFix(values.verified) ? (
<Icon
style={{ color: 'blue', verticalAlign: 'top' }}
component={CustomIcons.VerifiedBadge}
/>
) : null}
</antd.Tooltip>
</h1>
<span
style={{
fontSize: '14px',
fontWeight: '100',
lineHeight: '0',
marginBottom: '5px',
}}
dangerouslySetInnerHTML={{ __html: values.about }}
/>
</div> </div>
</div> </div>
</div> </div>
} /> }
</div> />
); </div>
}; )
render(){ }
const { loading, UUID, invalid } = this.state render() {
return( const { loading, UUID, invalid } = this.state
<div> return (
{loading? <antd.Skeleton active /> : <div>
(<div> {loading ? (
{invalid? null: this.UserHeader(this.state.RenderValue)} <antd.Skeleton active />
{ycore.IsThisUser.same(UUID)? <PostCreator userData={ycore.userData()} /> : null} ) : (
<MainFeed get='user' uid={UUID} /> <div>
</div>) {invalid ? null : this.UserHeader(this.state.RenderValue)}
} {ycore.IsThisUser.same(UUID) ? (
</div> <PostCreator userData={ycore.userData()} />
) ) : null}
} <MainFeed get="user" uid={UUID} />
</div>
)}
</div>
)
}
} }
export default UserProfile; export default UserProfile

View File

@ -11,11 +11,13 @@
// ------------------------ // ------------------------
.clearfix() { .clearfix() {
zoom: 1; zoom: 1;
&::before, &::before,
&::after { &::after {
display: table; display: table;
content: ' '; content: ' ';
} }
&::after { &::after {
clear: both; clear: both;
height: 0; height: 0;
@ -24,24 +26,27 @@
} }
} }
.userWrapper{ .userWrapper {
padding: 0 68px 15px 68px; padding: 0 68px 15px 68px;
margin: auto; margin: auto;
:global{
:global {
.ant-page-header-content { .ant-page-header-content {
padding-top: 0; padding-top: 0;
overflow: initial !important; overflow: initial !important;
} }
.ant-page-header { .ant-page-header {
padding: 20px 0 3px 0; padding: 20px 0 3px 0;
} }
.ant-pro-page-header-wrap-page-header-warp { .ant-pro-page-header-wrap-page-header-warp {
border-radius: 0 0 20px 20px; border-radius: 0 0 20px 20px;
} }
} }
} }
.TagWrappers{ .TagWrappers {
width: 100%; width: 100%;
float: right; float: right;
position: relative; position: relative;
@ -54,15 +59,15 @@
margin: -32px auto auto auto; margin: -32px auto auto auto;
max-height: 400px; max-height: 400px;
overflow: hidden; overflow: hidden;
img{ img {
width: calc(100% + 30px); width: calc(100% + 30px);
overflow: hidden; overflow: hidden;
margin: auto; margin: auto;
} }
} }
.follow_wrapper{ .follow_wrapper {
margin: 0 7px 0 7px; margin: 0 7px 0 7px;
position: relative; position: relative;
float: right; float: right;
@ -70,17 +75,20 @@
.avatar { .avatar {
transform: translate(-25px, -45px); transform: translate(-25px, -45px);
& > span {
&>span {
position: relative; position: relative;
z-index: 10; z-index: 10;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
:global{
:global {
.ant-avatar { .ant-avatar {
box-shadow: 13px 13px 17px 4px rgba(69, 69, 69, 0.151); box-shadow: 13px 13px 17px 4px rgba(69, 69, 69, 0.151);
border-radius: 7px; border-radius: 7px;
img{
img {
width: 120px; width: 120px;
} }
} }
@ -90,10 +98,12 @@
.pageHeaderContent { .pageHeaderContent {
vertical-align: top; vertical-align: top;
display: flex; display: flex;
.content { .content {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
color: @text-color-secondary; color: @text-color-secondary;
width: 100%; width: 100%;
.contentTitle { .contentTitle {
padding: 0 10px 10px 0; padding: 0 10px 10px 0;
color: @heading-color; color: @heading-color;
@ -109,6 +119,7 @@
.extraContent { .extraContent {
margin-left: -16px; margin-left: -16px;
} }
.projectList { .projectList {
.projectGrid { .projectGrid {
width: 50%; width: 50%;
@ -120,10 +131,12 @@
.pageHeaderContent { .pageHeaderContent {
display: block; display: block;
margin: 10px; margin: 10px;
.content { .content {
margin-left: 0; margin-left: 0;
} }
} }
.extraContent { .extraContent {
.statItem { .statItem {
float: none; float: none;
@ -138,4 +151,3 @@
} }
} }
} }

View File

@ -2,88 +2,96 @@
.inputform { .inputform {
:global{ :global {
input { input {
height: 50px; height: 50px;
font-size: 16px; font-size: 16px;
border: 2px solid #d1d3d4; border: 2px solid #d1d3d4;
width: 100%; width: 100%;
padding: 12px; padding: 12px;
font-family: "Poppins"; font-family: "Poppins";
border-radius: 6px; border-radius: 6px;
color: black color: black
} }
input:focus {
outline: none; input:focus {
border-color: black; outline: none;
} border-color: black;
} }
}
} }
.check { .check {
animation-delay: 0s; animation-delay: 0s;
} }
.checkmark { .checkmark {
opacity: 0; opacity: 0;
} }
.Oval { .Oval {
opacity: 1; opacity: 1;
transform-origin: 30px 30px; transform-origin: 30px 30px;
stroke-dasharray: 200px; stroke-dasharray: 200px;
transform: rotate(-75deg); transform: rotate(-75deg);
animation: 3s spin infinite ; animation: 3s spin infinite;
stroke-dashoffset: 200; stroke-dashoffset: 200;
/* animation-play-state: paused; */ /* animation-play-state: paused; */
} }
.animateCheck { .animateCheck {
animation: 0.5s check_animation linear forwards; animation: 0.5s check_animation linear forwards;
} }
.animateOvaloop { .animateOvaloop {
animation: 3s spin infinite ; animation: 3s spin infinite;
} }
@keyframes spin{ @keyframes spin {
0%{ 0% {
opacity: 1; opacity: 1;
stroke-dasharray: 360; stroke-dasharray: 360;
stroke-dashoffset: 360; stroke-dashoffset: 360;
transform: rotate(-720deg); transform: rotate(-720deg);
} }
50% {
opacity: 1; 50% {
stroke-dasharray: 360; opacity: 1;
stroke-dashoffset: 260; stroke-dasharray: 360;
transform: rotate(360deg); stroke-dashoffset: 260;
} transform: rotate(360deg);
100%{ }
opacity: 1;
stroke-dasharray: 360; 100% {
stroke-dashoffset: 360; opacity: 1;
transform: rotate(720deg); stroke-dasharray: 360;
stroke-dashoffset: 360;
transform: rotate(720deg);
} }
} }
@keyframes circle_animation { @keyframes circle_animation {
60% { 60% {
opacity: 1; opacity: 1;
} }
100% {
opacity: 1; 100% {
stroke-dasharray: 400px; opacity: 1;
transform: rotate(40deg); stroke-dasharray: 400px;
} transform: rotate(40deg);
} }
@keyframes check_animation { }
0% {
stroke-dasharray: 126; @keyframes check_animation {
stroke-dashoffset: 126; 0% {
stroke-dasharray: 126;
} stroke-dashoffset: 126;
100% {
stroke-dasharray: 45; }
stroke-dashoffset: 94
} 100% {
stroke-dasharray: 45;
stroke-dashoffset: 94
}
} }

View File

@ -1,20 +1,17 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { connect } from 'dva'; import { connect } from 'dva'
import { Form, Icon as LegacyIcon } from '@ant-design/compatible'; import { Form, Icon as LegacyIcon } from '@ant-design/compatible'
import { Button, Input, Drawer } from 'antd'; import { Button, Input, Drawer } from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import styles from './index.less'; import styles from './index.less'
import { ANT_MARK } from 'antd/lib/locale-provider';
import { validateLocaleAndSetLanguage } from 'typescript';
const FormItem = Form.Item const FormItem = Form.Item
@connect(({ loading }) => ({ loading })) @connect(({ loading }) => ({ loading }))
@Form.create() @Form.create()
class YulioID extends Component { class YulioID extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
@ -26,62 +23,79 @@ class YulioID extends Component {
} }
// Handlers & others // Handlers & others
handleUsername(text) { handleUsername(text) {
this.setState({ RawUsername: text.target.value }); this.setState({ RawUsername: text.target.value })
} }
handlePassword(text) { handlePassword(text) {
this.setState({ RawPassword: text.target.value }); this.setState({ RawPassword: text.target.value })
} }
handleRetry = () => { handleRetry = () => {
this.setState({ShowLoading: false, StateException: false, StateIcon: ''}) this.setState({ ShowLoading: false, StateException: false, StateIcon: '' })
} }
handleEnter = (e) => { handleEnter = e => {
this.handleLogin(); this.handleLogin()
} }
handleLogin = () => { handleLogin = () => {
var prefix = '[YID]: '; var prefix = '[YID]: '
const { RawUsername, RawPassword } = this.state; const { RawUsername, RawPassword } = this.state
var EncPassword = btoa(RawPassword); var EncPassword = btoa(RawPassword)
var EncUsername = btoa(RawUsername); var EncUsername = btoa(RawUsername)
if (!EncUsername || !EncPassword) { if (!EncUsername || !EncPassword) {
var message = 'Incomplete information!' var message = 'Incomplete information!'
ycore.yconsole.log(prefix, message) ycore.yconsole.log(prefix, message)
} }
if (EncUsername && EncPassword){ if (EncUsername && EncPassword) {
this.setState({ ShowLoading: true, StateMessage: 'Wait a sec...' }); this.setState({ ShowLoading: true, StateMessage: 'Wait a sec...' })
if (ycore.AppSettings.InfiniteLogin == true) { if (ycore.AppSettings.InfiniteLogin == true) {
ycore.yconsole.log(prefix, 'InfiniteLogin is enabled! Disabled getAuth') ycore.yconsole.log(prefix, 'InfiniteLogin is enabled! Disabled getAuth')
} } else {
else {
ycore.yconsole.log(prefix, 'Initialising login process...') ycore.yconsole.log(prefix, 'Initialising login process...')
ycore.__AppSetup__(EncUsername, EncPassword, (exception, response) => this.handleResponse(response)) const payload = { EncUsername, EncPassword }
ycore.app_session.login((err, res) => {
this.handleResponse(res)
}, payload)
} }
} }
} }
handleResponse = (response) => { handleResponse = response => {
if (response == '200') { if (response == '200') {
this.setState({ StateIcon: 'login', StateMessage: 'Wait a sec...', StateException: false }) this.setState({
StateIcon: 'login',
StateMessage: 'Wait a sec...',
StateException: false,
})
} }
if (response == '400') { if (response == '400') {
this.setState({ StateIcon: 'exclamation-circle', StateMessage: 'Invalid credentials', StateException: true }) this.setState({
StateIcon: 'exclamation-circle',
StateMessage: 'Invalid credentials',
StateException: true,
})
} }
if (response == '404') { if (response == '404') {
this.setState({ StateIcon: 'exclamation-circle', StateMessage: 'Invalid Data', StateException: true }) this.setState({
StateIcon: 'exclamation-circle',
StateMessage: 'Invalid Data',
StateException: true,
})
} }
if (response == '500') { if (response == '500') {
this.setState({ StateIcon: 'cluster', StateMessage: 'Server Error', StateException: true }) this.setState({
StateIcon: 'cluster',
StateMessage: 'Server Error',
StateException: true,
})
} }
} }
render() { render() {
const { visible } = this.props const { visible } = this.props
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form
const { ShowLoading, StateIcon, StateMessage, StateException } = this.state; const { ShowLoading, StateIcon, StateMessage, StateException } = this.state
return ( return (
<div className={styles.loginWrapper}> <div className={styles.loginWrapper}>
<Drawer <Drawer
@ -92,93 +106,134 @@ class YulioID extends Component {
visible={visible} visible={visible}
className={styles.loginWrapper} className={styles.loginWrapper}
> >
<div className={styles.preheader}><h6><img src={"https://api.ragestudio.net/id.svg"} /> YulioID&trade;</h6> <div className={styles.preheader}>
<h1>Login</h1></div> <h6>
<img src={'https://api.ragestudio.net/id.svg'} /> YulioID&trade;
</h6>
<h1>Login</h1>
</div>
<main className={styles.mainlp}> <main className={styles.mainlp}>
<form className={styles.formlogin}> <form className={styles.formlogin}>
{ShowLoading ? ( {ShowLoading ? (
<div style={{ height: '329px' }}> <div style={{ height: '329px' }}>
<div className={styles.spinner__wrapper} id="loadingspn"> <div className={styles.spinner__wrapper} id="loadingspn">
{StateIcon ? (<LegacyIcon type={StateIcon} className={StateException? styles.StateIcon_exception : styles.StateIcon} /> ) : (<LegacyIcon type="loading" style={{ fontSize: 24, margin: '13px' }} spin />)} {StateIcon ? (
<div><br/><br/><br/> <LegacyIcon
<div className={styles.resultbox}> type={StateIcon}
<h6 > {StateMessage} </h6> className={
<Button onClick={() => ycore.RefreshONCE()}> Reload </Button> StateException
{StateException ? <div className={styles.retryBTN}><Button style={{ width: '270px' }} type='dashed' onClick={() => this.handleRetry()}>Retry</Button></div> : null} ? styles.StateIcon_exception
</div> : styles.StateIcon
}
/>
) : (
<LegacyIcon
type="loading"
style={{ fontSize: 24, margin: '13px' }}
spin
/>
)}
<div>
<br />
<br />
<br />
<div className={styles.resultbox}>
<h6> {StateMessage} </h6>
<Button onClick={() => ycore.RefreshONCE()}>
{' '}
Reload{' '}
</Button>
{StateException ? (
<div className={styles.retryBTN}>
<Button
style={{ width: '270px' }}
type="dashed"
onClick={() => this.handleRetry()}
>
Retry
</Button>
</div>
) : null}
</div> </div>
</div> </div>
</div> </div>
) : ( </div>
<div> ) : (
<div className={styles.input__wrapper}> <div>
<label className={styles.labelform}> <div className={styles.input__wrapper}>
<LegacyIcon type="user" style={{ fontSize: '15px' }} />{' '} <label className={styles.labelform}>
Username <LegacyIcon type="user" style={{ fontSize: '15px' }} />{' '}
</label> Username
<FormItem> </label>
{getFieldDecorator('Username', { <FormItem>
rules: [{ required: true }], {getFieldDecorator('Username', {
})( rules: [{ required: true }],
<Input })(
onPressEnter={this.handleEnter} <Input
className={styles.inputform} onPressEnter={this.handleEnter}
type="text" className={styles.inputform}
placeholder="Username" type="text"
onChange={text => { placeholder="Username"
this.handleUsername(text) onChange={text => {
}} this.handleUsername(text)
/> }}
)} />
</FormItem> )}
</div> </FormItem>
<div className={styles.input__wrapper}>
<label className={styles.labelform}>
<LegacyIcon type="unlock" style={{ fontSize: '15px' }} />{' '}
Password
</label>
<FormItem>
{getFieldDecorator('Password', {
rules: [{ required: true }],
})(
<Input.Password
onPressEnter={this.handleEnter}
className={styles.inputform}
placeholder="Password"
onChange={text => {
this.handlePassword(text)
}}
/>
)}
</FormItem>
</div>
<div style={{ margin: 'auto' }}>
<a className={styles.buttonlp} id="login" onClick={this.handleLogin}>
Login
</a>
</div>
<h2
style={{
textAlign: 'center',
margin: '8px',
color: '#666',
}}
>
Or
</h2>
<div className={styles.moreActions}>
<Button type="dashed"><LegacyIcon type="question-circle" /> Forgotten password </Button>
<Button type="dashed" ><LegacyIcon type="user-add" /> Create an account </Button>
</div>
</div> </div>
)} <div className={styles.input__wrapper}>
</form> <label className={styles.labelform}>
<LegacyIcon type="unlock" style={{ fontSize: '15px' }} />{' '}
Password
</label>
<FormItem>
{getFieldDecorator('Password', {
rules: [{ required: true }],
})(
<Input.Password
onPressEnter={this.handleEnter}
className={styles.inputform}
placeholder="Password"
onChange={text => {
this.handlePassword(text)
}}
/>
)}
</FormItem>
</div>
<div style={{ margin: 'auto' }}>
<a
className={styles.buttonlp}
id="login"
onClick={this.handleLogin}
>
Login
</a>
</div>
<h2
style={{
textAlign: 'center',
margin: '8px',
color: '#666',
}}
>
Or
</h2>
<div className={styles.moreActions}>
<Button type="dashed">
<LegacyIcon type="question-circle" /> Forgotten password{' '}
</Button>
<Button type="dashed">
<LegacyIcon type="user-add" /> Create an account{' '}
</Button>
</div>
</div>
)}
</form>
</main> </main>
</Drawer> </Drawer>
</div> </div>
); )
} }
} }

View File

@ -1,433 +1,485 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.loginWrapper{ .loginWrapper {
:global{ :global {
.ant-drawer-right.ant-drawer-open.no-mask { .ant-drawer-right.ant-drawer-open.no-mask {
right: 1px; right: 1px;
-ms-transform: translateX(1px); -ms-transform: translateX(1px);
transform: translateX(1px); transform: translateX(1px);
width: 100%; width: 100%;
} }
.ant-drawer-right.ant-drawer-open .ant-drawer-content-wrapper{
width: 100%; .ant-drawer-right.ant-drawer-open .ant-drawer-content-wrapper {
border-radius: 20px 0 0 20px; width: 100%;
} border-radius: 20px 0 0 20px;
.ant-drawer-body{ }
height: 100%;
} .ant-drawer-body {
.ant-drawer { height: 100%;
box-shadow: none; }
border-radius: 20px 0 0 20px;
max-width: 512px; .ant-drawer {
width: 100%; box-shadow: none;
} border-radius: 20px 0 0 20px;
.ant-drawer-content{ max-width: 512px;
background: #ffffff9f; width: 100%;
border-radius: 20px 0 0 20px; }
}
} .ant-drawer-content {
} background: #ffffff9f;
border-radius: 20px 0 0 20px;
}
}
}
.StateIcon { .StateIcon {
font-size: 24px; font-size: 24px;
margin: 13px; margin: 13px;
} }
.StateIcon_exception {
font-size: 24px;
margin: 13px;
color: red !important;
:global{
i {
color: red !important;
}
}
}
.mainlp {
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
width: 100%;
word-break: keep-all;
color: @foregroundColor;
text-align: left;
}
.mainlp .sectionlp {
border: 1px solid @accentColor;
position: relative;
padding: 40px 40px 50px;
}
.mainlp .sectionlp > h6 {
color: @accentColor;
background: @canvasColor;
position: absolute;
top: -10px;
left: 20px;
padding: 0 10px;
}
.mainlp .sectionlp .h6lp.subheader {
color: @grayColor;
margin-top: 20px;
margin-bottom: 20px;
width: 100%;
}
@media (max-width: 992px) {
section:not(:last-child) {
border-width: 0 0 1px;
}
section:last-child {
border-width: 0;
}
}
.StateIcon_exception {
font-size: 24px;
margin: 13px;
color: red !important;
:global {
i {
color: red !important;
}
}
}
.mainlp {
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
width: 100%;
word-break: keep-all;
color: @foregroundColor;
text-align: left;
}
.mainlp .sectionlp {
border: 1px solid @accentColor;
position: relative;
padding: 40px 40px 50px;
}
.mainlp .sectionlp>h6 {
color: @accentColor;
background: @canvasColor;
position: absolute;
top: -10px;
left: 20px;
padding: 0 10px;
}
.mainlp .sectionlp .h6lp.subheader {
color: @grayColor;
margin-top: 20px;
margin-bottom: 20px;
width: 100%;
}
@media (max-width: 992px) {
section:not(:last-child) {
border-width: 0 0 1px;
}
section:last-child {
border-width: 0;
}
}
.buttons { .buttons {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
} }
.buttons > * {
flex: 1 1 calc(50% - 20px); .buttons>* {
margin-top: 20px; flex: 1 1 calc(50% - 20px);
margin-top: 20px;
} }
.buttons > *:nth-child(odd) {
margin-right: 20px; .buttons>*:nth-child(odd) {
margin-right: 20px;
} }
a.buttonlp, a.buttonlp,
input.buttonlp, input.buttonlp,
.buttonlp { .buttonlp {
outline: none; outline: none;
width: 100%; width: 100%;
text-align: center; text-align: center;
display: inline-block; display: inline-block;
border: none; border: none;
font: 500 16px/1 "Poppins", sans-serif; font: 500 16px/1 "Poppins", sans-serif;
padding: 20px; padding: 20px;
cursor: pointer; cursor: pointer;
border-radius: @borderRadius; border-radius: @borderRadius;
background: @primaryColor; background: @primaryColor;
color: @backgroundColor; color: @backgroundColor;
position: relative; position: relative;
top: 0; top: 0;
transition: 0.2s ease; transition: 0.2s ease;
} }
a.buttonlp:hover, a.buttonlp.hover,
a.buttonlp:hover,
a.buttonlp.hover,
input.buttonlp:hover, input.buttonlp:hover,
input.buttonlp.hover, input.buttonlp.hover,
.buttonlp:hover, .buttonlp:hover,
.buttonlp.hover { .buttonlp.hover {
top: -3px; top: -3px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
} }
a.buttonlp:active, a.buttonlp.active,
a.buttonlp:active,
a.buttonlp.active,
input.buttonlp:active, input.buttonlp:active,
.input.buttonlp.active, .input.buttonlp.active,
.buttonlp:active, .buttonlp:active,
.buttonlp.active { .buttonlp.active {
background: @primaryShade4; background: @primaryShade4;
outline: none; outline: none;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
top: 0; top: 0;
} }
a.buttonlp.disabled, a.buttonlp.disabled,
input.buttonlp.disabled, input.buttonlp.disabled,
.buttonlp.disabled { .buttonlp.disabled {
opacity: 0.4; opacity: 0.4;
user-select: none; user-select: none;
pointer-events: none; pointer-events: none;
} }
a.buttonlp.medium, a.buttonlp.medium,
input.buttonlp.medium, input.buttonlp.medium,
.buttonlp.medium { .buttonlp.medium {
padding: 15px 18px; padding: 15px 18px;
width: auto; width: auto;
} }
a.buttonlp.small, a.buttonlp.small,
input.buttonlp.small, input.buttonlp.small,
.buttonlp.small { .buttonlp.small {
padding: 10px 12px; padding: 10px 12px;
width: auto; width: auto;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
} }
a.buttonlp.secondary, a.buttonlp.secondary,
input.buttonlp.secondary, input.buttonlp.secondary,
.buttonlp.secondary { .buttonlp.secondary {
background: @secondaryColor; background: @secondaryColor;
} }
a.buttonlp.secondary:active, a.buttonlp.secondary:focus, a.buttonlp.secondary.active,
a.buttonlp.secondary:active,
a.buttonlp.secondary:focus,
a.buttonlp.secondary.active,
input.buttonlp.secondary:active, input.buttonlp.secondary:active,
input.buttonlp.secondary:focus, input.buttonlp.secondary:focus,
input.buttonlp.secondary.active, input.buttonlp.secondary.active,
.buttonlp.secondary:active, .buttonlp.secondary:active,
.buttonlp.secondary:focus, .buttonlp.secondary:focus,
.buttonlp.secondary.active { .buttonlp.secondary.active {
background: @secondaryShade4; background: @secondaryShade4;
outline: none; outline: none;
} }
a.buttonlp.accent, a.buttonlp.accent,
input.buttonlp.accent, input.buttonlp.accent,
.buttonlp.accent { .buttonlp.accent {
background: @accentColor; background: @accentColor;
} }
a.buttonlp.accent:active, a.buttonlp.accent:focus, a.buttonlp.accent.active,
a.buttonlp.accent:active,
a.buttonlp.accent:focus,
a.buttonlp.accent.active,
input.buttonlp.accent:active, input.buttonlp.accent:active,
input.buttonlp.accent:focus, input.buttonlp.accent:focus,
input.buttonlp.accent.active, input.buttonlp.accent.active,
.buttonlp.accent:active, .buttonlp.accent:active,
.buttonlp.accent:focus, .buttonlp.accent:focus,
.buttonlp.accent.active { .buttonlp.accent.active {
background: @accentShade4; background: @accentShade4;
} }
a.buttonlp.accent2, a.buttonlp.accent2,
input.buttonlp.accent2, input.buttonlp.accent2,
.buttonlp.accent2 { .buttonlp.accent2 {
background: @accent2Color; background: @accent2Color;
} }
a.buttonlp.accent2:active, a.buttonlp.accent2:focus, a.buttonlp.accent2.active,
a.buttonlp.accent2:active,
a.buttonlp.accent2:focus,
a.buttonlp.accent2.active,
input.buttonlp.accent2:active, input.buttonlp.accent2:active,
input.buttonlp.accent2:focus, input.buttonlp.accent2:focus,
input.buttonlp.accent2.active, input.buttonlp.accent2.active,
.buttonlp.accent2:active, .buttonlp.accent2:active,
.buttonlp.accent2:focus, .buttonlp.accent2:focus,
.buttonlp.accent2.active { .buttonlp.accent2.active {
background: @accent2Shade4; background: @accent2Shade4;
} }
a.buttonlp.accent3, a.buttonlp.accent3,
input.buttonlp.accent3, input.buttonlp.accent3,
.buttonlp.accent3 { .buttonlp.accent3 {
background: @accent3Color; background: @accent3Color;
} }
a.buttonlp.accent3:active, a.buttonlp.accent3:focus, a.buttonlp.accent3.active,
a.buttonlp.accent3:active,
a.buttonlp.accent3:focus,
a.buttonlp.accent3.active,
input.buttonlp.accent3:active, input.buttonlp.accent3:active,
input.buttonlp.accent3:focus, input.buttonlp.accent3:focus,
input.buttonlp.accent3.active, input.buttonlp.accent3.active,
.buttonlp.accent3:active, .buttonlp.accent3:active,
.buttonlp.accent3:focus, .buttonlp.accent3:focus,
.buttonlp.accent3.active { .buttonlp.accent3.active {
background: @accent3Shade4; background: @accent3Shade4;
} }
/*inputs*/ /*inputs*/
.input__wrapper { .input__wrapper {
margin-bottom: 10px; margin-bottom: 10px;
:global{
.ant-col { :global {
width: 100%; .ant-col {
} width: 100%;
} }
}
} }
.inputRG__wrapper { .inputRG__wrapper {
margin-bottom: 0px; margin-bottom: 0px;
} }
.labelform { .labelform {
font-weight: 500; font-weight: 500;
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
} }
.inputform, .inputform,
select, select,
textarea { textarea {
height: 50px; height: 50px;
font-size: 16px; font-size: 16px;
border: 2px solid @neutralShade3; border: 2px solid @neutralShade3;
width: 100%; width: 100%;
padding: 12px; padding: 12px;
font-family: "Poppins"; font-family: "Poppins";
border-radius: @borderRadius; border-radius: @borderRadius;
color: @foregroundColor; color: @foregroundColor;
background: @backgroundColor; background: @backgroundColor;
} }
.inputform:focus, .inputform.active,
.inputform:focus,
.inputform.active,
select:focus, select:focus,
select.active, select.active,
textarea:focus, textarea:focus,
textarea.active { textarea.active {
outline: none; outline: none;
border-color: @primaryColor; border-color: @primaryColor;
} }
.inputform:disabled, .inputform:disabled,
select:disabled, select:disabled,
textarea:disabled { textarea:disabled {
cursor: not-allowed; cursor: not-allowed;
background: @neutralShade1; background: @neutralShade1;
opacity: 0.6; opacity: 0.6;
} }
Input .inputPasswordform { Input .inputPasswordform {
height: 50px; height: 50px;
font-size: 16px; font-size: 16px;
border: 2px solid @neutralShade3; border: 2px solid @neutralShade3;
width: 100%; width: 100%;
padding: 12px; padding: 12px;
font-family: "Poppins"; font-family: "Poppins";
border-radius: @borderRadius; border-radius: @borderRadius;
color: @foregroundColor; color: @foregroundColor;
background: @backgroundColor; background: @backgroundColor;
} }
Input .inputPasswordform:focus { Input .inputPasswordform:focus {
outline: none; outline: none;
border-color: @primaryColor; border-color: @primaryColor;
} }
.inputform.input { .inputform.input {
height: 56px; height: 56px;
font-size: 18px; font-size: 18px;
padding: 15px; padding: 15px;
} }
/*spinner*/ /*spinner*/
.spinner + .labellp { .spinner+.labellp {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
margin-top: 8px; margin-top: 8px;
display: inline-block; display: inline-block;
text-transform: uppercase; text-transform: uppercase;
color: @primaryShade4; color: @primaryShade4;
} }
.spinner1 .spinner { .spinner1 .spinner {
max-width: 50px; max-width: 50px;
margin: auto; margin: auto;
height: 20px; height: 20px;
position: relative; position: relative;
} }
.spinner1 .spinner:after { .spinner1 .spinner:after {
content: ""; content: "";
position: absolute; position: absolute;
width: 20px; width: 20px;
height: 20px; height: 20px;
left: -10%; left: -10%;
background: @primaryColor; background: @primaryColor;
animation: spinnerLeftRight 1s infinite; animation: spinnerLeftRight 1s infinite;
} }
.spinner1 .spinner:before { .spinner1 .spinner:before {
content: ""; content: "";
position: absolute; position: absolute;
width: 20px; width: 20px;
height: 20px; height: 20px;
left: -10%; left: -10%;
background: @primaryShade2; background: @primaryShade2;
opacity: 1; opacity: 1;
animation: spinnerLeftRight 1s infinite 0.06s; animation: spinnerLeftRight 1s infinite 0.06s;
} }
@keyframes spinnerLeftRight { @keyframes spinnerLeftRight {
0% { 0% {
left: 85%; left: 85%;
} }
50% {
left: -10%; 50% {
} left: -10%;
100% { }
left: 85%;
} 100% {
} left: 85%;
}
}
.formlogin { .formlogin {
width: 95%; width: 95%;
height: auto; height: auto;
border-radius: 10px; border-radius: 10px;
padding: 30px; padding: 30px;
box-shadow: 0 3px 15px rgba(51, 51, 51, 0.2); box-shadow: 0 3px 15px rgba(51, 51, 51, 0.2);
background: #ffffff44; background: #ffffff44;
margin: 20px 10px 20px 10px; margin: 20px 10px 20px 10px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
vertical-align: middle; vertical-align: middle;
} }
.formlogin .checkbox { .formlogin .checkbox {
margin-bottom: 30px; margin-bottom: 30px;
} }
.formlogin .spinner__wrapper { .formlogin .spinner__wrapper {
place-items: center; place-items: center;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
left: 0; left: 0;
top: 0; top: 0;
background: rgba(255, 255, 255, 0.85); background: rgba(255, 255, 255, 0.85);
}
.preheader{
position: relative;
top: 0;
h1{
font: 700 48px "Nunito", sans-serif;
text-align: center;
margin-bottom: 10px;
}
h6{
padding: 3em 0 0 0;
line-height: 1px;
display: flex;
font: 500 16px/1 "Poppins", sans-serif;
text-transform: uppercase;
img{
vertical-align: middle;
height: 17px;
}
}
}
.moreActions{
display: flex;
margin: auto;
align-content: center;
position: relative;
width: 100%;
:global{
.ant-btn{
margin: auto;
}
}
}
@media (max-width: 472px) {
.moreActions{
display: grid;
align-content: center;
position: relative;
width: 100%;
:global{
.ant-btn{
margin: 5px;
}
}
}
} }
.resultbox{
h6{ .preheader {
font-family: "Poppins", sans-serif; position: relative;
text-align: center; top: 0;
font-size: 16px;
margin: auto; h1 {
vertical-align: middle; font: 700 48px "Nunito", sans-serif;
} text-align: center;
.retryBTN{ margin-bottom: 10px;
text-align: center; }
width: 100%;
position: absolute; h6 {
bottom: 0; padding: 3em 0 0 0;
margin: auto; line-height: 1px;
vertical-align: bottom; display: flex;
} font: 500 16px/1 "Poppins", sans-serif;
margin: auto; text-transform: uppercase;
}
img {
vertical-align: middle;
height: 17px;
}
}
}
.moreActions {
display: flex;
margin: auto;
align-content: center;
position: relative;
width: 100%;
:global {
.ant-btn {
margin: auto;
}
}
}
@media (max-width: 472px) {
.moreActions {
display: grid;
align-content: center;
position: relative;
width: 100%;
:global {
.ant-btn {
margin: 5px;
}
}
}
}
.resultbox {
h6 {
font-family: "Poppins", sans-serif;
text-align: center;
font-size: 16px;
margin: auto;
vertical-align: middle;
}
.retryBTN {
text-align: center;
width: 100%;
position: absolute;
bottom: 0;
margin: auto;
vertical-align: bottom;
}
margin: auto;
}

View File

@ -5,11 +5,9 @@ import MobileWarning from './MobileWarning'
import CustomIcons from './CustomIcons' import CustomIcons from './CustomIcons'
import Loader from './Loader/Loader.js' import Loader from './Loader/Loader.js'
import ScrollBar from './ScrollBar' import ScrollBar from './ScrollBar'
import Page from './Page'
// App Layout Components // App Layout Components
import * as MyLayout from './Layout/index.js' import * as MyLayout from './Layout/index.js'
import MicroHeader from './MicroHeader'
import HeaderSearch from './HeaderSearch' import HeaderSearch from './HeaderSearch'
import PageTransition from './PageTransition' import PageTransition from './PageTransition'
import YulioID from './YulioID' import YulioID from './YulioID'
@ -22,29 +20,26 @@ import SearchCard from './SearchCard'
// Post Components // Post Components
import MediaPlayer from './MediaPlayer' import MediaPlayer from './MediaPlayer'
import PostCard from './PostCard' import PostCard from './PostCard'
import LikeBTN from './LikeBtn' import Like_button from './Like_button'
import MainFeed from './MainFeed' import MainFeed from './MainFeed'
import PostCreator from './PostCreator' import PostCreator from './PostCreator'
// Mix & Export all // Mix & Export all
export export {
{ MediaPlayer,
MediaPlayer, UserBadges,
UserBadges, MobileWarning,
MobileWarning, PageTransition,
PageTransition, SearchCard,
SearchCard, HeaderSearch,
HeaderSearch, YulioID,
YulioID, UserProfile,
UserProfile, MyLayout,
MyLayout, Loader,
Loader, ScrollBar,
Page, PostCard,
ScrollBar, PostCreator,
PostCard, CustomIcons,
PostCreator, Like_button,
CustomIcons, MainFeed,
LikeBTN,
MainFeed,
MicroHeader
} }

View File

@ -41,7 +41,7 @@ class BaseLayout extends PureComponent {
<Helmet> <Helmet>
<title>{config.siteName}</title> <title>{config.siteName}</title>
</Helmet> </Helmet>
<Container>{children}</Container> <Container>{children}</Container>
</Fragment> </Fragment>
) )
} }

View File

@ -5,6 +5,7 @@
#root { #root {
width: 100%; width: 100%;
} }
#nprogress { #nprogress {
pointer-events: none; pointer-events: none;
@ -58,6 +59,7 @@
position: relative; position: relative;
#nprogress { #nprogress {
.bar, .bar,
.spinner { .spinner {
position: absolute; position: absolute;

View File

@ -4,9 +4,14 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import withRouter from 'umi/withRouter' import withRouter from 'umi/withRouter'
import { connect } from 'dva' import { connect } from 'dva'
import { MyLayout, PageTransition, HeaderSearch, MobileWarning } from 'components' import {
MyLayout,
PageTransition,
HeaderSearch,
MobileWarning,
} from 'components'
import { enquireScreen, unenquireScreen } from 'enquire-js' import { enquireScreen, unenquireScreen } from 'enquire-js'
import store from 'store'; import store from 'store'
import classnames from 'classnames' import classnames from 'classnames'
import * as ycore from 'ycore' import * as ycore from 'ycore'
@ -21,23 +26,23 @@ const { Sider, Control, Secondary, WindowAppBar } = MyLayout
@withRouter @withRouter
@connect(({ app, loading }) => ({ app, loading })) @connect(({ app, loading }) => ({ app, loading }))
class PrimaryLayout extends React.Component { class PrimaryLayout extends React.Component {
constructor(props){ constructor(props) {
super(props) super(props)
window.PrimaryComponent = this; window.PrimaryComponent = this
this.state = { this.state = {
collapsed: (ycore.AppSettings.default_collapse_sider? true : false), collapsed: ycore.AppSettings.default_collapse_sider ? true : false,
isMobile: false, isMobile: false,
desktop_mode: false, desktop_mode: false,
userData: '' userData: '',
} }
} }
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
userData: ycore.userData(), userData: ycore.userData(),
desktop_mode: ycore.CheckThisApp.desktop_mode() desktop_mode: ycore.CheckThisApp.desktop_mode(),
}) })
this.enquireHandler = enquireScreen(mobile => { this.enquireHandler = enquireScreen(mobile => {
const { isMobile } = this.state const { isMobile } = this.state
if (isMobile !== mobile) { if (isMobile !== mobile) {
@ -45,7 +50,7 @@ class PrimaryLayout extends React.Component {
isMobile: mobile, isMobile: mobile,
}) })
} }
}) })
} }
componentWillUnmount() { componentWillUnmount() {
@ -55,24 +60,24 @@ class PrimaryLayout extends React.Component {
onCollapseChange = () => { onCollapseChange = () => {
const fromStore = store.get('collapsed') const fromStore = store.get('collapsed')
this.setState({ collapsed: !this.state.collapsed }) this.setState({ collapsed: !this.state.collapsed })
store.set('collapsed', !fromStore) store.set('collapsed', !fromStore)
} }
isDarkMode = () => { isDarkMode = () => {
const {app} = this.props const { app } = this.props
const { theme } = app const { theme } = app
if (theme == "light") { if (theme == 'light') {
return false; return false
} }
return true; return true
} }
render() { render() {
const { app, location, dispatch, children } = this.props const { app, location, dispatch, children } = this.props
const { userData, collapsed, isMobile, desktop_mode } = this.state const { userData, collapsed, isMobile, desktop_mode } = this.state
const { onCollapseChange } = this const { onCollapseChange } = this
const { theme } = app const { theme } = app
const SiderProps = { const SiderProps = {
desktop_mode: desktop_mode, desktop_mode: desktop_mode,
theme, theme,
@ -95,30 +100,47 @@ class PrimaryLayout extends React.Component {
theme, theme,
} }
return ( return (
<React.Fragment > <React.Fragment>
<div className={classnames(styles.AppWrapper, {[styles.desktop_mode]: desktop_mode})}> <div
{isMobile? <MobileWarning /> : null} className={classnames(styles.AppWrapper, {
<div className={styles.BarControlWrapper}><Control /></div> [styles.desktop_mode]: desktop_mode,
<antd.Layout className={classnames( styles.layout, {[styles.md_dark]: this.isDarkMode(), [styles.desktop_mode]: desktop_mode })}> })}
<Sider {...SiderProps}/> >
{isMobile ? <MobileWarning /> : null}
<div id="primaryLayout" className={styles.leftContainer}> <div className={styles.BarControlWrapper}>
<PageTransition preset="moveToRightScaleUp" id="scroller" transitionKey={location.pathname}> <Control />
<Content className={classnames(styles.content, {[styles.collapsed]: !collapsed} )}>
<HeaderSearch />
{children}
</Content>
</PageTransition>
</div>
<Secondary {...SecondaryProps} />
</antd.Layout>
</div> </div>
</React.Fragment> <antd.Layout
) className={classnames(styles.layout, {
[styles.md_dark]: this.isDarkMode(),
[styles.desktop_mode]: desktop_mode,
})}
>
<Sider {...SiderProps} />
<div id="primaryLayout" className={styles.leftContainer}>
<PageTransition
preset="moveToRightScaleUp"
id="scroller"
transitionKey={location.pathname}
>
<Content
className={classnames(styles.content, {
[styles.collapsed]: !collapsed,
})}
>
<HeaderSearch />
{children}
</Content>
</PageTransition>
</div>
<Secondary {...SecondaryProps} />
</antd.Layout>
</div>
</React.Fragment>
)
} }
} }

View File

@ -1,98 +1,116 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.AppWrapper{ .AppWrapper {
&.desktop_mode{ &.desktop_mode {
padding: 0 30px 0 30px; padding: 0 30px 0 30px;
border-radius: 10px; border-radius: 10px;
} }
} }
.content { .content {
vertical-align: middle; vertical-align: middle;
width: 100%; width: 100%;
float: right; float: right;
padding: 35px 25px 15px 60px; padding: 35px 25px 15px 60px;
transition: all 0.2s ease; transition: all 0.2s ease;
&.collapsed { &.collapsed {
width: ~'calc(100% - 180px)'; width: ~'calc(100% - 180px)';
transition: all 0.2s ease; transition: all 0.2s ease;
} }
} }
.layout{ .layout {
background-color: @Theme-Layout-Backgroud; //#E2E6E9; background-color: @Theme-Layout-Backgroud; //#E2E6E9;
transition: background-color 200ms linear; transition: background-color 200ms linear;
&.desktop_mode{
&.desktop_mode {
border-radius: 12px; border-radius: 12px;
} }
&.md_radius{
&.md_radius {
width: 95%; width: 95%;
margin: auto; margin: auto;
position: relative; position: relative;
border-radius: 15px; border-radius: 15px;
} }
&.md_dark{
&.md_dark {
background-color: @DarkMode-backgroud_container; background-color: @DarkMode-backgroud_container;
color: @DarkMode-color_container; color: @DarkMode-color_container;
transition: background-color 200ms linear; transition: background-color 200ms linear;
:global { :global {
h1{ h1 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
h2{
h2 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
h3{
h3 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
h4{
h4 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
h5{
h5 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
h6{
h6 {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
p{
p {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
span{
span {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
pre{
pre {
color: @DarkMode-color_container; color: @DarkMode-color_container;
} }
.ant-pro-page-header-wrap-page-header-warp { .ant-pro-page-header-wrap-page-header-warp {
color: @DarkMode-color_container; color: @DarkMode-color_container;
background-color: @DarkMode-backgroud_container; background-color: @DarkMode-backgroud_container;
transition: background-color 200ms linear; transition: background-color 200ms linear;
} }
.ant-card{
.ant-card {
background-color: @DarkMode-backgroud; background-color: @DarkMode-backgroud;
} }
.ant-input { .ant-input {
color: @DarkMode-color_container; color: @DarkMode-color_container;
background-color: @DarkMode-backgroud; background-color: @DarkMode-backgroud;
} }
.ant-btn-primary[disabled]{
.ant-btn-primary[disabled] {
color: @DarkMode-color_container; color: @DarkMode-color_container;
background-color: @DarkMode-backgroud; background-color: @DarkMode-backgroud;
} }
transition: background-color 200ms linear; transition: background-color 200ms linear;
} }
} }
} }
.BarControlWrapper{ .BarControlWrapper {
width: 100%; width: 100%;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
z-index: 30; z-index: 30;
} }
.leftContainer{ .leftContainer {
align-self: center; align-self: center;
width: 100vw; width: 100vw;
position: relative; position: relative;
@ -100,12 +118,13 @@
overflow-x: hidden; overflow-x: hidden;
height: 100vh; height: 100vh;
bottom: 0; bottom: 0;
:global{
#scroller{ :global {
overflow-y: scroll !important; #scroller {
overflow-y: scroll !important;
}
} }
}
} }
@ -114,6 +133,7 @@
.content { .content {
padding: 12px; padding: 12px;
} }
.layout { .layout {
height: 100vh; height: 100vh;
flex: 1; flex: 1;

View File

@ -28,7 +28,7 @@ class Layout extends Component {
const language = langFromPath(nextProps.location.pathname) const language = langFromPath(nextProps.location.pathname)
const preLanguage = this.language const preLanguage = this.language
const { catalogs } = nextState const { catalogs } = nextState
if (preLanguage !== language && !catalogs[language]) { if (preLanguage !== language && !catalogs[language]) {
this.loadCatalog(language) this.loadCatalog(language)
this.language = language this.language = language
@ -40,8 +40,10 @@ class Layout extends Component {
} }
loadCatalog = async language => { loadCatalog = async language => {
const catalog = await import(/* webpackMode: "lazy", webpackChunkName: "i18n-[index]" */ const catalog = await import(
`@lingui/loader!../locales/${language}/messages.json`) /* webpackMode: "lazy", webpackChunkName: "i18n-[index]" */
`@lingui/loader!../locales/${language}/messages.json`
)
this.setState(state => ({ this.setState(state => ({
catalogs: { catalogs: {

View File

@ -1,10 +1,7 @@
/* global window */ /* global window */
import { router } from 'utils' import { router } from 'utils'
import { stringify } from 'qs'
import store from 'store' import store from 'store'
import { queryLayout, pathMatchRegexp } from 'utils' import { pathMatchRegexp } from 'utils'
import api from 'api'
import config from 'config' import config from 'config'
import * as ycore from 'ycore' import * as ycore from 'ycore'
@ -44,28 +41,24 @@ export default {
}, },
}, },
effects: { effects: {
*query({payload}, { call, put, select }) { *query({ payload }, { call, put, select }) {
const validBackup = ycore.ValidBackup(); const validBackup = ycore.validate.backup()
if (ycore.ValidLoginSession() == true) { if (ycore.validate.session() == true) {
if (pathMatchRegexp(['/', '/login'], window.location.pathname)) { if (pathMatchRegexp(['/', '/login'], window.location.pathname)) {
router.push({pathname: '/main',}) router.push({ pathname: '/main' })
} }
ycore.MakeBackup() ycore.QueryRuntime()
ycore.QueryRuntime() return true
return true } else if (!pathMatchRegexp(['', '/login'], window.location.pathname)) {
} if (validBackup == true) {
else if(!pathMatchRegexp(['','/login'], window.location.pathname)) { ycore.app_session.logout()
if (validBackup == true) { } else {
ycore.LogoutCall() router.push({ pathname: '/login' })
} }
else{
router.push({pathname: '/login',})
}
} }
if(pathMatchRegexp([''], window.location.pathname)){ if (pathMatchRegexp([''], window.location.pathname)) {
router.push({pathname: '/login',}) router.push({ pathname: '/login' })
} }
}, },
}, },
reducers: { reducers: {

View File

@ -1,31 +1,38 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { UserProfile } from 'components' import { UserProfile } from 'components'
import __m from '../__m/index.js' import __m from '../__m/index.js'
import { pathMatchRegexp } from 'utils' import { pathMatchRegexp } from 'utils'
import Error404 from '../404.js' import Error404 from '../404.js'
import * as ycore from 'ycore' import * as ycore from 'ycore'
class PageIndexer extends PureComponent { class PageIndexer extends PureComponent {
render() {
render() { const { location } = this.props
const {location} = this.props const matchUser = pathMatchRegexp('/@:id', location.pathname)
const matchUser = pathMatchRegexp("/@:id", location.pathname); const matchMaster = pathMatchRegexp('/__m', location.pathname)
const matchMaster = pathMatchRegexp("/__m", location.pathname)
if (matchUser) { if (matchUser) {
ycore.yconsole.log(`User matched! ${location.pathname}`) ycore.yconsole.log(`User matched! ${location.pathname}`)
return(<div> return (
<div>
<UserProfile regx={matchUser} /> <UserProfile regx={matchUser} />
</div>) </div>
} )
if (matchMaster){
return ycore.IsThisUser.dev() || ycore.IsThisUser.admin()? <__m /> : <Error404 />
}
// By default return Error 404
return(<div><Error404 /></div>)
} }
if (matchMaster) {
return ycore.IsThisUser.dev() || ycore.IsThisUser.admin() ? (
<__m />
) : (
<Error404 />
)
}
// By default return Error 404
return (
<div>
<Error404 />
</div>
)
}
} }
export default PageIndexer export default PageIndexer

View File

@ -1,14 +1,14 @@
.content { .content {
line-height: 2.4; line-height: 2.4;
font-size: 13px; font-size: 13px;
.item { .item {
display: flex; display: flex;
& > div { &>div {
&:first-child { &:first-child {
width: 100px; width: 100px;
}
} }
} }
} }
}

View File

@ -1,16 +1,16 @@
import React from 'react' import React from 'react'
import { Icon as LegacyIcon } from '@ant-design/compatible'; import { Icon as LegacyIcon } from '@ant-design/compatible'
import { Page } from 'components' import { Page } from 'components'
import styles from './404.less' import styles from './404.less'
const Error404 = () => ( const Error404 = () => (
<div className={styles.error}>
<div className={styles.error}>
<LegacyIcon type="api" /> <LegacyIcon type="api" />
<h1>OBA BLYAT</h1> <h1>OBA BLYAT</h1>
<p><strong>ERROR 404</strong></p> <p>
</div> <strong>ERROR 404</strong>
</p>
</div>
) )
export default Error404 export default Error404

View File

@ -7,6 +7,7 @@
src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2'); src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
} }
/* latin-ext */ /* latin-ext */
@font-face { @font-face {
font-family: 'Poppins'; font-family: 'Poppins';
@ -16,6 +17,7 @@
src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2'); src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
} }
/* latin */ /* latin */
@font-face { @font-face {
font-family: 'Poppins'; font-family: 'Poppins';
@ -25,6 +27,7 @@
src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJfecg.woff2) format('woff2'); src: local('Poppins Regular'), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v6/pxiEyp8kv8JHgFVrJJfecg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
} }
.error { .error {
background-color: transparent; background-color: transparent;
color: black; color: black;
@ -45,7 +48,8 @@
font-family: 'Poppins', sans-serif; font-family: 'Poppins', sans-serif;
} }
p { p {
font-family: 'Poppins', sans-serif; font-family: 'Poppins', sans-serif;
} }
} }

View File

@ -1,25 +1,23 @@
import React from 'react'
import React from 'react';
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import styles from './style.less' import styles from './style.less'
import MainFeed from '../../components/MainFeed'; import MainFeed from '../../components/MainFeed'
const UserData = ycore.userData() const UserData = ycore.userData()
export default class __m extends React.Component { export default class __m extends React.Component {
constructor(props){ constructor(props) {
super(props), super(props),
this.state = { (this.state = {
s_id: '', s_id: '',
coninfo: 'Getting info...', coninfo: 'Getting info...',
s_token: '', s_token: '',
s_ses: '' s_ses: '',
}; })
} }
componentDidMount() { componentDidMount() {
@ -30,133 +28,199 @@ export default class __m extends React.Component {
this.handleToken() this.handleToken()
} }
handleSID(){ handleSID() {
ycore.get_app_session.get_id((err, response)=> { ycore.get_app_session.get_id((err, response) => {
if (err){ if (err) {
return ycore.notifyError(err) return ycore.notify.error(err)
} }
this.setState({ s_id: response}) this.setState({ s_id: response })
}) })
} }
handleToken(){ handleToken() {
const a = ycore.handlerYIDT.getRaw() const a = ycore.token_data.getRaw()
const b = jwt.decode(a) const b = jwt.decode(a)
this.setState({ s_token: b}) this.setState({ s_token: b })
{ycore.ValidLoginSession(res => { {
this.setState({s_ses: res}) ycore.validate.session(res => {
})} this.setState({ s_ses: res })
})
}
} }
handleDesktop(){ handleDesktop() {
const a = localStorage.getItem('desktop_src') const a = localStorage.getItem('desktop_src')
let to; let to
if (a == 'false') { if (a == 'false') {
to = true to = true
}else { } else {
to = false to = false
} }
ycore.notify.proccess('Switching to ', to? 'Desktop Mode' : 'Normal Mode') ycore.notify.proccess('Switching to ', to ? 'Desktop Mode' : 'Normal Mode')
localStorage.setItem('desktop_src', to) localStorage.setItem('desktop_src', to)
setTimeout(() => ycore.RefreshONCE(), 2000) setTimeout(() => ycore.RefreshONCE(), 2000)
} }
DescompileSDCP(){ DescompileSDCP() {
let result = {}; let result = {}
for (var i = 0; i < UserData.length; i++) { for (var i = 0; i < UserData.length; i++) {
result[UserData[i].key] = UserData[i].value; result[UserData[i].key] = UserData[i].value
} }
console.log([result]) console.log([result])
} }
render() { render() {
const arrayOfSDCP = Object.entries(UserData).map((e) => ( { [e[0]]: e[1] } )); const arrayOfSDCP = Object.entries(UserData).map(e => ({ [e[0]]: e[1] }))
const { UserID, UserToken, expiresIn } = this.state.s_token const { UserID, UserToken, expiresIn } = this.state.s_token
const { ValidSDCP, ValidCookiesToken, final } = this.state.s_ses const { ValidSDCP, ValidCookiesToken, final } = this.state.s_ses
const AddDummy = {id: "3", publisher: {id: "1"},post_id: "1", user_id: "48", recipient_id: "0", postText: "New by ID Dummy Payload"} const AddDummy = {
id: '3',
publisher: { id: '1' },
post_id: '1',
user_id: '48',
recipient_id: '0',
postText: 'New by ID Dummy Payload',
}
return ( return (
<div className={styles.Wrapper}> <div className={styles.Wrapper}>
<div className={styles.titleHeader}> <div className={styles.titleHeader}>
<h1><Icons.DeploymentUnitOutlined /> yCore Server</h1> <h1>
</div> <Icons.DeploymentUnitOutlined /> yCore Server
<div className={styles.sectionWrapper}> </h1>
<antd.Card> </div>
<h2><Icons.CloudServerOutlined /> Server UID</h2> <div className={styles.sectionWrapper}>
<span> {ycore.yConfig.server_key} </span> <antd.Card>
</antd.Card> <h2>
<antd.Card> <Icons.CloudServerOutlined /> Server UID
<h2><Icons.UserOutlined /> Your SID</h2> </h2>
<span> {this.state.s_id} </span> <span> {ycore.yConfig.server_key} </span>
</antd.Card> </antd.Card>
<antd.Card> <antd.Card>
<h2><Icons.UserOutlined /> Current Session</h2> <h2>
<p> Raw => {JSON.stringify(this.state.s_token)} </p> <Icons.UserOutlined /> Your SID
<p> UID => {UserID} </p> </h2>
<p> Session Token => {UserToken} </p> <span> {this.state.s_id} </span>
<p> expiresIn => {expiresIn} </p> </antd.Card>
<hr /> <antd.Card>
<p> ValidSDCP => {JSON.stringify(ValidSDCP)} </p> <h2>
<p> ValidCookiesToken => {JSON.stringify(ValidCookiesToken)} </p> <Icons.UserOutlined /> Current Session
<p> Valid? => {JSON.stringify(final)} </p> </h2>
<p> Raw => {JSON.stringify(this.state.s_token)} </p>
</antd.Card> <p> UID => {UserID} </p>
<antd.Card> <p> Session Token => {UserToken} </p>
<span> Using v{ycore.AppInfo.version} | User @{UserData.username}#{UserData.id} | </span> <p> expiresIn => {expiresIn} </p>
</antd.Card> <hr />
</div> <p> ValidSDCP => {JSON.stringify(ValidSDCP)} </p>
<p> ValidCookiesToken => {JSON.stringify(ValidCookiesToken)} </p>
<p> Valid? => {JSON.stringify(final)} </p>
</antd.Card>
<antd.Card>
<span>
{' '}
Using v{ycore.AppInfo.version} | User @{UserData.username}#
{UserData.id} |{' '}
</span>
</antd.Card>
</div>
<div className={styles.titleHeader}> <div className={styles.titleHeader}>
<h1><Icons.DeploymentUnitOutlined /> Test yCore </h1> <h1>
</div> <Icons.DeploymentUnitOutlined /> Test yCore{' '}
<div className={styles.sectionWrapper}> </h1>
<antd.Button onClick={() => ycore.notifyError('Yep, its not empty, jeje funny')} > Send empty notifyError() </antd.Button> </div>
<antd.Button onClick={() => ycore.notifyError(` <div className={styles.sectionWrapper}>
<antd.Button
onClick={() => ycore.notify.error('Yep, its not empty, jeje funny')}
>
{' '}
Send empty notify.error(){' '}
</antd.Button>
<antd.Button
onClick={() =>
ycore.notify.error(`
ycore.GetPosts(uid, get, '0', (err, result) => { ycore.GetPosts(uid, get, '0', (err, result) => {
const parsed = JSON.parse(result)['data'] const parsed = JSON.parse(result)['data']
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false
this.setState({ isEnd: isEnd, data: parsed, loading: false }) this.setState({ isEnd: isEnd, data: parsed, loading: false })
})` })`)
)} > Send mock notifyError() </antd.Button> }
>
{' '}
Send mock notify.error(){' '}
</antd.Button>
<antd.Button onClick={() => ycore.notify.error('Error Mock 1')} > notify.error </antd.Button> <antd.Button onClick={() => ycore.notify.error('Error Mock 1')}>
<antd.Button onClick={() => ycore.notify.proccess('Proccess Mock 1')} > notify.proccess </antd.Button> {' '}
<antd.Button onClick={() => this.handleDesktop()} > Switch to Desktop_mode </antd.Button> notify.error{' '}
</div> </antd.Button>
<antd.Button onClick={() => ycore.notify.proccess('Proccess Mock 1')}>
{' '}
notify.proccess{' '}
</antd.Button>
<antd.Button onClick={() => this.handleDesktop()}>
{' '}
Switch to Desktop_mode{' '}
</antd.Button>
</div>
<div className={styles.titleHeader}> <div className={styles.titleHeader}>
<h1><Icons.DatabaseOutlined /> SDCP</h1> <h1>
</div> <Icons.DatabaseOutlined /> SDCP
<div className={styles.sectionWrapper}> </h1>
<antd.Card> </div>
<h2><Icons.CloudServerOutlined /> UserData</h2> <div className={styles.sectionWrapper}>
<antd.Collapse> <antd.Card>
<antd.Collapse.Panel header="WARNING: High Heap when descompile data! " key="1"> <h2>
{ JSON.stringify(arrayOfSDCP) } <Icons.CloudServerOutlined /> UserData
</antd.Collapse.Panel> </h2>
</antd.Collapse> <antd.Collapse>
<antd.Collapse.Panel
header="WARNING: High Heap when descompile data! "
key="1"
>
{JSON.stringify(arrayOfSDCP)}
</antd.Card> </antd.Collapse.Panel>
</antd.Collapse>
</div> </antd.Card>
</div>
<div className={styles.titleHeader}>
<h1><Icons.BugOutlined /> MainFeed | ENV Test</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<antd.Button onClick={() => ycore.FeedHandler.addToRend(AddDummy)}> ADD DUMMY </antd.Button>
<antd.Button onClick={()=> ycore.FeedHandler.killByID(3)} > KillByID (3) </antd.Button>
<hr />
<MainFeed custompayload={[{id: "1", publisher: {id: "1"},post_id: "1", user_id: "48", recipient_id: "0", postText: "Dummy Payload"}, {id: "2", post_id: "2", publisher: {id: "1"}, user_id: "48", recipient_id: "0", postText: "Dummy Payload"}]} />
</antd.Card>
</div>
<div className={styles.titleHeader}>
<h1>
<Icons.BugOutlined /> MainFeed | ENV Test
</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<antd.Button onClick={() => ycore.FeedHandler.addToRend(AddDummy)}>
{' '}
ADD DUMMY{' '}
</antd.Button>
<antd.Button onClick={() => ycore.FeedHandler.killByID(3)}>
{' '}
KillByID (3){' '}
</antd.Button>
<hr />
<MainFeed
custompayload={[
{
id: '1',
publisher: { id: '1' },
post_id: '1',
user_id: '48',
recipient_id: '0',
postText: 'Dummy Payload',
},
{
id: '2',
post_id: '2',
publisher: { id: '1' },
user_id: '48',
recipient_id: '0',
postText: 'Dummy Payload',
},
]}
/>
</antd.Card>
</div>
</div> </div>
) )
} }

View File

@ -1,9 +1,10 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.Wrapper{ .Wrapper {
padding: 10px; padding: 10px;
} }
.titleHeader{
.titleHeader {
position: relative; position: relative;
width: 100%; width: 100%;
height: 40px; height: 40px;
@ -11,14 +12,16 @@
border-radius: 8px; border-radius: 8px;
line-height: 40px; line-height: 40px;
padding: 0 30px 0 15px; padding: 0 30px 0 15px;
h1{
h1 {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
font-size: 14px; font-size: 14px;
color: #1890ff; color: #1890ff;
} }
} }
.sectionWrapper{
.sectionWrapper {
word-break: break-all; word-break: break-all;
max-width: 100%; max-width: 100%;
text-overflow: clip; text-overflow: clip;

View File

@ -3,18 +3,18 @@ import styles from './index.less'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
class AppAbout extends React.Component { class AppAbout extends React.Component {
render(){ render() {
return( return (
<div className={styles.aboutWrapper}> <div className={styles.aboutWrapper}>
<img src={ycore.AppInfo.logo} /> <img src={ycore.AppInfo.logo} />
<antd.Card > <antd.Card>
<h1 className={styles.appName}> {ycore.AppInfo.name} </h1> <h1 className={styles.appName}> {ycore.AppInfo.name} </h1>
<antd.Tag color="geekblue">v{ycore.AppInfo.version}</antd.Tag>{ycore.DetectNoNStableBuild('TagComponent')} <antd.Tag color="geekblue">v{ycore.AppInfo.version}</antd.Tag>
</antd.Card> {ycore.DetectNoNStableBuild('TagComponent')}
</div> </antd.Card>
) </div>
} )
}
} }
export default AppAbout export default AppAbout

View File

@ -1,17 +1,18 @@
.aboutWrapper{ .aboutWrapper {
margin: auto; margin: auto;
max-width: 70vw; max-width: 70vw;
width: 500px; width: 500px;
vertical-align: middle; vertical-align: middle;
position: relative; position: relative;
background-color: rgba(73, 72, 72, 0.349); background-color: rgba(73, 72, 72, 0.349);
img{
width: 100%; img {
padding: 15px; width: 100%;
} padding: 15px;
}
} }
.appName { .appName {
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
font-size: 27px; font-size: 27px;
} }

View File

@ -4,92 +4,97 @@ import { SearchCard } from 'components'
import styles from './styles.less' import styles from './styles.less'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
class GroupIndexer extends PureComponent { class GroupIndexer extends PureComponent {
constructor(props){ constructor(props) {
super(props), super(props),
this.state = { (this.state = {
SearchResult: '', SearchResult: '',
loading: true loading: true,
} })
} }
toogleLoading(){ toogleLoading() {
this.setState({loading: !this.state.loading}) this.setState({ loading: !this.state.loading })
} }
componentDidMount(){ componentDidMount() {
try { try {
const {location} = this.props const { location } = this.props
const matchSearch = pathMatchRegexp("/s/:id", location.pathname); const matchSearch = pathMatchRegexp('/s/:id', location.pathname)
const parsed = matchSearch.shift()
const raw = parsed.toString()
const string = raw.replace('/s/', "")
} catch (err) {
ycore.notifyError(err)
}
}
EntryComponent = (t, source) => {
try {
return(
<div>
<antd.Typography.Title level={2} ><Icons.TeamOutlined /> {t} </antd.Typography.Title>
<div className={styles.searchEntry}>
<antd.List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 4,
lg: 4,
xl: 6,
xxl: 3,
}}
dataSource={source}
renderItem={item => (
<SearchCard type={t} source={item} />
)}
/>
</div>
</div>
)
} catch (error) {
console.log(error)
return <center><h2>Render Error</h2></center>
}
}
render() {
const {location} = this.props
const matchSearch = pathMatchRegexp("/g/:id", location.pathname);
const parsed = matchSearch.shift() const parsed = matchSearch.shift()
const raw = parsed.toString() const raw = parsed.toString()
const string = raw.replace('/g/', "") const string = raw.replace('/s/', '')
} catch (err) {
ycore.notify.error(err)
if (matchSearch) {
return(
<div>
<h1 className={styles.searchHeader}><Icons.SearchOutlined /> Results of {string} </h1>
<antd.Card>
<div className={styles.results}>
{this.state.loading? null : this.renderResult(this.state.SearchResult)}
</div>
</antd.Card>
</div>
)
}
return(<div><center> Render Error </center></div>)
} }
}
EntryComponent = (t, source) => {
try {
return (
<div>
<antd.Typography.Title level={2}>
<Icons.TeamOutlined /> {t}{' '}
</antd.Typography.Title>
<div className={styles.searchEntry}>
<antd.List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 4,
lg: 4,
xl: 6,
xxl: 3,
}}
dataSource={source}
renderItem={item => <SearchCard type={t} source={item} />}
/>
</div>
</div>
)
} catch (error) {
console.log(error)
return (
<center>
<h2>Render Error</h2>
</center>
)
}
}
render() {
const { location } = this.props
const matchSearch = pathMatchRegexp('/g/:id', location.pathname)
const parsed = matchSearch.shift()
const raw = parsed.toString()
const string = raw.replace('/g/', '')
if (matchSearch) {
return (
<div>
<h1 className={styles.searchHeader}>
<Icons.SearchOutlined /> Results of {string}{' '}
</h1>
<antd.Card>
<div className={styles.results}>
{this.state.loading
? null
: this.renderResult(this.state.SearchResult)}
</div>
</antd.Card>
</div>
)
}
return (
<div>
<center> Render Error </center>
</div>
)
}
} }
export default GroupIndexer export default GroupIndexer

View File

@ -1,18 +1,20 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.searchHeader { .searchHeader {
font-family: "Nunito", sans-serif; font-family: "Nunito", sans-serif;
font-size: 40px; font-size: 40px;
text-align: center; text-align: center;
margin-top: 7px; margin-top: 7px;
} }
.results { .results {
padding: 10px; padding: 10px;
} }
.searchEntry { .searchEntry {
:global{ :global {
.antd-card{ .antd-card {
margin: auto; margin: auto;
}
} }
}
} }

View File

@ -1,34 +1,38 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import * as antd from 'antd' import * as antd from 'antd'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import {YulioID} from 'components' import { YulioID } from 'components'
import styles from './index.less'; import styles from './index.less'
class Login extends Component { class Login extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
showYulioID: true showYulioID: true,
} }
} }
toogleYulioID(){ toogleYulioID() {
this.setState({ showYulioID: !this.state.showYulioID }) this.setState({ showYulioID: !this.state.showYulioID })
} }
render() { render() {
return ( return (
<div> <div>
<img src="https://dl.ragestudio.net/background.svg" className={styles.backgroud} /> <img
src="https://dl.ragestudio.net/background.svg"
className={styles.backgroud}
/>
<div className={styles.loginLandingWrapper}> <div className={styles.loginLandingWrapper}>
<div className={styles.brand} ><img src={ycore.AppInfo.logo} /> </div> <div className={styles.brand}>
<img src={ycore.AppInfo.logo} />{' '}
</div>
</div>
<div className={styles.version}>
<h2>{`v${ycore.AppInfo.version}`}</h2>
{ycore.DetectNoNStableBuild('TagComponent')}
</div> </div>
<div className={styles.version}><h2>{`v${ycore.AppInfo.version}`}</h2>{ycore.DetectNoNStableBuild('TagComponent')}</div>
<YulioID visible={this.state.showYulioID} /> <YulioID visible={this.state.showYulioID} />
</div> </div>
) )
} }
} }

View File

@ -2,99 +2,115 @@
/* Animation */ /* Animation */
.parallax > use { .parallax>use {
animation: move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite; animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
}
.parallax > use:nth-child(1) {
animation-delay: -2s;
animation-duration: 7s;
}
.parallax > use:nth-child(2) {
animation-delay: -3s;
animation-duration: 10s;
}
.parallax > use:nth-child(3) {
animation-delay: -4s;
animation-duration: 13s;
}
.parallax > use:nth-child(4) {
animation-delay: -5s;
animation-duration: 20s;
}
@keyframes move-forever {
0% {
transform: translate3d(-90px,0,0);
}
100% {
transform: translate3d(85px,0,0);
}
}
.backgroud{
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
top: 0;
left: 0;
} }
.version{
display: flex; .parallax>use:nth-child(1) {
z-index: 2; animation-delay: -2s;
font-family: "Poppins", sans-serif; animation-duration: 7s;
font-size: 11px;
bottom: 0;
position: absolute;
padding: 0 0 5px 3%;
color: #F9F9F9;
h2{
margin: 0 14px 0 0;
color: #F9F9F9;
}
:global{
.ant-tag {
border-radius: 4px;
}
}
} }
.loginLandingWrapper{
background-color: #F9F9F9; .parallax>use:nth-child(2) {
width: 100%; animation-delay: -3s;
height: 100%; animation-duration: 10s;
font-family: "Nunito", sans-serif;
padding: 15px 30px 15px 35px;
} }
.brand{
width: 100%; .parallax>use:nth-child(3) {
top: 0; animation-delay: -4s;
float: left; animation-duration: 13s;
vertical-align: middle; }
position: relative;
img{ .parallax>use:nth-child(4) {
max-width: 250px; animation-delay: -5s;
width: 11vw; animation-duration: 20s;
}
@keyframes move-forever {
0% {
transform: translate3d(-90px, 0, 0);
}
100% {
transform: translate3d(85px, 0, 0);
}
}
.backgroud {
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
top: 0;
left: 0;
}
.version {
display: flex;
z-index: 2;
font-family: "Poppins", sans-serif;
font-size: 11px;
bottom: 0;
position: absolute;
padding: 0 0 5px 3%;
color: #F9F9F9;
h2 {
margin: 0 14px 0 0;
color: #F9F9F9;
}
:global {
.ant-tag {
border-radius: 4px;
} }
}
} }
.prest{
z-index: 2; .loginLandingWrapper {
position: relative; background-color: #F9F9F9;
font-family: "Source Sans Pro", sans-serif; width: 100%;
padding: 25px; height: 100%;
margin: auto; font-family: "Nunito", sans-serif;
vertical-align: bottom; padding: 15px 30px 15px 35px;
img{ }
width: 100%;
max-height: 60vh; .brand {
} width: 100%;
.loginbtn{ top: 0;
margin: auto; float: left;
position: relative; vertical-align: middle;
display: flex; position: relative;
width: 100%;
:global{ img {
.ant-btn { max-width: 250px;
margin: auto; width: 11vw;
} }
} }
}
.prest {
z-index: 2;
position: relative;
font-family: "Source Sans Pro", sans-serif;
padding: 25px;
margin: auto;
vertical-align: bottom;
img {
width: 100%;
max-height: 60vh;
}
.loginbtn {
margin: auto;
position: relative;
display: flex;
width: 100%;
:global {
.ant-btn {
margin: auto;
}
}
}
} }

View File

@ -1,15 +1,15 @@
import React from 'react' import React from 'react'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import {PostCreator, MainFeed} from 'components' import { PostCreator, MainFeed } from 'components'
import styles from './index.less' import styles from './index.less'
export default class Main extends React.Component { export default class Main extends React.Component {
render(){ render() {
return ( return (
<div className={styles.mainWrapper}> <div className={styles.mainWrapper}>
<PostCreator userData={ycore.userData()} /> <PostCreator userData={ycore.userData()} />
<MainFeed get="feed" /> <MainFeed get="feed" />
</div> </div>
) )
} }
} }

View File

@ -1,5 +1,6 @@
@import '~themes/vars.less'; @import '~themes/vars.less';
.mainWrapper{
position: relative; .mainWrapper {
padding: 20px; position: relative;
padding: 20px;
} }

View File

@ -2,47 +2,46 @@ import React from 'react'
import { pathMatchRegexp } from 'utils' import { pathMatchRegexp } from 'utils'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
export default class Indexer_Post extends React.Component {
constructor(props) {
super(props),
(this.state = {
loading: true,
swaped: false,
UUID: '',
})
}
export default class Indexer_Post extends React.Component{ toSwap(id) {
constructor(props){ const payload = { post_id: id }
super(props), ycore.comty_post.get((err, res) => {
this.state = { if (err) {
loading: true, return false
swaped: false,
UUID: ''
}
}
toSwap(id){
const payload = {post_id: id}
ycore.comty_post.get((err,res)=>{
if (err) { return false }
ycore.SecondarySwap.openPost(res)
}, payload)
}
componentDidMount(){
try {
const {location} = this.props
const regexp = pathMatchRegexp("/p/:id", location.pathname)
const match = regexp.shift().toString()
const string = match.replace('/p/', "")
this.setState({ UUID: string })
if (string) {
this.toSwap(string)
}
} catch (err) {
ycore.notifyError(err)
} }
} ycore.SecondarySwap.openPost(res)
}, payload)
}
render(){ componentDidMount() {
ycore.crouter.native('main') try {
return null const { location } = this.props
const regexp = pathMatchRegexp('/p/:id', location.pathname)
const match = regexp.shift().toString()
const string = match.replace('/p/', '')
this.setState({ UUID: string })
if (string) {
this.toSwap(string)
}
} catch (err) {
ycore.notify.error(err)
} }
}
render() {
ycore.crouter.native('main')
return null
}
} }

View File

@ -1,10 +1,7 @@
import React from 'react' import React from 'react'
export default class Go_Pro extends React.Component{ export default class Go_Pro extends React.Component {
render(){ render() {
return( return <div>Go pro? Yeah</div>
<div>Go pro? Yeah</div> }
) }
}
}

View File

@ -4,143 +4,162 @@ import { SearchCard } from 'components'
import styles from './styles.less' import styles from './styles.less'
import * as ycore from 'ycore' import * as ycore from 'ycore'
import * as antd from 'antd' import * as antd from 'antd'
import * as Icons from '@ant-design/icons'; import * as Icons from '@ant-design/icons'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
class SearchPageIndexer extends PureComponent { class SearchPageIndexer extends PureComponent {
constructor(props){ constructor(props) {
super(props), super(props),
this.state = { (this.state = {
SearchResult: '', SearchResult: '',
loading: true loading: true,
} })
} }
toogleLoading(){ toogleLoading() {
this.setState({loading: !this.state.loading}) this.setState({ loading: !this.state.loading })
} }
componentDidMount(){ componentDidMount() {
try { try {
const {location} = this.props const { location } = this.props
const matchSearch = pathMatchRegexp("/s/:id", location.pathname); const matchSearch = pathMatchRegexp('/s/:id', location.pathname)
const parsed = matchSearch.shift()
const raw = parsed.toString()
const string = raw.replace('/s/', "")
const payload = {key: string}
ycore.comty_search.keywords((err,res) =>{
if (err) {
ycore.notifyError(err)
}
ycore.yconsole.log('Founded entries => ', JSON.parse(res))
this.setState({ SearchResult: res })
this.toogleLoading()
}, payload)
} catch (err) {
ycore.notifyError(err)
}
}
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) {
console.log('Users => ', usersParsed)
return this.EntryComponent('Users', usersParsed)
}}
const groups = () => {if (groupsParsed.length >= 1) {
console.log('Groups => ', groupsParsed)
return this.EntryComponent('Groups', groupsParsed)
}}
const pages = () => {if (pagesParsed.length >= 1) {
console.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) {
console.log(error)
return <center><h2>Render Error</h2></center>
}
}
EntryComponent = (t, source) => {
try {
return(
<div>
<antd.Typography.Title level={2} ><Icons.TeamOutlined /> {t} </antd.Typography.Title>
<div className={styles.searchEntry}>
<antd.List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 4,
lg: 4,
xl: 6,
xxl: 3,
}}
dataSource={source}
renderItem={item => (
<SearchCard type={t} source={item} />
)}
/>
</div>
</div>
)
} catch (error) {
console.log(error)
return <center><h2>Render Error</h2></center>
}
}
render() {
const {location} = this.props
const matchSearch = pathMatchRegexp("/s/:id", location.pathname);
const parsed = matchSearch.shift() const parsed = matchSearch.shift()
const raw = parsed.toString() const raw = parsed.toString()
const string = raw.replace('/s/', "") const string = raw.replace('/s/', '')
const payload = { key: string }
if (matchSearch) { ycore.comty_search.keywords((err, res) => {
if (err) {
console.log(`Search matched! ${location.pathname}`) ycore.notify.error(err)
return( }
<div> ycore.yconsole.log('Founded entries => ', JSON.parse(res))
<h1 className={styles.searchHeader}><Icons.SearchOutlined /> Results of {string} </h1> this.setState({ SearchResult: res })
<antd.Card> this.toogleLoading()
<div className={styles.results}> }, payload)
{this.state.loading? null : this.renderResult(this.state.SearchResult)} } catch (err) {
</div> ycore.notify.error(err)
</antd.Card>
</div>
)
}
return(<div><center> Render Error </center></div>)
} }
}
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) {
console.log('Users => ', usersParsed)
return this.EntryComponent('Users', usersParsed)
}
}
const groups = () => {
if (groupsParsed.length >= 1) {
console.log('Groups => ', groupsParsed)
return this.EntryComponent('Groups', groupsParsed)
}
}
const pages = () => {
if (pagesParsed.length >= 1) {
console.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) {
console.log(error)
return (
<center>
<h2>Render Error</h2>
</center>
)
}
}
EntryComponent = (t, source) => {
try {
return (
<div>
<antd.Typography.Title level={2}>
<Icons.TeamOutlined /> {t}{' '}
</antd.Typography.Title>
<div className={styles.searchEntry}>
<antd.List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 4,
lg: 4,
xl: 6,
xxl: 3,
}}
dataSource={source}
renderItem={item => <SearchCard type={t} source={item} />}
/>
</div>
</div>
)
} catch (error) {
console.log(error)
return (
<center>
<h2>Render Error</h2>
</center>
)
}
}
render() {
const { location } = this.props
const matchSearch = pathMatchRegexp('/s/:id', location.pathname)
const parsed = matchSearch.shift()
const raw = parsed.toString()
const string = raw.replace('/s/', '')
if (matchSearch) {
console.log(`Search matched! ${location.pathname}`)
return (
<div>
<h1 className={styles.searchHeader}>
<Icons.SearchOutlined /> Results of {string}{' '}
</h1>
<antd.Card>
<div className={styles.results}>
{this.state.loading
? null
: this.renderResult(this.state.SearchResult)}
</div>
</antd.Card>
</div>
)
}
return (
<div>
<center> Render Error </center>
</div>
)
}
} }
export default SearchPageIndexer export default SearchPageIndexer

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