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/
import { resolve } from 'path';
import { i18n } from './config/ycore.config.js';
import { resolve } from 'path'
import { i18n } from './config/ycore.config.js'
export default {
ignoreMomentLocale: true,
targets: {
ie: 9,
@ -31,23 +30,26 @@ export default {
/services\//,
],
update: routes => {
if (!i18n) return routes;
const newRoutes = [];
if (!i18n) return routes
const newRoutes = []
for (const item of routes[0].routes) {
newRoutes.push(item);
newRoutes.push(item)
if (item.path) {
newRoutes.push(
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;
return routes;
routes[0].routes = newRoutes
return routes
},
},
dll: false,
@ -88,5 +90,4 @@ export default {
'lodash',
],
],
};
}

View File

@ -1,38 +1,53 @@
function SettingStoragedValue(e){
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
}
catch (error) {
return null
}
function SettingStoragedValue(e) {
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e ? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
} catch (error) {
return null
}
}
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
export var AppSettings = {
// Global Behaviors
InfiniteLoading: false,
InfiniteLogin: false,
InfiniteRegister: false,
DisableLogin: false,
DisableRegister: true,
DisablePasswordRecover: true,
// Activating this, the logs must be trowed
force_showDevLogs: fromStorage? SettingStoragedValue('force_showDevLogs') : false,
StrictLightMode: fromStorage? SettingStoragedValue('strict_lightMode') : false,
SignForNotExpire: fromStorage? SettingStoragedValue('sessions_noexpire') : false,
auto_search_ontype: fromStorage? SettingStoragedValue('auto_search_ontype') : false,
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'
// Global Behaviors
InfiniteLoading: false,
InfiniteLogin: false,
InfiniteRegister: false,
DisableLogin: false,
DisableRegister: true,
DisablePasswordRecover: true,
// Activating this, the logs must be trowed
force_showDevLogs: fromStorage
? SettingStoragedValue('force_showDevLogs')
: false,
StrictLightMode: fromStorage
? SettingStoragedValue('strict_lightMode')
: false,
SignForNotExpire: fromStorage
? SettingStoragedValue('sessions_noexpire')
: false,
auto_search_ontype: fromStorage
? SettingStoragedValue('auto_search_ontype')
: false,
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 = {
secretOrKey: "secret"
};
secretOrKey: 'secret',
}

View File

@ -1,42 +1,38 @@
module.exports = {
server_endpoint: 'https://comty.julioworld.club',
siteName: 'Comty',
copyright: 'RageStudio©',
server_endpoint: 'https://comty.julioworld.club',
siteName: 'Comty',
copyright: 'RageStudio©',
LogoPath: '/logo.svg',
FullLogoPath: '/full_logo.svg',
DarkFullLogoPath: '/dark_full_logo.svg',
DarkLogoPath: '/dark_logo.svg',
LogoPath: '/logo.svg',
FullLogoPath: '/full_logo.svg',
DarkFullLogoPath: '/dark_full_logo.svg',
DarkLogoPath: '/dark_logo.svg',
resource_bundle: 'light_ng',
resource_bundle: 'light_ng',
/* Layout configuration, specify which layout to use for route. */
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',
},
/* Layout configuration, specify which layout to use for route. */
layouts: [
i18n: {
languages: [
{
name: 'primary',
include: [/.*/],
exclude: [/\/login/, /\/socket\/(.*)/, /\/publics/, /\/authorize/],
key: 'en',
title: 'English',
},
],
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",
},
App_Config: {
InitRes: '800x600',
},
i18n: {
languages: [
{
key: 'en',
title: 'English',
},
],
defaultLanguage: 'en',
},
}
defaultLanguage: 'en',
},
}

View File

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

View File

@ -1,31 +1,22 @@
import * as Icons from '@ant-design/icons'
export var Post_Options = [
{
"option": "pro_boost",
"icon": <Icons.RocketOutlined />,
"type" : "switch",
"title": "CPRO™ Boost",
"description": "",
"require": "pro",
"value": false
},
{
"option": "allow_likes",
"icon": <Icons.HeartOutlined />,
"type" : "switch",
"title": "Allow Likes",
"description": "",
"require": "",
"value": true
},
{
"option": "allow_comments",
"icon": <Icons.CommentOutlined />,
"type" : "switch",
"title": "Allow Comments",
"description": "",
"require": "",
"value": true
},
{
key: 'pro_boost',
icon: <Icons.RocketOutlined />,
type: 'switch',
title: 'CPRO™ Boost',
description: '',
require: 'pro',
value: false,
},
{
key: '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'))
function SettingStoragedValue(e){
function SettingStoragedValue(e) {
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null
return item.SettingID === e ? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
}
catch (error) {
} catch (error) {
return null
}
}
export var ListSettings = [
{
"SettingID": "strict_lightMode",
"type" : "switch",
"title": "Strict Light Mode",
"description": "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",
"title": "Default Collapse Sider",
"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",
"description": "Force the app to auto refresh the posts feed when exist news posts for update",
"value": fromStorage? SettingStoragedValue('auto_feedrefresh') : false
},
{
"SettingID": "force_showDevLogs",
"type" : "switch",
"title": "Show Functions Logs",
"description": "Show all console logs... [Developer]",
"value": fromStorage? SettingStoragedValue('force_showDevLogs') : false
},
{
"SettingID": "sessions_noexpire",
"type" : "switch",
"title": "No expire session",
"description": "Force the app to not expire any session... [Developer]",
"value": fromStorage? SettingStoragedValue('sessions_noexpire') : false
},
{
"SettingID": "auto_search_ontype",
"type" : "switch",
"title": "Auto search",
"description": "Force the app to automaticly search when a type input is detected... [Developer]",
"value": fromStorage? SettingStoragedValue('auto_search_ontype') : false
},
{
"SettingID": "default_showpostcreator",
"type" : "switch",
"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": "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
},
{
SettingID: 'strict_lightMode',
type: 'switch',
title: 'Strict Light Mode',
description:
'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',
title: 'Default Collapse Sider',
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',
description:
'Force the app to auto refresh the posts feed when exist news posts for update',
value: fromStorage ? SettingStoragedValue('auto_feedrefresh') : false,
},
{
SettingID: 'force_showDevLogs',
type: 'switch',
title: 'Show Functions Logs',
description: 'Show all console logs... [Developer]',
value: fromStorage ? SettingStoragedValue('force_showDevLogs') : false,
},
{
SettingID: 'sessions_noexpire',
type: 'switch',
title: 'No expire session',
description: 'Force the app to not expire any session... [Developer]',
value: fromStorage ? SettingStoragedValue('sessions_noexpire') : false,
},
{
SettingID: 'auto_search_ontype',
type: 'switch',
title: 'Auto search',
description:
'Force the app to automaticly search when a type input is detected... [Developer]',
value: fromStorage ? SettingStoragedValue('auto_search_ontype') : false,
},
{
SettingID: 'default_showpostcreator',
type: 'switch',
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: '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/ycore_styles/pre.js';
export * from './libs/ycore_sdcp/pre.js';
export * from './libs/app_functions/pre.js'
export * from './libs/rs_cloud/pre.js'
export * from './libs/app_functions/pre.js';
export * from './libs/rs_cloud/pre.js';

View File

@ -1,34 +1,154 @@
import {SetControls, CloseControls} from "../../../components/Layout/Control"
import {SwapMode} from '../../../components/Layout/Secondary'
import { SetControls, CloseControls } from '../../../components/Layout/Control'
import { SwapMode } from '../../../components/Layout/Secondary'
import * as ycore from 'ycore'
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 = {
desktop_mode: () => {
const a = localStorage.getItem('desktop_src')
if (a == 'true') {
return true
}
return false
},
desktop_mode: () => {
const a = localStorage.getItem('desktop_src')
if (a == 'true') {
return true
}
return false
},
}
export const SecondarySwap = {
close: () => {
SwapMode.close()
},
openPost: (e) => {
SwapMode.openPost(e)
}
close: () => {
SwapMode.close()
},
openPost: e => {
SwapMode.openPost(e)
},
}
export const ControlBar = {
set: (e) => {
SetControls(e)
},
close: () => {
CloseControls()
}
set: e => {
SetControls(e)
},
close: () => {
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 { 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 = {
refresh: () => {
RenderFeed.RefreshFeed()
@ -16,7 +23,7 @@ export const FeedHandler = {
export const IsThisPost = {
owner: (post_uid) => {
const a = ycore.handlerYIDT.__id()
const a = token_data.__id()
if (post_uid == a) {
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 = {
bool: (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 { FormatColorResetOutlined } from '@material-ui/icons'
export * from './api_call.js'
export const Alive_API = {
fail: (a) => {
if (a){
ycore.yconsole.log(a)
ycore.notify.error(a)
}
fail: a => {
if (a) {
ycore.yconsole.log(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){
if (!payload || !endpoint) {
return false
}
let payloadContainer = payload;
payloadContainer.append("server_key", ycore.yConfig.server_key);
const formdata = new FormData()
formdata.append('username', username)
formdata.append('password', password)
let method;
let timeout;
let processData;
let includeUserID;
const callOptions = { disabledToken: true }
ycore.API_Call(
(err, res) => {
return callback(err, res)
},
ycore.endpoints.auth_endpoint,
formdata,
callOptions
)
},
logout: callback => {
const callOptions = { includeUserID: true }
ycore.API_Call(
(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)
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
}else {
method = "POST"
timeout = 0
processData = false
includeUserID = false
}
if (includeUserID) {
payloadContainer.append("user_id", ycore.handlerYIDT.__id());
}
const requestOptions = {
"url": `${endpoint}${ycore.handlerYIDT.__token()}`,
"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('error', error)
ycore.Alive_API.fail(error)
return callback(true, error)
});
}
const optionCall = { override__token: true }
ycore.API_Call(
(err, res) => {
try {
let cooked = JSON.parse(res)['user_data']
let Ensamblator = btoa(JSON.stringify(cooked))
return callback(err, Ensamblator)
} catch (error) {
return callback(true, error)
}
},
ycore.endpoints.get_userData_endpoint,
formdata,
optionCall,
user_token
)
},
set: () => {},
},
}

View File

@ -2,117 +2,58 @@ import * as ycore from 'ycore'
import localforage from 'localforage'
export const asyncSDCP = {
setSDCP: function (value) {
return Promise.resolve().then(function () {
localforage.setItem('SDCP', value)
});
},
getRaw: () => {
try {
return localforage.getItem('SDCP');
} catch (err) {
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;
setSDCP: function(value) {
return Promise.resolve().then(function() {
localforage.setItem('SDCP', value)
})
},
getRaw: () => {
try {
return localforage.getItem('SDCP')
} catch (err) {
return false
}
payload.UserToken = values.UserToken;
payload.UserID = values.UserID;
if (payload) {
ycore.GetUserData(payload, (err, response) =>
{
let cooked = JSON.parse(response)['user_data']
let Ensamblator = btoa(JSON.stringify(cooked))
res(Ensamblator);
}
)
},
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 UpdateSDCP() {
const prefix = '[UpdateSDCP]';
ycore.GetUserData(null, (err, response) => {
let cooked = JSON.parse(response)['user_data']
let Lsdcp = [atob(sessionStorage.getItem('SDCP'))];
let Nsdcp = [JSON.stringify(cooked)]
const e1 = btoa(Lsdcp)
const e2 = btoa(Nsdcp)
const n = e1.localeCompare(e2)
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
}
}
export const cryptSDCP = {
atob_parse: e => {
if (e) {
try {
atob(e)
} catch (err) {
ycore.notify.error(err)
ycore.router.push({
pathname: '/login',
})
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')
}
try {
let decodedSDCP = atob(e)
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
},
}

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 antd from 'antd'
import Cookies from "ts-cookies";
import keys from '../../../../config/keys.js';
import * as Icons from '@ant-design/icons';
import Cookies from 'ts-cookies'
var jquery = require("jquery");
var jwt = require("jsonwebtoken")
// EXPORT PUBLIC WORKERS
export * from './token_data.js'
export * from './ctid_gen.js'
export * from './validate.js'
export function userData(){
return ycore.handlerYIDT.get()
export function userData() {
return ycore.token_data.get()
}
function __API__User (payload, sdcp, callback){
const { UserID, UserToken } = payload
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 make_data = {
backup: () => {
localStorage.setItem('last_backup', Cookies.get('cid'))
},
}
export const IsThisUser = {
admin: () => {
const a = ycore.userData()
return ycore.booleanFix(a.admin)? true : false
},
dev: () => {
const a = ycore.userData()
return ycore.booleanFix(a.dev)? true : false
},
pro: () => {
const a = ycore.userData()
return ycore.booleanFix(a.is_pro)? true : false
},
same: (a) => {
if(a == ycore.userData().UserID){
return true
}
return false
admin: () => {
const a = ycore.userData()
return ycore.booleanFix(a.admin) ? true : false
},
dev: () => {
const a = ycore.userData()
return ycore.booleanFix(a.dev) ? true : false
},
pro: () => {
const a = ycore.userData()
return ycore.booleanFix(a.is_pro) ? true : false
},
same: a => {
if (a == ycore.userData().UserID) {
return true
}
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

@ -5,36 +5,43 @@
* @licensed Pending...
*/
import {Endpoints} from "globals/endpoints.js";
import * as Icons from '@ant-design/icons';
import localforage from "localforage"
import { format } from 'timeago.js';
import umiRouter from "umi/router";
import * as antd from "antd";
import { Endpoints } from 'globals/endpoints.js'
import * as Icons from '@ant-design/icons'
import localforage from 'localforage'
import { format } from 'timeago.js'
import umiRouter from 'umi/router'
import * as antd from 'antd'
import moment from 'moment'
import React from "react";
import React from 'react'
import config from "config"
import "./libs.js"
import { func } from "prop-types";
import config from 'config'
import './libs.js'
export * from "../../config/app.settings.js"
export * from "./libs.js"
export * from '../../config/app.settings.js'
export * from './libs.js'
export var { router } = require("utils")
export var yConfig = config.yConfig;
export var endpoints = Endpoints;
export var { router } = require('utils')
export var yConfig = config.yConfig
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}`
localforage.config({
name : UUAID,
version : 1.0,
size : 4980736,
storeName : package_json.name
});
name: UUAID,
version: 1.0,
size: 4980736,
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.
@ -45,120 +52,127 @@ localforage.config({
* @return Blob
*/
export function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
contentType = contentType || ''
sliceSize = sliceSize || 512
var byteCharacters = atob(b64Data);
var byteArrays = [];
var byteCharacters = atob(b64Data)
var byteArrays = []
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize)
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
var byteNumbers = new Array(slice.length)
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
var byteArray = new Uint8Array(byteNumbers)
export function ReadFileAsB64(file, callback){
if (file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
const a = `data:image/png;base64, ${btoa(binaryString)}`
return callback(a)
};
reader.readAsBinaryString(file);
}
}
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);
byteArrays.push(byteArray)
}
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();
}
}
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();
var blob = new Blob(byteArrays, { type: contentType })
return blob
}
/**
* 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 = {
apid: package_json.name,
name: package_json.title,
version: package_json.version,
logo: config.FullLogoPath,
logo_dark: config.DarkFullLogoPath
export function ReadFileAsB64(file, callback) {
if (file) {
var reader = new FileReader()
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result
const a = `data:image/png;base64, ${btoa(binaryString)}`
return callback(a)
}
reader.readAsBinaryString(file)
}
}
/**
* 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
* @return {string} Boolean value
*/
export function SettingStoragedValue(e){
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
}
catch (error) {
return null
}
export function SettingStoragedValue(e) {
try {
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
ycore.ReturnValueFromMap({ data: fromStorage, key: e })
} 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
})
}
/**
@ -167,11 +181,49 @@ export function SettingStoragedValue(e){
* @param e {int} Numeric boolean reference
* @return {bool} Boolean value
*/
export function booleanFix(e){
if(e == 1){
return true
}
return false
export function booleanFix(e) {
if (e == 1) return true
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()
},
}
/**
@ -179,129 +231,62 @@ export function booleanFix(e){
*
*/
export const crouter = {
native: (e) =>{
umiRouter.push({
pathname: `/${e}`,
search: window.location.search,
});
},
default: (e) =>{
router.push(e)
}
native: e => {
umiRouter.push({
pathname: `/${e}`,
search: window.location.search,
})
},
default: e => {
router.push(e)
},
}
/**
* Framework functionality for show with interface an notification
*
*/
export const notify = {
success: (...res) => {
antd.notification.success({
message: 'Well',
description: (res.toString()),
placement: 'bottomLeft'
})
},
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){
success: (...res) => {
antd.notification.success({
message: 'Well',
description: res.toString(),
placement: 'bottomLeft',
})
},
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' }} >{err.toString()}</div></div>),
placement: 'bottomLeft'
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',
})
}
/**
* Render User Notification about an proccess
*
* @param cust {String} String of proccess for show
*/
export function notifyProccess(cust){
},
proccess: (...res) => {
antd.notification.open({
icon: <Icons.LoadingOutlined style={{ color: '#108ee9' }} />,
message: 'Please wait',
description: (<div>{cust}</div>),
placement: 'bottomLeft'
icon: <Icons.LoadingOutlined style={{ color: '#108ee9' }} />,
message: 'Please wait',
description: <div>{res}</div>,
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;
}
},
}
/**
@ -310,21 +295,40 @@ export function DetectNoNStableBuild(e1) {
* @param ... {any} Use for type of console
*/
export const yconsole = {
log: (...cont)=>{
SettingStoragedValue('force_showDevLogs')? console.log(...cont) : null
return
},
debug: (...cont)=>{
SettingStoragedValue('force_showDevLogs')? console.debug(...cont) : null
return
},
error: (...cont)=>{
SettingStoragedValue('force_showDevLogs')? console.error(...cont) : null
return
},
warn: (...cont)=>{
SettingStoragedValue('force_showDevLogs')? console.warn(...cont) : null
return
}
log: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.log(...cont) : null
return
},
debug: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.debug(...cont) : null
return
},
error: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.error(...cont) : null
return
},
warn: (...cont) => {
SettingStoragedValue('force_showDevLogs') ? console.warn(...cont) : null
return
},
}
/**
* 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 ycore from 'ycore'
import styles from './index.less'
import classnames from 'classnames'
import * as Icons from '@ant-design/icons';
import Icon from '@ant-design/icons'
import * as Icons from '@ant-design/icons'
export const SetHeaderSearchType = {
disable: () => {
@ -18,58 +17,60 @@ export const SetHeaderSearchType = {
},
toSecondary: () => {
window.HeaderSearchComponent.setState({ framelocation: 'secondary' })
}
},
}
export default class HeaderSearch extends Component {
constructor(props) {
super(props);
window.HeaderSearchComponent = this;
super(props)
window.HeaderSearchComponent = this
this.state = {
value: '',
searchidden: false,
framelocation: 'primary',
};
}
}
sendToSearch = () => {
const { value } = this.state;
const { value } = this.state
ycore.crouter.native(`s/${value}`)
}
onChange = e => {
const { value } = e.target;
this.setState({value: value})
const { value } = e.target
this.setState({ value: value })
if (ycore.AppSettings.auto_search_ontype == 'true') {
this.autosend()
}
};
}
autosend = () => {
let timeout = null;
let input = document.getElementById('search_input');
input.addEventListener('keyup', (e) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
const { value } = this.state;
ycore.crouter.native(`s/${value}`)
}, 500);
});
let timeout = null
let input = document.getElementById('search_input')
input.addEventListener('keyup', e => {
clearTimeout(timeout)
timeout = setTimeout(() => {
const { value } = this.state
ycore.crouter.native(`s/${value}`)
}, 500)
})
}
render() {
const { searchidden } = this.state
return (
<div className={classnames( styles.HeaderSearchWrapper, {[styles.hidden]: searchidden})}>
<span className={styles.headerSearch}>
<div
className={classnames(styles.HeaderSearchWrapper, {
[styles.hidden]: searchidden,
})}
>
<span className={styles.headerSearch}>
<antd.Input
id='search_input'
id="search_input"
prefix={<Icons.SearchOutlined />}
placeholder=' Search on Comty...'
onChange={ this.onChange }
placeholder=" Search on Comty..."
onChange={this.onChange}
onPressEnter={this.sendToSearch}
/>
</span>
</span>
</div>
);
)
}
}

View File

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

View File

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

View File

@ -3,63 +3,65 @@ import * as antd from 'antd'
import * as ycore from 'ycore'
import styles from './Control.less'
import Radium, {StyleRoot}from 'radium';
import Radium, { StyleRoot } from 'radium'
import { fadeInUp, bounceOutDown } from 'react-animations'
const animationStyles = {
fadeInUp: {
animation: 'x 0.5s',
animationName: Radium.keyframes(fadeInUp, 'fadeInUp')
},
bounceOutDown: {
animation: 'x 1s',
animationName: Radium.keyframes(bounceOutDown, 'bounceOutDown')
}
fadeInUp: {
animation: 'x 0.5s',
animationName: Radium.keyframes(fadeInUp, 'fadeInUp'),
},
bounceOutDown: {
animation: 'x 1s',
animationName: Radium.keyframes(bounceOutDown, 'bounceOutDown'),
},
}
export function SetControls(e){
window.ControlComponent.DummySetControls(e);
return
export function SetControls(e) {
window.ControlComponent.DummySetControls(e)
return
}
export function CloseControls(){
window.ControlComponent.DummyCloseControls();
return
export function CloseControls() {
window.ControlComponent.DummyCloseControls()
return
}
class Control extends React.Component {
constructor(props){
super(props)
window.ControlComponent = this;
this.state = {
Show: false,
FadeIN: true,
}
constructor(props) {
super(props)
window.ControlComponent = this
this.state = {
Show: false,
FadeIN: true,
}
DummySetControls = (e) =>{
ycore.yconsole.log('Controls recived => ', e)
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)
}
DummySetControls = e => {
ycore.yconsole.log('Controls recived => ', e)
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
)
}
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';
.ControlCard{
background-color: rgba(0, 0, 0, 0.1);
width: auto;
max-width: 60%;
padding: 0 5px 0 5px;
margin: 0 0 0 50%;
height: auto;
position: absolute;
z-index: 10000;
bottom: 0;
text-align: center;
:global {
.ant-card-body {
padding: 5px;
}
.ant-btn {
background-color: rgba(0, 0, 0, 0.1);
margin: 3px;
}
.ControlCard {
background-color: rgba(0, 0, 0, 0.1);
width: auto;
max-width: 60%;
padding: 0 5px 0 5px;
margin: 0 0 0 50%;
height: auto;
position: absolute;
z-index: 10000;
bottom: 0;
text-align: center;
:global {
.ant-card-body {
padding: 5px;
}
.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 classnames from 'classnames'
import {__priPost, __secComments} from './renders.js'
import { __priPost, __secComments } from './renders.js'
export const SwapMode = {
close: () => {
SecondaryLayoutComponent.closeSwap()
},
openPost: (a, b) => {
SecondaryLayoutComponent.setState({
swap: true,
mode: 'post',
global_raw: a,
})
}
close: () => {
SecondaryLayoutComponent.closeSwap()
},
openPost: (a, b) => {
SecondaryLayoutComponent.setState({
swap: true,
mode: 'post',
global_raw: a,
})
},
}
export default class Secondary extends React.PureComponent{
constructor(props){
super(props),
window.SecondaryLayoutComponent = this;
this.state = {
swap: false,
mode: '',
global_raw: '',
pri_raw: '',
sec_raw: '',
}
export default class Secondary extends React.PureComponent {
constructor(props) {
super(props), (window.SecondaryLayoutComponent = this)
this.state = {
swap: false,
mode: '',
global_raw: '',
pri_raw: '',
sec_raw: '',
}
}
closeSwap(){
this.setState({
swap: !this.state.swap,
pri_raw: null,
sec_raw: null,
mode: ''
})
closeSwap() {
this.setState({
swap: !this.state.swap,
pri_raw: null,
sec_raw: null,
mode: '',
})
}
SwapBalanceContent(container) {
switch (container) {
case '__pri': {
return this.__pri()
}
case '__sec': {
return this.__sec()
}
default:
return null
}
}
SwapBalanceContent(container){
switch (container){
case '__pri': {
return this.__pri()
}
case '__sec': {
return this.__sec()
}
default: return null
}
__pri() {
const dtraw = this.state.pri_raw
switch (this.state.mode) {
case 'post': {
return this.renderPost(this.state.global_raw)
}
default:
return null
}
__pri(){
const dtraw = this.state.pri_raw;
switch (this.state.mode){
case 'post': {
return this.renderPost(this.state.global_raw)
}
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
}
}
__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) => {
const post_data = JSON.parse(payload)['post_data']
console.log(post_data)
return(
<__priPost payload={post_data} />
)
}
renderPost = payload => {
const post_data = JSON.parse(payload)['post_data']
console.log(post_data)
return <__priPost payload={post_data} />
}
renderComments = (payload) => {
const post_comments = JSON.parse(payload)['post_comments']
const post_data = JSON.parse(payload)['post_data']
console.log(post_comments)
return(
<__secComments post_id={post_data.post_id} payload={post_comments} />
)
}
renderComments = payload => {
const post_comments = JSON.parse(payload)['post_comments']
const post_data = JSON.parse(payload)['post_data']
console.log(post_comments)
return <__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(){
const { userData } = this.props
return(
<div className={classnames(styles.SecondaryWrapper, {[styles.active]: this.state.swap })}>
<div
className={classnames(styles.container, {
[styles.desktop_mode]: this.props.desktop_mode,
})}
>
<div className={styles.container_body}>
{this.state.swap ? (
<antd.Button
type="ghost"
icon={<Icons.LeftOutlined />}
onClick={() => this.closeSwap()}
>
{' '}
Back{' '}
</antd.Button>
) : null}
{this.SwapBalanceContent('__pri')}
</div>
</div>
<div className={styles.UserHeader}>
<div className={styles.notif_box}></div>
<img onClick={() => ycore.crouter.native(`@${userData.username}`)} src={userData.avatar} />
</div>
<div className={classnames(styles.container, {[styles.desktop_mode]: this.props.desktop_mode})} >
<div className={styles.container_body}>
{this.state.swap? <antd.Button type="ghost" icon={<Icons.LeftOutlined />} onClick={() => this.closeSwap()} > Back </antd.Button> : null}
{this.SwapBalanceContent('__pri')}
</div>
</div>
<div className={classnames(styles.container_2, {[styles.active]: this.state.swap})}>
{this.SwapBalanceContent('__sec')}
</div>
</div>
)
}
<div
className={classnames(styles.container_2, {
[styles.active]: this.state.swap,
})}
>
{this.SwapBalanceContent('__sec')}
</div>
</div>
)
}
}

View File

@ -1,110 +1,120 @@
@SwapAnimDuration: 340ms;
.SecondaryWrapper{
width: 27%;
height: 100vh;
.SecondaryWrapper {
width: 27%;
height: 100vh;
position: relative;
float: left;
overflow-y: hidden !important;
overflow-x: hidden;
position: relative;
float: left;
overflow-y: hidden !important;
overflow-x: hidden;
display: flex;
display: flex;
&.active{
width: 96vw;
position: absolute;
right: 0;
>.container{
border-radius: 12px 12px 12px 12px;
}
&.active {
width: 96vw;
position: absolute;
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{
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);
img:hover {
box-shadow: 0px 0px 10px 0px rgba(255, 255, 255, 0.205);
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;
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);
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;
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;
}
.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);
transition: all 150ms linear;
}
}
}
.container_body{
padding: 30px 375px 30px 75px;
}
.container_body {
padding: 30px 375px 30px 75px;
}
.container_2 {
z-index: 51;
background-color: #fff;
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;
}
.container_2{
z-index: 51;
transition: all @SwapAnimDuration ease-in-out;
}
background-color: #fff;
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{
}
.comments_body {}

View File

@ -6,151 +6,196 @@ import * as ycore from 'ycore'
import * as Icons 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{
renderContent(payload){
const { id, postText, postFile_full, post_time, publisher} = payload
if (!postFile_full) {
return(
<div className={styles.postContent_OnlyText}>
<PostCard payload={payload} />
</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>
)
export class __priPost extends React.Component {
renderContent(payload) {
const { id, postText, postFile_full, post_time, publisher } = payload
if (!postFile_full) {
return (
<div className={styles.postContent_OnlyText}>
<PostCard payload={payload} />
</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(){
const payload = this.props.payload
if (!payload) {
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>
)
render() {
const payload = this.props.payload
if (!payload) {
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>
)
}
}
export class __secComments extends React.Component {
state = {
comment_data: this.props.payload,
raw_comment: '',
loading: false
}
handleDeleteComment(id){
console.log(`Removing Comment with id => ${id}`)
ycore.Post_Comments.delete((err, res) => { if(err){return false} return this.reloadComments() }, {comment_id: id})
}
handleNewComment(){
const { raw_comment } = this.state
const { post_id } = this.props
if (raw_comment) {
const payload = { post_id: post_id, raw_text: raw_comment }
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)
state = {
comment_data: this.props.payload,
raw_comment: '',
loading: false,
}
handleDeleteComment(id) {
console.log(`Removing Comment with id => ${id}`)
ycore.comty_post_comment.delete(
(err, res) => {
if (err) {
return false
}
return false
}
renderComment = (a) => {
const {id, time, Orginaltext, publisher} = a
const CommentMenu = (
<antd.Menu>
<antd.Menu.Item key="remove_comment" onClick={()=> this.handleDeleteComment(id)}><Icons.DeleteOutlined /> Delete</antd.Menu.Item>
</antd.Menu>
);
return (
<div className={styles.comment_card}>
<div className={styles.comment_title}>
<img src={publisher.avatar} />
<p className={styles.comment_user_username}>@{publisher.username} {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
return this.reloadComments()
},
{ comment_id: id }
)
}
handleNewComment() {
const { raw_comment } = this.state
const { post_id } = this.props
if (raw_comment) {
const payload = { post_id: post_id, raw_text: raw_comment }
ycore.comty_post_comment.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
}
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>
)
renderComment = a => {
const { id, time, Orginaltext, publisher } = a
const CommentMenu = (
<antd.Menu>
<antd.Menu.Item
key="remove_comment"
onClick={() => this.handleDeleteComment(id)}
>
<Icons.DeleteOutlined /> Delete
</antd.Menu.Item>
</antd.Menu>
)
return (
<div className={styles.comment_card}>
<div className={styles.comment_title}>
<img src={publisher.avatar} />
<p className={styles.comment_user_username}>
@{publisher.username}{' '}
{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
}
}
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';
.SecondaryBody{
width: 100%;
height: 100%;
.SecondaryBody {
width: 100%;
height: 100%;
}
.UserContainer{
display: flex;
position: relative;
float: right;
z-index: 150;
transform: translate(0, -40px);
.UserContainer_text{
margin: 0 8px;
h4 { text-align: right; }
p { word-break: break-all; text-align: right; font-size: 11px; color: #eeeeee!important; }
.UserContainer {
display: flex;
position: relative;
float: right;
z-index: 150;
transform: translate(0, -40px);
.UserContainer_text {
margin: 0 8px;
h4 {
text-align: right;
}
}
.postAvatar{
position: absolute;
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;
}
.MoreMenu{
color: #2d2d2d !important;
}
p {
word-break: break-all;
text-align: right;
font-size: 11px;
color: #eeeeee !important;
}
}
}
.titleWrapper{
display: flex;
h4{
cursor: pointer;
.postAvatar {
position: absolute;
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;
}
.contentWrapper{
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;
.MoreMenu {
color: #2d2d2d !important;
}
}
}
.postContent_OnlyText{
padding: 25% 0 0 0;
position: relative;
vertical-align: middle;
.titleWrapper {
display: flex;
h4 {
cursor: pointer;
}
color: #ffffff !important;
}
.likebtn{
:global{
svg{
color:rgba(0, 0, 0, 0.45);
}
svg:hover{
color: rgb(233, 35, 68);
transition: all 0.2s linear;
}
}
.contentWrapper {
margin: auto;
width: 100%;
padding: 20px;
}
.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;
padding: 75px 10px 10px 20px;
color: #ffffff;
font-weight: 400;
font-size: 15px;
letter-spacing: -0.3px;
}
}
.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;
}
}
}
}
.postContent_OnlyText {
padding: 25% 0 0 0;
position: relative;
vertical-align: middle;
}
.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 classnames from 'classnames'
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 { withI18n, Trans } from '@lingui/react'
import ScrollBar from '../ScrollBar'
import { config } from 'utils'
import styles from './Sider.less'
import * as ycore from 'ycore';
import router from 'umi/router';
import {CustomIcons} from 'components'
import * as ycore from 'ycore'
import router from 'umi/router'
import { CustomIcons } from 'components'
@withI18n()
class Sider extends PureComponent {
constructor(props) {
super(props);
super(props)
this.state = {
isHover: false,
collapsedWidth: '30',
};
}
}
StrictMode = () =>{
const { theme } = this.props;
StrictMode = () => {
const { theme } = this.props
if (ycore.AppSettings.StrictLightMode == false) {
return "dark"
return 'dark'
}
return theme
}
handleClickMenu = e => {
e.key === 'SignOut' && ycore.LogoutCall()
e.key === 'SignOut' && ycore.app_session.logout()
e.key === 'general_settings' && ycore.crouter.native('settings')
e.key === 'accountpage' && router.push('/account')
e.key === 'explore' && router.push('main')
e.key === 'admin_area' && router.push('__m')
}
isDarkMode(){
isDarkMode() {
const { theme } = this.props
if (theme == 'dark'){
if (theme == 'dark') {
return true
}
return false
@ -57,81 +57,142 @@ class Sider extends PureComponent {
} = this.props
return (
<div className={styles.siderwrapper}>
<antd.Layout.Sider
breakpoint="lg"
trigger={null}
collapsible
defaultCollapsed="true"
collapsedWidth={this.state.collapsedWidth}
theme={this.StrictMode()}
width="180"
collapsed={collapsed}
className={classnames(styles.sider, {[styles.darkmd]: this.isDarkMode(), [styles.desktop_mode]: this.props.desktop_mode} )}
onMouseEnter={() => this.setState({ collapsedWidth: '90' })}
onMouseLeave={() => this.setState({ collapsedWidth: '35' })}
>
<div className={styles.brand}><img onClick={() => ycore.crouter.native('main')} src={collapsed? config.LogoPath : config.FullLogoPath } /></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.Layout.Sider
breakpoint="lg"
trigger={null}
collapsible
defaultCollapsed="true"
collapsedWidth={this.state.collapsedWidth}
theme={this.StrictMode()}
width="180"
collapsed={collapsed}
className={classnames(styles.sider, {
[styles.darkmd]: this.isDarkMode(),
[styles.desktop_mode]: this.props.desktop_mode,
})}
onMouseEnter={() => this.setState({ collapsedWidth: '90' })}
onMouseLeave={() => this.setState({ collapsedWidth: '35' })}
>
<div className={styles.brand}>
<img
onClick={() => ycore.crouter.native('main')}
src={collapsed ? config.LogoPath : config.FullLogoPath}
/>
</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">
<Icons.ReadOutlined />
<Trans><span>Journal</span></Trans>
</antd.Menu.Item>
<antd.Menu.Item key="journal_page">
<Icons.ReadOutlined />
<Trans>
<span>Journal</span>
</Trans>
</antd.Menu.Item>
<antd.Menu.Item key="marketplace_page">
<Icons.ReconciliationOutlined />
<Trans><span>Marketplace</span></Trans>
</antd.Menu.Item>
<antd.Menu.Item key="marketplace_page">
<Icons.ReconciliationOutlined />
<Trans>
<span>Marketplace</span>
</Trans>
</antd.Menu.Item>
</antd.Menu>
</antd.Menu>
<div className={styles.something_thats_pulling_me_down}>
<antd.Menu selectable={false} className={collapsed ? styles.menuItemsCollapsed : styles.menuItems} mode="vertical" onClick={this.handleClickMenu}>
<antd.Menu.Item key="general_settings">
<Icons.SettingOutlined/>
<Trans><span>Settings</span></Trans>
</antd.Menu.Item>
{ycore.booleanFix(userData.admin)?
<antd.Menu.Item key="admin_area">
<Icons.ThunderboltOutlined />
<Trans><span>{userData.username}</span></Trans>
</antd.Menu.Item>
:
undefined
}
<antd.Menu.Item style={{ fontSize: '15px' }} key="LightMode" disabled={false} >
{collapsed? <Icons.BulbOutlined /> :
<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>
<div className={styles.something_thats_pulling_me_down}>
<antd.Menu
selectable={false}
className={
collapsed ? styles.menuItemsCollapsed : styles.menuItems
}
mode="vertical"
onClick={this.handleClickMenu}
>
<antd.Menu.Item key="general_settings">
<Icons.SettingOutlined />
<Trans>
<span>Settings</span>
</Trans>
</antd.Menu.Item>
{ycore.booleanFix(userData.admin) ? (
<antd.Menu.Item key="admin_area">
<Icons.ThunderboltOutlined />
<Trans>
<span>{userData.username}</span>
</Trans>
</antd.Menu.Item>
) : (
undefined
)}
<antd.Menu.Item
style={{ fontSize: '15px' }}
key="LightMode"
disabled={false}
>
{collapsed ? (
<Icons.BulbOutlined />
) : (
<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>
</div>
</antd.Layout.Sider>
</div>
</div>
</antd.Layout.Sider>
</div>
)
}
}

View File

@ -6,15 +6,16 @@
@LDarkMode-color: #fff;
@LLightMode-color: #2F2E30;
.CollapserWrapperLight{
.CollapserWrapperLight {
height: 100%;
position: absolute;
float: left;
top: 0;
top: 0;
left: 0;
z-index: 200;
vertical-align: middle;
:global{
:global {
.ant-btn {
border: none;
@ -27,23 +28,25 @@
box-shadow: none;
transition: all 1s ease-in;
}
.ant-btn:hover{
.ant-btn:hover {
background: rgba(121, 121, 121, 0.247);
background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(252, 252, 252, 0.13) 95%);
transition: all 1s ease-in;
}
}
}
}
.CollapserWrapperDark{
.CollapserWrapperDark {
height: 100%;
position: absolute;
float: left;
top: 0;
top: 0;
left: 0;
z-index: 200;
vertical-align: middle;
:global{
:global {
.ant-btn {
border: none;
border-radius: unset;
@ -55,17 +58,19 @@
box-shadow: none;
transition: all 1s ease-in;
}
.ant-btn:hover{
.ant-btn:hover {
background: rgba(121, 121, 121, 0.247);
background: linear-gradient(270deg, rgba(121, 121, 121, 0) 0%, rgba(121, 121, 121, 0.13) 95%);
transition: all 1s ease-in;
}
}
}
}
.brand {
cursor: pointer;
img{
img {
display: flex;
vertical-align: middle;
padding: 5px;
@ -76,31 +81,34 @@
}
.avatarFull{
.avatarFull {
width: 120px;
}
.avatar{
.avatar {
margin: 0 0 15px 0;
}
.something_thats_pulling_me_down{
:global{
.something_thats_pulling_me_down {
:global {
text-align: center;
bottom: 0;
position: absolute;
width: 100%;
}
}
.siderhead{
.siderhead {
cursor: pointer;
font-family: 'Source Sans Pro', sans-serif;
display: flex;
align-items: center;
justify-content: center;
::first-letter{
::first-letter {
margin-left: 7px;
}
height: 60px;
font-size: 17px;
}
@ -118,34 +126,47 @@
.ant-layout-sider-dark {
background-color: @LDarkMode-backgroud;
color: @DarkMode-color;
h2{
h2 {
color: @Theme-SiderDeco-Color;
}
.ant-menu-item{
.ant-menu-item {
color: @DarkMode-color;
}
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
:hover {
background-color: rgb(80, 80, 80);
color: #fff;
}
border-right: 1px solid transparent;
}
}
.ant-layout-sider-light {
background-color: @Theme-SiderDeco-Backgroud;
color: @Theme-SiderDeco-Color;
h2{
h2 {
color: @Theme-SiderDeco-Color;
}
.ant-menu-item{
.ant-menu-item {
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 {
background-color: @Theme-Hover-Backgroud;
color: #fff;
}
border-right: 1px solid transparent;
}
}
@ -154,114 +175,138 @@
.sider {
border-right: transparent;
&.desktop_mode{
&.desktop_mode {
border-radius: 12px 0 0 12px;
}
height: 100%;
z-index: 50;
:global {
.ant-menu-sub {
font-size: 14px;
-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);
box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005);
}
.ant-menu-dark {
background-color: @LDarkMode-backgroud;
color: @LDarkMode-color;
.ant-menu-sub {
font-size: 14px;
-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);
box-shadow: 13px 4px 34px 0px rgba(0, 0, 0, 0.005);
}
.ant-menu-light {
background-color: @LLightMode-backgroud;
color: @LLightMode-color;
.ant-menu-dark {
background-color: @LDarkMode-backgroud;
color: @LDarkMode-color;
}
.ant-menu-light {
background-color: @LLightMode-backgroud;
color: @LLightMode-color;
}
}
.menuItems{
.menuItems {
background-color: transparent;
margin-bottom: 8px;
width: 100%;
font-weight: 500;
animation: fadein 0.5s;
:global {
.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;
}
:global {
.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;
}
}
}
.menuItemsCollapsed{
.menuItemsCollapsed {
background-color: transparent;
margin-bottom: 8px;
width: 100%;
font-weight: 500;
animation: fadein 0.5s;
:global {
.ant-menu-item-selected{
background-color: transparent;
}
.ant-menu-item {
padding: 0 !important;
margin: 2px 0 2px 0;
width: 100%;
text-align: center;
}
:global {
.ant-menu-item-selected {
background-color: transparent;
}
.ant-menu-item {
padding: 0 !important;
margin: 2px 0 2px 0;
width: 100%;
text-align: center;
}
}
}
.menuContainer {
height: 100%;
margin: 18px 0 8px 0;
.scrollbar-container {
position: initial;
height: 100%;
}
overflow-x: hidden;
flex: 1;
&::-webkit-scrollbar-thumb {
background-color: transparent;
}
&:hover {
&::-webkit-scrollbar-thumb {
background-color: rgba(59, 59, 59, 0.2);
}
}
:global {
.ant-layout-sider-children {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.ant-layout-sider-collapsed {
.ant-menu-item {
left: 0;
margin: 0;
padding: 0;
}
.ant-menu-inline-collapsed > .ant-menu-item{
.ant-menu-inline-collapsed>.ant-menu-item {
padding: 0;
left:0;
left: 0;
}
}
.scrollbar-container {
position: initial;
height: 100%;
}
.ant-menu-inline .ant-menu-item {
font-size: 14px;
font-family: 'Source Sans Pro', sans-serif;
}
.ant-menu-dark .ant-menu-item a {
color: rgb(197, 197, 197);
}
}
}
}
.scrollbar-container {
position: initial;
height: 100%;
@ -285,10 +330,12 @@
background-color: #2F2E30;
}
}
svg {
height: 100%;
vertical-align: middle;
}
span {
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 Control from './Control'
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 {
position: relative;
box-sizing: border-box;
}
.ripple, .ripple:before, .ripple:after {
.like_button,
.like_button:before,
.like_button:after {
position: relative;
box-sizing: border-box;
}
.btnWrapper{
.ripple,
.ripple:before,
.ripple:after {
position: relative;
box-sizing: border-box;
}
.btnWrapper {
display: flex;
}
.likeCounter{
.likeCounter {
font-family: "Poppins", sans-serif;
line-height: 70px;
margin: 0 0 0 10px;
@ -20,14 +25,16 @@
transform: perspective(100px) translateZ(10px);
filter: blur(10px);
letter-spacing: 0.1em;
&.active{
&.active {
opacity: 1;
transform: perspective(100px) translateZ(0px);
filter: blur(0px);
letter-spacing: 0.15em;
transition: opacity 1000ms linear, transform 1000ms linear, filter 400ms linear, letter-spacing 1000ms linear;
}
&.past{
&.past {
opacity: 0;
transform: perspective(100px) translateZ(-10px);
filter: blur(10px);
@ -39,7 +46,7 @@
.like_button {
--color-heart: #EA442B;
--easing: cubic-bezier(.7,0,.3,1);
--easing: cubic-bezier(.7, 0, .3, 1);
--duration: .5s;
font-size: 40px;
@ -83,18 +90,24 @@
@keyframes depress {
from, to {
from,
to {
transform: none;
}
50% {
transform: translateY(5%) scale(0.9);
}
}
@keyframes depress-shadow {
from, to {
from,
to {
transform: none;
}
50% {
transform: scale(0.5);
}
@ -106,7 +119,8 @@
align-items: center;
justify-content: center;
z-index: 1;
> * {
>* {
margin: auto;
grid-area: 1 / 1;
}
@ -116,17 +130,17 @@
width: .5em;
height: .5em;
display: block;
transform-origin: center 80%;
transform-origin: center 80%;
> path {
>path {
stroke: var(--color-heart);
stroke-width: 2;
transition: fill var(--duration) var(--easing);
fill: var(--color-heart);
}
&.empty{
> path {
&.empty {
>path {
stroke: var(--color-heart);
stroke-width: 2;
transition: fill var(--duration) var(--easing);
@ -134,18 +148,23 @@
}
}
&.clickanim{
&.clickanim {
animation: heart-bounce var(--duration) var(--easing);
@keyframes heart-bounce {
40% { transform: scale(0.7); }
0%, 80%, 100% { transform: scale(1); }
40% {
transform: scale(0.7);
}
0%,
80%,
100% {
transform: scale(1);
}
}
}
animation: none;
}
.ripple {
@ -166,16 +185,21 @@
border-radius: inherit;
transform: scale(0);
}
&.clickanim{
&.clickanim {
&:before {
animation: ripple-out var(--duration) var(--easing);
@keyframes ripple-out {
from { transform: scale(0); }
to { transform: scale(5); }
from {
transform: scale(0);
}
to {
transform: scale(5);
}
}
}
}
}

View File

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

View File

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

View File

@ -3,165 +3,194 @@ import * as antd from 'antd'
import * as ycore from 'ycore'
import * as Icons from '@ant-design/icons'
import {PostCard} from 'components'
import { PostCard } from 'components'
export const RenderFeed = {
RefreshFeed: () => {
window.MainFeedComponent.FirstGet();
return
},
killByID: (post_id) => {
window.MainFeedComponent.killByID(post_id);
return
},
addToRend: (payload) => {
window.MainFeedComponent.addToRend(payload);
return
}
RefreshFeed: () => {
window.MainFeedComponent.FirstGet()
return
},
killByID: post_id => {
window.MainFeedComponent.killByID(post_id)
return
},
addToRend: payload => {
window.MainFeedComponent.addToRend(payload)
return
},
}
class MainFeed extends React.Component {
constructor(props){
super(props)
window.MainFeedComponent = this;
this.state = {
invalid: false,
loading: false,
data: [],
fkey: 0
constructor(props) {
super(props)
window.MainFeedComponent = this
this.state = {
invalid: false,
loading: false,
data: [],
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']
const isEnd =
parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: parsed, loading: false })
}, payload)
} catch (err) {
ycore.notify.error('err')
}
}
componentDidMount(){
this.FirstGet()
GetMore(fkey) {
try {
const { get, uid, filters } = this.props
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
if (!fkey) {
ycore.yconsole.warn(
'Please, provide a fkey for offset the feed, default using => 0'
)
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
ycore.comty_post.getFeed((err, res) => {
if (err) {
return false
}
const oldData = this.state.data
const parsed = JSON.parse(res)['data']
const mix = oldData.concat(parsed)
const isEnd =
parsed.length < ycore.AppSettings.limit_post_catch ? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () =>
ycore.gotoElement(getLastPost.id)
)
return true
}, payload)
} catch (err) {
ycore.notify.error(err)
}
}
toogleLoader(){
this.setState({ loading: !this.state.loading })
renderFeedPosts = () => {
const { data, loading, isEnd } = this.state
const loadMore =
!isEnd && !loading ? (
<div
style={{
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}}
>
<antd.Button
type="ghost"
icon={<Icons.DownSquareOutlined />}
onClick={() => this.GetMore()}
/>
</div>
) : null
try {
ycore.yconsole.log(data)
return (
<antd.List
loadMore={loadMore}
dataSource={data}
renderItem={item => (
<div id={item.id}>
<PostCard payload={item} key={item.id} />
</div>
)}
/>
)
} catch (err) {
return false
}
}
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.notifyError('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']
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false
this.setState({ isEnd: isEnd, data: parsed, loading: false })
}, payload)
}catch(err){
ycore.notifyError('err')
}
}
GetMore(fkey){
try{
const { get, uid, filters } = this.props;
if (!get) {
ycore.yconsole.error('Please, fill params with an catch type...')
return
}
if (!fkey) {
ycore.yconsole.warn('Please, provide a fkey for offset the feed, default using => 0');
}
this.toogleLoader()
const getLastPost = ycore.objectLast(this.state.data)
ycore.yconsole.log('LAST POST ID =>', getLastPost.id)
const payload = { fkey: getLastPost.id, type: get, id: uid }
ycore.comty_post.getFeed((err,res) => {
if (err){return false}
const oldData = this.state.data
const parsed = JSON.parse(res)['data']
const mix = oldData.concat(parsed)
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : false
this.setState({ isEnd: isEnd, data: mix, loading: false }, () => ycore.gotoElement(getLastPost.id) )
return true
}, payload)
}catch(err){
ycore.notifyError(err)
}
}
renderFeedPosts = () =>{
const {data, loading, isEnd} = this.state
const loadMore =
!isEnd && !loading ? (
<div style={{
render() {
const { loading, invalid } = this.state
return (
<div id="mainfeed">
{invalid ? (
<antd.Card
style={{
borderRadius: '10px',
maxWidth: '26.5vw',
margin: 'auto',
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}}
>
<antd.Button type="ghost" icon={<Icons.DownSquareOutlined />} onClick={() => this.GetMore()} />
</div>
) : null;
try {
ycore.yconsole.log(data)
return (
<antd.List
loadMore={loadMore}
dataSource={data}
renderItem={item => (<div id={item.id}><PostCard payload={item} key={item.id} /></div>)}
/>
)
} catch (err) {
return false
}
}
render(){
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>
)
}
<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'
export default class MediaPlayer extends React.PureComponent {
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} />
)
}
renderPostPlayer(payload) {
const ident = payload
if (ident.includes('.mp4')) {
return (
<video id="player" playsInline controls>
<source src={`${payload}`} type="video/mp4" />
</video>
)
}
render(){
const {file} = this.props
return (
<div className={styles.PlayerContainer}>
{this.renderPostPlayer(file)}
</div>
)
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() {
const { file } = this.props
return (
<div className={styles.PlayerContainer}>
{this.renderPostPlayer(file)}
</div>
)
}
}

View File

@ -1,28 +1,31 @@
.PlayerContainer{
max-width: 100vw;
max-height: 75vh;
img {
object-fit: contain;
position: absolute;
top: 50%;
left: 47%;
width: 500px;
height: 500px;
margin-top: -250px;
margin-left: -350px;
}
video {
object-fit: contain;
position: absolute;
top: 50%;
left: 47%;
width: 500px;
height: 500px;
margin-top: -250px;
margin-left: -350px;
}
h3{
color: rgb(85, 85, 85);
font-weight: 470;
}
.PlayerContainer {
max-width: 100vw;
max-height: 75vh;
img {
object-fit: contain;
position: absolute;
top: 50%;
left: 47%;
width: 500px;
height: 500px;
margin-top: -250px;
margin-left: -350px;
}
video {
object-fit: contain;
position: absolute;
top: 50%;
left: 47%;
width: 500px;
height: 500px;
margin-top: -250px;
margin-left: -350px;
}
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 * 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 = {
resbypass: store.get('resbypass') || false,
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>
)
}
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
}
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{
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;
:global {
.ant-result-title {
color: white;
}
: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 {
moveToLeft: {
@ -8,7 +8,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromLeft: {
keyframes: keyframes`
@ -16,7 +16,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToRight: {
keyframes: keyframes`
@ -25,7 +25,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromRight: {
keyframes: keyframes`
@ -33,7 +33,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToTop: {
keyframes: keyframes`
@ -42,7 +42,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromTop: {
keyframes: keyframes`
@ -50,7 +50,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToBottom: {
keyframes: keyframes`
@ -59,7 +59,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromBottom: {
keyframes: keyframes`
@ -67,7 +67,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
fade: {
keyframes: keyframes`
@ -76,7 +76,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToLeftFade: {
keyframes: keyframes`
@ -85,7 +85,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromLeftFade: {
keyframes: keyframes`
@ -93,7 +93,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToRightFade: {
keyframes: keyframes`
@ -102,7 +102,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromRightFade: {
keyframes: keyframes`
@ -110,7 +110,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToTopFade: {
keyframes: keyframes`
@ -119,7 +119,7 @@ export default {
`,
duration: 600,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromTopFade: {
keyframes: keyframes`
@ -127,7 +127,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveToBottomFade: {
keyframes: keyframes`
@ -136,7 +136,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
moveFromBottomFade: {
keyframes: keyframes`
@ -144,7 +144,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleDown: {
keyframes: keyframes`
@ -153,7 +153,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleUp: {
keyframes: keyframes`
@ -161,7 +161,7 @@ export default {
`,
duration: 700,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleUpDown: {
keyframes: keyframes`
@ -169,7 +169,7 @@ export default {
`,
duration: 500,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleDownUp: {
keyframes: keyframes`
@ -178,7 +178,7 @@ export default {
`,
duration: 500,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleDownCenter: {
keyframes: keyframes`
@ -187,7 +187,7 @@ export default {
`,
duration: 400,
timing: 'ease',
fill: 'both'
fill: 'both',
},
scaleUpCenter: {
keyframes: keyframes`
@ -195,7 +195,7 @@ export default {
`,
duration: 400,
timing: 'ease',
fill: 'both'
fill: 'both',
},
rotateRightSideFirst: {
keyframes: keyframes`
@ -206,7 +206,7 @@ export default {
duration: 800,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateLeftSideFirst: {
keyframes: keyframes`
@ -217,7 +217,7 @@ export default {
duration: 800,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateTopSideFirst: {
keyframes: keyframes`
@ -228,7 +228,7 @@ export default {
duration: 800,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateBottomSideFirst: {
keyframes: keyframes`
@ -239,7 +239,7 @@ export default {
duration: 800,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
flipOutRight: {
keyframes: keyframes`
@ -249,7 +249,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipInLeft: {
keyframes: keyframes`
@ -258,7 +258,7 @@ export default {
duration: 500,
timing: 'ease-out',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipOutLeft: {
keyframes: keyframes`
@ -268,7 +268,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipInRight: {
keyframes: keyframes`
@ -277,7 +277,7 @@ export default {
duration: 500,
timing: 'ease-out',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipOutTop: {
keyframes: keyframes`
@ -287,7 +287,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipInBottom: {
keyframes: keyframes`
@ -296,7 +296,7 @@ export default {
duration: 500,
timing: 'ease-out',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipOutBottom: {
keyframes: keyframes`
@ -306,7 +306,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
flipInTop: {
keyframes: keyframes`
@ -315,7 +315,7 @@ export default {
duration: 500,
timing: 'ease-out',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
rotateFall: {
keyframes: keyframes`
@ -328,7 +328,7 @@ export default {
duration: 1000,
timing: 'ease-in',
fill: 'both',
origin: '0% 0%'
origin: '0% 0%',
},
rotateOutNewspaper: {
keyframes: keyframes`
@ -338,7 +338,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
rotateInNewspaper: {
keyframes: keyframes`
@ -347,7 +347,7 @@ export default {
duration: 500,
timing: 'ease-out',
fill: 'both',
origin: '50% 50%'
origin: '50% 50%',
},
rotatePushLeft: {
keyframes: keyframes`
@ -357,7 +357,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotatePushRight: {
keyframes: keyframes`
@ -367,7 +367,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotatePushTop: {
keyframes: keyframes`
@ -377,7 +377,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotatePushBottom: {
keyframes: keyframes`
@ -387,7 +387,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotatePullRight: {
keyframes: keyframes`
@ -396,7 +396,7 @@ export default {
duration: 500,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotatePullLeft: {
keyframes: keyframes`
@ -405,7 +405,7 @@ export default {
duration: 500,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotatePullTop: {
keyframes: keyframes`
@ -414,7 +414,7 @@ export default {
duration: 500,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotatePullBottom: {
keyframes: keyframes`
@ -423,7 +423,7 @@ export default {
duration: 500,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateFoldRight: {
keyframes: keyframes`
@ -433,7 +433,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateFoldLeft: {
keyframes: keyframes`
@ -443,7 +443,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateFoldTop: {
keyframes: keyframes`
@ -453,7 +453,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateFoldBottom: {
keyframes: keyframes`
@ -463,7 +463,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateUnfoldLeft: {
keyframes: keyframes`
@ -472,7 +472,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateUnfoldRight: {
keyframes: keyframes`
@ -481,7 +481,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateUnfoldTop: {
keyframes: keyframes`
@ -490,7 +490,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateUnfoldBottom: {
keyframes: keyframes`
@ -499,7 +499,7 @@ export default {
duration: 700,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateRoomLeftOut: {
keyframes: keyframes`
@ -509,7 +509,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateRoomLeftIn: {
keyframes: keyframes`
@ -518,7 +518,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateRoomRightOut: {
keyframes: keyframes`
@ -528,7 +528,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateRoomRightIn: {
keyframes: keyframes`
@ -537,7 +537,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateRoomTopOut: {
keyframes: keyframes`
@ -547,7 +547,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateRoomTopIn: {
keyframes: keyframes`
@ -556,7 +556,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateRoomBottomOut: {
keyframes: keyframes`
@ -566,7 +566,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateRoomBottomIn: {
keyframes: keyframes`
@ -575,7 +575,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateCubeLeftOut: {
keyframes: keyframes`
@ -586,7 +586,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateCubeLeftIn: {
keyframes: keyframes`
@ -596,7 +596,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateCubeRightOut: {
keyframes: keyframes`
@ -607,7 +607,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateCubeRightIn: {
keyframes: keyframes`
@ -617,7 +617,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateCubeTopOut: {
keyframes: keyframes`
@ -628,7 +628,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateCubeTopIn: {
keyframes: keyframes`
@ -638,7 +638,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateCubeBottomOut: {
keyframes: keyframes`
@ -649,7 +649,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateCubeBottomIn: {
keyframes: keyframes`
@ -659,7 +659,7 @@ export default {
duration: 600,
timing: 'ease-in',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateCarouselLeftOut: {
keyframes: keyframes`
@ -669,7 +669,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateCarouselLeftIn: {
keyframes: keyframes`
@ -678,7 +678,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateCarouselRightOut: {
keyframes: keyframes`
@ -688,7 +688,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '0% 50%'
origin: '0% 50%',
},
rotateCarouselRightIn: {
keyframes: keyframes`
@ -697,7 +697,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '100% 50%'
origin: '100% 50%',
},
rotateCarouselTopOut: {
keyframes: keyframes`
@ -707,7 +707,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateCarouselTopIn: {
keyframes: keyframes`
@ -716,7 +716,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateCarouselBottomOut: {
keyframes: keyframes`
@ -726,7 +726,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 0%'
origin: '50% 0%',
},
rotateCarouselBottomIn: {
keyframes: keyframes`
@ -735,7 +735,7 @@ export default {
duration: 800,
timing: 'ease',
fill: 'both',
origin: '50% 100%'
origin: '50% 100%',
},
rotateSidesOut: {
keyframes: keyframes`
@ -745,7 +745,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '-50% 50%'
origin: '-50% 50%',
},
rotateSidesIn: {
keyframes: keyframes`
@ -754,7 +754,7 @@ export default {
duration: 500,
timing: 'ease-in',
fill: 'both',
origin: '150% 50%'
origin: '150% 50%',
},
rotateSlideOut: {
keyframes: keyframes`
@ -765,7 +765,7 @@ export default {
`,
duration: 1000,
timing: 'ease',
fill: 'both'
fill: 'both',
},
rotateSlideIn: {
keyframes: keyframes`
@ -775,6 +775,6 @@ export default {
`,
duration: 1000,
timing: 'ease',
fill: 'both'
}
};
fill: 'both',
},
}

View File

@ -1,8 +1,8 @@
import React, { memo } from 'react';
import { Transition, TransitionGroup } from 'react-transition-group';
import animations from './animations';
import presets from './presets';
import * as Styles from './styles';
import React, { memo } from 'react'
import { Transition, TransitionGroup } from 'react-transition-group'
import animations from './animations'
import presets from './presets'
import * as Styles from './styles'
function PageTransition({
children,
@ -15,48 +15,48 @@ function PageTransition({
const selectEnterAnimation = () => {
if (enterAnimationOverride) {
if (typeof enterAnimationOverride === 'string') {
return animations[enterAnimationOverride];
return animations[enterAnimationOverride]
}
return {
...animations[enterAnimationOverride.name],
delay: enterAnimationOverride.delay,
onTop: enterAnimationOverride.onTop
};
onTop: enterAnimationOverride.onTop,
}
}
if (preset) {
return {
...animations[presets[preset].enter.name],
delay: presets[preset].enter.delay,
onTop: presets[preset].enter.onTop
};
onTop: presets[preset].enter.onTop,
}
}
return 'rotateSlideIn';
};
return 'rotateSlideIn'
}
const selectExitAnimation = () => {
if (exitAnimationOverride) {
if (typeof exitAnimationOverride === 'string') {
return animations[exitAnimationOverride];
return animations[exitAnimationOverride]
}
return {
...animations[exitAnimationOverride.name],
delay: exitAnimationOverride.delay,
onTop: exitAnimationOverride.onTop
};
onTop: exitAnimationOverride.onTop,
}
}
if (preset) {
return {
...animations[presets[preset].exit.name],
delay: presets[preset].exit.delay,
onTop: presets[preset].exit.onTop
};
onTop: presets[preset].exit.onTop,
}
}
return 'rotateSlideIn';
};
return 'rotateSlideIn'
}
const enterAnimation = selectEnterAnimation();
const exitAnimation = selectExitAnimation();
const timeout = Math.max(enterAnimation.duration, exitAnimation.duration);
const enterAnimation = selectEnterAnimation()
const exitAnimation = selectExitAnimation()
const timeout = Math.max(enterAnimation.duration, exitAnimation.duration)
return (
<Styles.PageTransitionGroup {...rest}>
@ -74,7 +74,7 @@ function PageTransition({
</Transition>
</TransitionGroup>
</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 = ({
keyframes,
@ -7,7 +7,7 @@ const createAnimationStyles = ({
timing,
fill,
origin,
onTop
onTop,
}) => css`
animation-name: ${keyframes};
animation-delay: ${delay};
@ -19,27 +19,27 @@ const createAnimationStyles = ({
css`
z-index: 1;
`}
`;
`
const stateMap = {
entering: ({ enterAnimation }) => {
return css`
${createAnimationStyles(enterAnimation)};
`;
`
},
exiting: ({ exitAnimation }) => {
return css`
${createAnimationStyles(exitAnimation)};
`;
}
};
`
},
}
export const PageTransitionGroup = styled.div`
position: relative;
width: 100%;
height: 100%;
perspective: 1200px;
`;
`
export const PageTransition = styled.div`
backface-visibility: hidden;
@ -51,4 +51,4 @@ export const PageTransition = styled.div`
transform: translate3d(0, 0, 0);
width: 100%;
${({ state }) => stateMap[state]};
`;
`

View File

@ -1,135 +1,296 @@
import React from 'react'
import * as antd from 'antd'
import styles from './index.less'
import {CustomIcons, LikeBTN} from 'components'
import { CustomIcons, Like_button } from 'components'
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 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
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',
ago: 'This Post is empty',
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
content: 'Test Test',
}
class PostCard extends React.PureComponent{
constructor(props){
super(props),
this.state = {
FadeIN: true
}
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>
)
}
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} />
)
}
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)
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
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
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}`)
}
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>
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';
.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: 13px 0 5px 0;
}
.flaggedWarning {
border-radius: 7px;
width: 100%;
text-align: center;
position: absolute;
z-index: 20;
background: #ffffff60;
font-family: "Poppins", sans-serif;
padding: 20px 15px 25px 15px;
.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-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;
}
}
:global {
.anticon {
font-size: 40px;
}
}
}
.showMode{
:global{
ul {
opacity: 1 !important;
transform: translate(0, 15px);
}
.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
}
}
.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;
.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;
}
.MoreMenu{
color: #2d2d2d !important;
.ant-scroll-number-only>p.ant-scroll-number-only-unit {
height: 20px;
width: 20px;
margin: 0;
line-height: 20px;
padding: 0 0 0 1px;
}
}
}
.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;
}
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;
}
}
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;
.post_include {
padding: 13px 0 5px 0;
transition: all 150ms linear;
&.blur {
filter: blur(10px);
}
}
.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;
font-size: 30px;
transition: opacity 150ms linear;
}
video {
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.ellipsisIcon:hover{
opacity: 0;
transition: opacity 150ms linear;
.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 ycore from 'ycore'
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 $ from 'jquery'
import * as MICONS from '@material-ui/icons'
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) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
const reader = new FileReader()
reader.addEventListener('load', () => callback(reader.result))
reader.readAsDataURL(img)
}
export function HandleVisibility(){
window.PostCreatorComponent.ToogleVisibility();
return
export function HandleVisibility() {
window.PostCreatorComponent.ToogleVisibility()
return
}
class PostCreator extends React.PureComponent{
constructor(props){
super(props),
window.PostCreatorComponent = this;
this.state = {
visible: true,
FadeIN: true,
keys_remaining: ycore.AppSettings.MaxLengthPosts,
rawtext: '',
posting: false,
posting_ok: false,
shareWith: 'any',
uploader: false,
Schedule: false,
}
class PostCreator extends React.PureComponent {
constructor(props) {
super(props), (window.PostCreatorComponent = this)
this.state = {
visible: true,
FadeIN: true,
keys_remaining: ycore.AppSettings.MaxLengthPosts,
rawtext: '',
posting: false,
posting_ok: false,
shareWith: 'any',
uploader: 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) => {
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')
}
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} />
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>
)
}
return null
<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 => {
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';
.cardWrapper{
// box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px;
max-width: 510px;
min-width: 265px;
width: auto;
margin: 7px auto 50px auto;
:global{
textarea{
font-weight: 500;
resize: none;
}
textarea:focus {
outline: none !important;
border: 0 !important;
}
textarea:hover {
outline: none !important;
border: 0 !important;
}
.cardWrapper {
// box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
border-radius: 7px;
max-width: 510px;
min-width: 265px;
width: auto;
margin: 7px auto 50px auto;
.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;
}
}
:global {
textarea {
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;
}
}
}
}
.titleAvatar{
width: 45px;
height: 45px;
display: flex;
:global{
img{
width: 45px;
height: 45px;
border-radius: 12px;
}
.titleAvatar {
width: 45px;
height: 45px;
display: flex;
:global {
img {
width: 45px;
height: 45px;
border-radius: 12px;
}
}
}
.inputWrapper{
display: flex;
z-index: 10;
position: relative;
width: 100%;
padding: 18px 7px 0 7px;
transition: height 150ms linear;
:global{
.ant-btn-primary {
z-index: 10;
position: relative;
border-radius: 0 10px 10px 0;
height: 100%;
vertical-align: bottom;
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%;
.inputWrapper {
display: flex;
z-index: 10;
position: relative;
width: 100%;
padding: 18px 7px 0 7px;
transition: height 150ms linear;
}
.ant-input:hover{
border-color: #1890ff;
}
.ant-input-affix-wrapper{
height: 100%;
}
:global {
.ant-btn-primary {
z-index: 10;
position: relative;
border-radius: 0 10px 10px 0;
height: 100%;
vertical-align: bottom;
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%;
}
}
}
.progressHandler{
z-index: 10;
position: relative;
margin: 0 7px 0 7px;
:global{
.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;
}
.progressHandler {
z-index: 10;
position: relative;
margin: 0 7px 0 7px;
:global {
.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;
}
}
}
.postExtra{
width: 100%;
height: 100%;
position: relative;
margin: 0 0 40px 0;
.shareWith{
color: rgb(53, 53, 53);
float: right;
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;
}
.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;
}
.postExtra {
width: 100%;
height: 100%;
position: relative;
margin: 0 0 40px 0;
.shareWith {
color: rgb(53, 53, 53);
float: right;
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;
}
.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;
}
}
}
.uploader {
display: flex;
position: relative;
border-radius: 10px;
z-index: 30;
display: flex;
position: relative;
border-radius: 10px;
z-index: 30;
width: 100%;
height: 100%;
span {
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 {
background: #fafafa;
border: 1px dashed #d9d9d9;
border-radius: 12px;
transition: border-color 0.3s;
}
.anticon svg {
display: inline-block;
font-size: 30px;
}
.anticon svg {
display: inline-block;
font-size: 30px;
}
}
}
.imagePreviewWrapper{
position: relative;
width: 100%;
height: 100%;
// top: -100px;
margin: 0 0 15px 0;
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;
.imagePreviewWrapper {
position: relative;
width: 100%;
height: 100%;
// top: -100px;
margin: 0 0 15px 0;
background-color: #eeeeee;
}
.imageOverlay{
z-index: 10;
position: relative;
opacity: 0;
transition: all 150ms linear;
margin: auto;
}
}
.imagePreviewWrapper:hover .imagePreview{
opacity: 0.5;
transition: all 150ms linear;
}
.imagePreviewWrapper:hover .imageOverlay{
opacity: 1;
.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;
}
.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;
transition: opacity 250ms linear;
animation: proccessUnset 250ms linear;
transition: all 150ms linear;
margin: auto;
}
}
.proccessSet{
transition: opacity 250ms linear;
animation: proccessSet 250ms linear;
.imagePreviewWrapper:hover .imagePreview {
opacity: 0.5;
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 {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes proccessUnset {
0% { opacity: 1; }
100% { opacity: 0; }
}
0% {
opacity: 0;
}
.fontct{
font-family: "Poppins", sans-serif;
}
100% {
opacity: 1;
}
}
@keyframes proccessUnset {
0% {
opacity: 1;
}
100% {
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 { Post_Options } from 'globals/post_options.js'
import styles from './post_options.less'
import moment from 'moment';
const dateFormat = 'YYYY-MM-DD';
const { MonthPicker, RangePicker } = antd.DatePicker;
export function toogleOptionsBox(){
window.postoptions_box_class.setState({
options_box: !window.postoptions_box_class.state.options_box
})
export const optionBox = {
toogle: () => {
window.postoptions_box_class.handleToggleToolbox()
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{
constructor(props){
super(props),
window.postoptions_box_class = this;
this.state = {
options_repo: Post_Options,
options_box: false,
Schedule: false,
handleToggleToolbox = () => {
this.setState({ options_box: !this.state.options_box })
}
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.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 = () =>{
this.setState({ options_box: !this.state.options_box })
}
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 = () => {
rendersets = item => {
let e = item.type
switch (e) {
case 'switch':
return (
<antd.List
itemLayout="horizontal"
split="true"
dataSource={this.state.options_repo}
renderItem={item => (
<antd.List.Item actions={item.actions} key={item.SettingID} >
<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>
)}
<antd.Switch
disabled={this.require(item.require)}
checkedChildren={'Enabled'}
unCheckedChildren={'Disabled'}
checked={item.value}
onChange={() => this.onChangeSwitch(item)}
/>
)
default:
break
}
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 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>
}
renderSettings = () => {
return (
<antd.List
itemLayout="horizontal"
split="true"
dataSource={this.state.options_repo}
renderItem={item => (
<antd.List.Item actions={item.actions} key={item.key}>
<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>
)}
/>
)
}
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 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';
.optionsWrapper{
font-family: "Poppins", sans-serif;
:global{
.ant-drawer-body {
-ms-flex-positive: 1;
flex-grow: 1;
padding: 12px;
overflow: auto;
font-size: 14px;
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;
}
.optionsWrapper {
font-family: "Poppins", sans-serif;
:global {
.ant-drawer-body {
-ms-flex-positive: 1;
flex-grow: 1;
padding: 12px;
overflow: auto;
font-size: 14px;
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;
}
}
}
.PostOptionsWrapper{
margin: 0 10px 0 10px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 20px;
grid-row-gap: 20px;
justify-items: stretch;
align-items: stretch;
.optionItem{
display: inline;
}
.PostOptionsWrapper {
margin: 0 10px 0 10px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 20px;
grid-row-gap: 20px;
justify-items: stretch;
align-items: stretch;
.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';
: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;
}
.ps__rail-x:hover > .ps__thumb-x,
.ps__rail-x:focus > .ps__thumb-x {
.ps__rail-x:hover>.ps__thumb-x,
.ps__rail-x:focus>.ps__thumb-x {
height: 8px;
}
.ps__rail-y:hover > .ps__thumb-y,
.ps__rail-y:focus > .ps__thumb-y {
.ps__rail-y:hover>.ps__thumb-y,
.ps__rail-y:focus>.ps__thumb-y {
width: 8px;
}

View File

@ -2,63 +2,87 @@ import React from 'react'
import * as antd from 'antd'
import * as ycore from 'ycore'
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 { 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{
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} | `
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 )
}
const DataStrip = {
title: e => {
if (this.props.type == 'Users') {
return `@${username}`
}
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>
)
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 (
<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

View File

@ -1,143 +1,169 @@
@import '~themes/vars.less';
.cardWrapper{
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
display: flex;
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: 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;
}
}
.cardWrapper {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
display: flex;
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: 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{
position: absolute;
left: -8px;
top: -8px;
display: flex;
.postAvatar {
position: absolute;
left: -8px;
top: -8px;
display: flex;
}
.titleUser{
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
.titleUser {
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
}
.textAgo{
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
.textAgo {
display: flex;
font-size: 10px;
margin: 0 0 0 53px;
}
.PostTags{
.PostTags {
float: right;
color: rgb(249, 179, 64);
width: 100%;
z-index: 10;
i {
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;
}
}
margin: -0 6px 0 0;
;
font-size: 17px;
}
}
.ellipsisIcon{
color:rgba(0, 0, 0, 0.45);
width: 100%;
position: absolute;
text-align: center;
.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;
font-size: 30px;
transition: opacity 150ms linear;
}
video {
max-height: 600px;
width: calc(100% + 30px);
overflow: hidden;
}
h3 {
color: rgb(85, 85, 85);
font-weight: 470;
}
}
.ellipsisIcon:hover{
opacity: 0;
transition: opacity 150ms linear;
.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'
export default class UserBadges extends React.Component {
render(){
const { values } = this.props;
console.log(BadgesType)
return(
<div className={styles.TagWrappers}>
{ycore.booleanFix(values.nsfw_flag)? <antd.Tag color="volcano" >NSFW</antd.Tag> : 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>
)
}
render() {
const { values } = this.props
console.log(BadgesType)
return (
<div className={styles.TagWrappers}>
{ycore.booleanFix(values.nsfw_flag) ? (
<antd.Tag color="volcano">NSFW</antd.Tag>
) : 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>
)
}
}

View File

@ -2,10 +2,16 @@ import React from 'react'
import styles from './Follow_btn.scss'
import classnames from 'classnames'
export default class Follow_btn extends React.Component{
render(){
return(
<a className={classnames(styles.like_btn, {[styles.nofollowed]: !this.props.followed})} ><span>{this.props.followed? 'Following' : 'Follow'}</span></a>
)
}
export default class Follow_btn extends React.Component {
render() {
return (
<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;
$border: 0;
@ -7,36 +7,36 @@ $orange: #ff7159;
$border-radius: 8px;
$deg: 120deg;
$deg: 120deg;
$size: 400%;
$dur: 15s;
$dur: 15s;
@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%);
}
.like_btn {
width: 100px;
height: 30px;
line-height: 28px;
padding: 5px 15px 5px 15px;
@extend .text-formatting;
width: 100px;
height: 30px;
line-height: 28px;
padding: 5px 15px 5px 15px;
@extend .text-formatting;
&:hover {
color: #7e7e7e;
}
&.nofollowed {
&:hover {
color: #7e7e7e;
}
&.nofollowed{
&:hover {
border: none;
content: '';
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;
}
border: none;
content: '';
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 */
@ -51,7 +51,15 @@ $dur: 15s;
/* motion */
@keyframes gradient {
0% { background-position: 14% 0%; }
50% { background-position: 87% 100%; }
100% { background-position: 14% 0%; }
0% {
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 * as ycore from 'ycore'
import * as antd from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import {CustomIcons, MainFeed, PostCreator} from 'components'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { CustomIcons, MainFeed, PostCreator } from 'components'
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 Follow_btn from './components/Follow_btn.js'
class UserProfile extends React.Component {
constructor(props){
super(props),
this.state = {
constructor(props) {
super(props),
(this.state = {
invalid: false,
UUID: '',
RenderValue: {},
loading: true,
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 = () => {
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)
}
componentDidMount() {
const { regx } = this.props
this.initUser(regx)
SetHeaderSearchType.disable()
}
componentDidMount(){
const { regx } = this.props
this.initUser(regx)
SetHeaderSearchType.disable()
}
initUser = e => {
const parsed = e.shift()
const raw = parsed.toString()
const string = raw.replace('/@', '')
initUser = (e) => {
const parsed = e.shift()
const raw = parsed.toString()
const string = raw.replace('/@', "")
const payload = { key: string }
ycore.comty_user.find((err, res) => {
err ? ycore.notify.error(err) : null
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 }
ycore.comty_user.find((err,res)=>{
err? ycore.notifyError(err) : null
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 = { id: rp['0'].user_id }
ycore.comty_user.__tags((err, res) => {
if (err) {
ycore.notify.error(err)
return
}
}, payload)
const payload = { id: rp['0'].user_id }
ycore.comty_user.__tags((err,res)=>{
if (err) {
ycore.notifyError(err)
return
}
},payload)
this.setState({
UUID: rp['0'].user_id,
RenderValue: rp['0'],
loading: false,
Followed: ycore.booleanFix(rp['0'].is_following),
})
} catch (err) {
ycore.notify.error(err)
}
}, payload)
}
this.setState({ UUID: rp['0'].user_id, RenderValue: rp['0'], loading: false , Followed: ycore.booleanFix(rp['0'].is_following)})
} catch (err) {
ycore.notifyError(err)
}
},payload)
UserHeader = values => {
return (
<div className={styles.userWrapper}>
<div className={styles.UserCover}>
<img src={values.cover} />
</div>
}
UserHeader = (values) => {
return (
<div className={styles.userWrapper}>
<div className={styles.UserCover}>
<img src={values.cover} />
</div>
<PageHeaderWrapper content={
<PageHeaderWrapper
content={
<div className={styles.pageHeaderContent}>
<div className={styles.avatar}>
<antd.Avatar shape="square" src={values.avatar} />
<antd.Avatar shape="square" src={values.avatar} />
</div>
<div className={styles.content}>
<div className={styles.TagWrappers}>
{ycore.booleanFix(values.nsfw_flag)? <antd.Tag color="volcano" >NSFW</antd.Tag> : 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}
{ycore.booleanFix(values.nsfw_flag) ? (
<antd.Tag color="volcano">NSFW</antd.Tag>
) : 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>
{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}>
<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>
<span style={{ fontSize: '14px', fontWeight: '100', lineHeight: '0', marginBottom: '5px' }} dangerouslySetInnerHTML={{__html: values.about }} />
<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>
<span
style={{
fontSize: '14px',
fontWeight: '100',
lineHeight: '0',
marginBottom: '5px',
}}
dangerouslySetInnerHTML={{ __html: values.about }}
/>
</div>
</div>
</div>
} />
</div>
);
};
render(){
const { loading, UUID, invalid } = this.state
return(
<div>
{loading? <antd.Skeleton active /> :
(<div>
{invalid? null: this.UserHeader(this.state.RenderValue)}
{ycore.IsThisUser.same(UUID)? <PostCreator userData={ycore.userData()} /> : null}
<MainFeed get='user' uid={UUID} />
</div>)
}
</div>
)
}
}
/>
</div>
)
}
render() {
const { loading, UUID, invalid } = this.state
return (
<div>
{loading ? (
<antd.Skeleton active />
) : (
<div>
{invalid ? null : this.UserHeader(this.state.RenderValue)}
{ycore.IsThisUser.same(UUID) ? (
<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() {
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
@ -24,24 +26,27 @@
}
}
.userWrapper{
.userWrapper {
padding: 0 68px 15px 68px;
margin: auto;
:global{
:global {
.ant-page-header-content {
padding-top: 0;
overflow: initial !important;
}
.ant-page-header {
padding: 20px 0 3px 0;
}
.ant-pro-page-header-wrap-page-header-warp {
border-radius: 0 0 20px 20px;
}
}
}
.TagWrappers{
.TagWrappers {
width: 100%;
float: right;
position: relative;
@ -55,14 +60,14 @@
max-height: 400px;
overflow: hidden;
img{
img {
width: calc(100% + 30px);
overflow: hidden;
margin: auto;
}
}
.follow_wrapper{
.follow_wrapper {
margin: 0 7px 0 7px;
position: relative;
float: right;
@ -70,17 +75,20 @@
.avatar {
transform: translate(-25px, -45px);
& > span {
&>span {
position: relative;
z-index: 10;
width: 100%;
height: 100%;
}
:global{
:global {
.ant-avatar {
box-shadow: 13px 13px 17px 4px rgba(69, 69, 69, 0.151);
border-radius: 7px;
img{
img {
width: 120px;
}
}
@ -90,10 +98,12 @@
.pageHeaderContent {
vertical-align: top;
display: flex;
.content {
font-family: "Poppins", sans-serif;
color: @text-color-secondary;
width: 100%;
.contentTitle {
padding: 0 10px 10px 0;
color: @heading-color;
@ -109,6 +119,7 @@
.extraContent {
margin-left: -16px;
}
.projectList {
.projectGrid {
width: 50%;
@ -120,10 +131,12 @@
.pageHeaderContent {
display: block;
margin: 10px;
.content {
margin-left: 0;
}
}
.extraContent {
.statItem {
float: none;
@ -138,4 +151,3 @@
}
}
}

View File

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

View File

@ -1,20 +1,17 @@
import React, { Component } from 'react'
import { connect } from 'dva';
import { Form, Icon as LegacyIcon } from '@ant-design/compatible';
import { connect } from 'dva'
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 styles from './index.less';
import { ANT_MARK } from 'antd/lib/locale-provider';
import { validateLocaleAndSetLanguage } from 'typescript';
import styles from './index.less'
const FormItem = Form.Item
@connect(({ loading }) => ({ loading }))
@Form.create()
class YulioID extends Component {
constructor(props) {
super(props)
this.state = {
@ -26,61 +23,78 @@ class YulioID extends Component {
}
// Handlers & others
handleUsername(text) {
this.setState({ RawUsername: text.target.value });
this.setState({ RawUsername: text.target.value })
}
handlePassword(text) {
this.setState({ RawPassword: text.target.value });
this.setState({ RawPassword: text.target.value })
}
handleRetry = () => {
this.setState({ShowLoading: false, StateException: false, StateIcon: ''})
this.setState({ ShowLoading: false, StateException: false, StateIcon: '' })
}
handleEnter = (e) => {
this.handleLogin();
handleEnter = e => {
this.handleLogin()
}
handleLogin = () => {
var prefix = '[YID]: ';
const { RawUsername, RawPassword } = this.state;
var EncPassword = btoa(RawPassword);
var EncUsername = btoa(RawUsername);
var prefix = '[YID]: '
const { RawUsername, RawPassword } = this.state
var EncPassword = btoa(RawPassword)
var EncUsername = btoa(RawUsername)
if (!EncUsername || !EncPassword) {
var message = 'Incomplete information!'
ycore.yconsole.log(prefix, message)
}
if (EncUsername && EncPassword){
this.setState({ ShowLoading: true, StateMessage: 'Wait a sec...' });
if (EncUsername && EncPassword) {
this.setState({ ShowLoading: true, StateMessage: 'Wait a sec...' })
if (ycore.AppSettings.InfiniteLogin == true) {
ycore.yconsole.log(prefix, 'InfiniteLogin is enabled! Disabled getAuth')
}
else {
} else {
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') {
this.setState({ StateIcon: 'login', StateMessage: 'Wait a sec...', StateException: false })
this.setState({
StateIcon: 'login',
StateMessage: 'Wait a sec...',
StateException: false,
})
}
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') {
this.setState({ StateIcon: 'exclamation-circle', StateMessage: 'Invalid Data', StateException: true })
this.setState({
StateIcon: 'exclamation-circle',
StateMessage: 'Invalid Data',
StateException: true,
})
}
if (response == '500') {
this.setState({ StateIcon: 'cluster', StateMessage: 'Server Error', StateException: true })
this.setState({
StateIcon: 'cluster',
StateMessage: 'Server Error',
StateException: true,
})
}
}
render() {
const { visible } = this.props
const { getFieldDecorator } = this.props.form;
const { ShowLoading, StateIcon, StateMessage, StateException } = this.state;
const { getFieldDecorator } = this.props.form
const { ShowLoading, StateIcon, StateMessage, StateException } = this.state
return (
<div className={styles.loginWrapper}>
@ -92,93 +106,134 @@ class YulioID extends Component {
visible={visible}
className={styles.loginWrapper}
>
<div className={styles.preheader}><h6><img src={"https://api.ragestudio.net/id.svg"} /> YulioID&trade;</h6>
<h1>Login</h1></div>
<div className={styles.preheader}>
<h6>
<img src={'https://api.ragestudio.net/id.svg'} /> YulioID&trade;
</h6>
<h1>Login</h1>
</div>
<main className={styles.mainlp}>
<form className={styles.formlogin}>
{ShowLoading ? (
<div style={{ height: '329px' }}>
<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 />)}
<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>
<form className={styles.formlogin}>
{ShowLoading ? (
<div style={{ height: '329px' }}>
<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
/>
)}
<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 className={styles.input__wrapper}>
<label className={styles.labelform}>
<LegacyIcon type="user" style={{ fontSize: '15px' }} />{' '}
Username
</label>
<FormItem>
{getFieldDecorator('Username', {
rules: [{ required: true }],
})(
<Input
onPressEnter={this.handleEnter}
className={styles.inputform}
type="text"
placeholder="Username"
onChange={text => {
this.handleUsername(text)
}}
/>
)}
</FormItem>
</div>
<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}>
<label className={styles.labelform}>
<LegacyIcon type="user" style={{ fontSize: '15px' }} />{' '}
Username
</label>
<FormItem>
{getFieldDecorator('Username', {
rules: [{ required: true }],
})(
<Input
onPressEnter={this.handleEnter}
className={styles.inputform}
type="text"
placeholder="Username"
onChange={text => {
this.handleUsername(text)
}}
/>
)}
</FormItem>
</div>
)}
</form>
<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>
)}
</form>
</main>
</Drawer>
</div>
);
)
}
}

View File

@ -1,433 +1,485 @@
@import '~themes/vars.less';
.loginWrapper{
:global{
.ant-drawer-right.ant-drawer-open.no-mask {
right: 1px;
-ms-transform: translateX(1px);
transform: translateX(1px);
width: 100%;
}
.ant-drawer-right.ant-drawer-open .ant-drawer-content-wrapper{
width: 100%;
border-radius: 20px 0 0 20px;
}
.ant-drawer-body{
height: 100%;
}
.ant-drawer {
box-shadow: none;
border-radius: 20px 0 0 20px;
max-width: 512px;
width: 100%;
}
.ant-drawer-content{
background: #ffffff9f;
border-radius: 20px 0 0 20px;
}
}
}
.loginWrapper {
:global {
.ant-drawer-right.ant-drawer-open.no-mask {
right: 1px;
-ms-transform: translateX(1px);
transform: translateX(1px);
width: 100%;
}
.ant-drawer-right.ant-drawer-open .ant-drawer-content-wrapper {
width: 100%;
border-radius: 20px 0 0 20px;
}
.ant-drawer-body {
height: 100%;
}
.ant-drawer {
box-shadow: none;
border-radius: 20px 0 0 20px;
max-width: 512px;
width: 100%;
}
.ant-drawer-content {
background: #ffffff9f;
border-radius: 20px 0 0 20px;
}
}
}
.StateIcon {
font-size: 24px;
margin: 13px;
font-size: 24px;
margin: 13px;
}
.StateIcon_exception {
font-size: 24px;
margin: 13px;
color: red !important;
font-size: 24px;
margin: 13px;
color: red !important;
:global{
i {
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 {
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;
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>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%;
color: @grayColor;
margin-top: 20px;
margin-bottom: 20px;
width: 100%;
}
@media (max-width: 992px) {
section:not(:last-child) {
border-width: 0 0 1px;
}
section:not(:last-child) {
border-width: 0 0 1px;
}
section:last-child {
border-width: 0;
}
section:last-child {
border-width: 0;
}
}
.buttons {
display: flex;
flex-wrap: wrap;
align-items: center;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.buttons > * {
flex: 1 1 calc(50% - 20px);
margin-top: 20px;
.buttons>* {
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,
input.buttonlp,
.buttonlp {
outline: none;
width: 100%;
text-align: center;
display: inline-block;
border: none;
font: 500 16px/1 "Poppins", sans-serif;
padding: 20px;
cursor: pointer;
border-radius: @borderRadius;
background: @primaryColor;
color: @backgroundColor;
position: relative;
top: 0;
transition: 0.2s ease;
outline: none;
width: 100%;
text-align: center;
display: inline-block;
border: none;
font: 500 16px/1 "Poppins", sans-serif;
padding: 20px;
cursor: pointer;
border-radius: @borderRadius;
background: @primaryColor;
color: @backgroundColor;
position: relative;
top: 0;
transition: 0.2s ease;
}
a.buttonlp:hover, a.buttonlp.hover,
a.buttonlp:hover,
a.buttonlp.hover,
input.buttonlp:hover,
input.buttonlp.hover,
.buttonlp:hover,
.buttonlp.hover {
top: -3px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
top: -3px;
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,
.buttonlp:active,
.buttonlp.active {
background: @primaryShade4;
outline: none;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
top: 0;
.buttonlp.active {
background: @primaryShade4;
outline: none;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
top: 0;
}
a.buttonlp.disabled,
input.buttonlp.disabled,
.buttonlp.disabled {
opacity: 0.4;
user-select: none;
pointer-events: none;
opacity: 0.4;
user-select: none;
pointer-events: none;
}
a.buttonlp.medium,
input.buttonlp.medium,
.buttonlp.medium {
padding: 15px 18px;
width: auto;
padding: 15px 18px;
width: auto;
}
a.buttonlp.small,
input.buttonlp.small,
.buttonlp.small {
padding: 10px 12px;
width: auto;
font-size: 14px;
font-weight: 500;
padding: 10px 12px;
width: auto;
font-size: 14px;
font-weight: 500;
}
a.buttonlp.secondary,
input.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:focus,
input.buttonlp.secondary.active,
.buttonlp.secondary:active,
.buttonlp.secondary:focus,
.buttonlp.secondary.active {
background: @secondaryShade4;
outline: none;
background: @secondaryShade4;
outline: none;
}
a.buttonlp.accent,
input.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:focus,
input.buttonlp.accent.active,
.buttonlp.accent:active,
.buttonlp.accent:focus,
.buttonlp.accent.active {
background: @accentShade4;
background: @accentShade4;
}
a.buttonlp.accent2,
input.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:focus,
input.buttonlp.accent2.active,
.buttonlp.accent2:active,
.buttonlp.accent2:focus,
.buttonlp.accent2.active {
background: @accent2Shade4;
background: @accent2Shade4;
}
a.buttonlp.accent3,
input.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:focus,
input.buttonlp.accent3.active,
.buttonlp.accent3:active,
.buttonlp.accent3:focus,
.buttonlp.accent3.active {
background: @accent3Shade4;
background: @accent3Shade4;
}
/*inputs*/
.input__wrapper {
margin-bottom: 10px;
:global{
.ant-col {
width: 100%;
}
}
margin-bottom: 10px;
:global {
.ant-col {
width: 100%;
}
}
}
.inputRG__wrapper {
margin-bottom: 0px;
margin-bottom: 0px;
}
.labelform {
font-weight: 500;
display: block;
margin-bottom: 5px;
font-weight: 500;
display: block;
margin-bottom: 5px;
}
.inputform,
select,
textarea {
height: 50px;
font-size: 16px;
border: 2px solid @neutralShade3;
width: 100%;
padding: 12px;
font-family: "Poppins";
border-radius: @borderRadius;
color: @foregroundColor;
background: @backgroundColor;
height: 50px;
font-size: 16px;
border: 2px solid @neutralShade3;
width: 100%;
padding: 12px;
font-family: "Poppins";
border-radius: @borderRadius;
color: @foregroundColor;
background: @backgroundColor;
}
.inputform:focus, .inputform.active,
.inputform:focus,
.inputform.active,
select:focus,
select.active,
textarea:focus,
textarea.active {
outline: none;
border-color: @primaryColor;
outline: none;
border-color: @primaryColor;
}
.inputform:disabled,
select:disabled,
textarea:disabled {
cursor: not-allowed;
background: @neutralShade1;
opacity: 0.6;
cursor: not-allowed;
background: @neutralShade1;
opacity: 0.6;
}
Input .inputPasswordform {
height: 50px;
font-size: 16px;
border: 2px solid @neutralShade3;
width: 100%;
padding: 12px;
font-family: "Poppins";
border-radius: @borderRadius;
color: @foregroundColor;
background: @backgroundColor;
height: 50px;
font-size: 16px;
border: 2px solid @neutralShade3;
width: 100%;
padding: 12px;
font-family: "Poppins";
border-radius: @borderRadius;
color: @foregroundColor;
background: @backgroundColor;
}
Input .inputPasswordform:focus {
outline: none;
border-color: @primaryColor;
outline: none;
border-color: @primaryColor;
}
.inputform.input {
height: 56px;
font-size: 18px;
padding: 15px;
height: 56px;
font-size: 18px;
padding: 15px;
}
/*spinner*/
.spinner + .labellp {
font-size: 14px;
font-weight: 500;
margin-top: 8px;
display: inline-block;
text-transform: uppercase;
color: @primaryShade4;
.spinner+.labellp {
font-size: 14px;
font-weight: 500;
margin-top: 8px;
display: inline-block;
text-transform: uppercase;
color: @primaryShade4;
}
.spinner1 .spinner {
max-width: 50px;
margin: auto;
height: 20px;
position: relative;
max-width: 50px;
margin: auto;
height: 20px;
position: relative;
}
.spinner1 .spinner:after {
content: "";
position: absolute;
width: 20px;
height: 20px;
left: -10%;
background: @primaryColor;
animation: spinnerLeftRight 1s infinite;
content: "";
position: absolute;
width: 20px;
height: 20px;
left: -10%;
background: @primaryColor;
animation: spinnerLeftRight 1s infinite;
}
.spinner1 .spinner:before {
content: "";
position: absolute;
width: 20px;
height: 20px;
left: -10%;
background: @primaryShade2;
opacity: 1;
animation: spinnerLeftRight 1s infinite 0.06s;
content: "";
position: absolute;
width: 20px;
height: 20px;
left: -10%;
background: @primaryShade2;
opacity: 1;
animation: spinnerLeftRight 1s infinite 0.06s;
}
@keyframes spinnerLeftRight {
0% {
left: 85%;
}
50% {
left: -10%;
}
100% {
left: 85%;
}
0% {
left: 85%;
}
50% {
left: -10%;
}
100% {
left: 85%;
}
}
.formlogin {
width: 95%;
height: auto;
border-radius: 10px;
padding: 30px;
box-shadow: 0 3px 15px rgba(51, 51, 51, 0.2);
background: #ffffff44;
margin: 20px 10px 20px 10px;
position: relative;
overflow: hidden;
vertical-align: middle;
width: 95%;
height: auto;
border-radius: 10px;
padding: 30px;
box-shadow: 0 3px 15px rgba(51, 51, 51, 0.2);
background: #ffffff44;
margin: 20px 10px 20px 10px;
position: relative;
overflow: hidden;
vertical-align: middle;
}
.formlogin .checkbox {
margin-bottom: 30px;
margin-bottom: 30px;
}
.formlogin .spinner__wrapper {
place-items: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(255, 255, 255, 0.85);
place-items: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
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;
}
}
}
.preheader {
position: relative;
top: 0;
.moreActions{
display: flex;
margin: auto;
align-content: center;
position: relative;
width: 100%;
:global{
.ant-btn{
margin: auto;
}
}
}
h1 {
font: 700 48px "Nunito", sans-serif;
text-align: center;
margin-bottom: 10px;
}
@media (max-width: 472px) {
.moreActions{
display: grid;
align-content: center;
position: relative;
width: 100%;
:global{
.ant-btn{
margin: 5px;
}
}
}
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;
}
}
}
.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;
}
.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 Loader from './Loader/Loader.js'
import ScrollBar from './ScrollBar'
import Page from './Page'
// App Layout Components
import * as MyLayout from './Layout/index.js'
import MicroHeader from './MicroHeader'
import HeaderSearch from './HeaderSearch'
import PageTransition from './PageTransition'
import YulioID from './YulioID'
@ -22,29 +20,26 @@ import SearchCard from './SearchCard'
// Post Components
import MediaPlayer from './MediaPlayer'
import PostCard from './PostCard'
import LikeBTN from './LikeBtn'
import Like_button from './Like_button'
import MainFeed from './MainFeed'
import PostCreator from './PostCreator'
// Mix & Export all
export
{
MediaPlayer,
UserBadges,
MobileWarning,
PageTransition,
SearchCard,
HeaderSearch,
YulioID,
UserProfile,
MyLayout,
Loader,
Page,
ScrollBar,
PostCard,
PostCreator,
CustomIcons,
LikeBTN,
MainFeed,
MicroHeader
export {
MediaPlayer,
UserBadges,
MobileWarning,
PageTransition,
SearchCard,
HeaderSearch,
YulioID,
UserProfile,
MyLayout,
Loader,
ScrollBar,
PostCard,
PostCreator,
CustomIcons,
Like_button,
MainFeed,
}

View File

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

View File

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

View File

@ -4,9 +4,14 @@ import React from 'react'
import PropTypes from 'prop-types'
import withRouter from 'umi/withRouter'
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 store from 'store';
import store from 'store'
import classnames from 'classnames'
import * as ycore from 'ycore'
@ -21,21 +26,21 @@ const { Sider, Control, Secondary, WindowAppBar } = MyLayout
@withRouter
@connect(({ app, loading }) => ({ app, loading }))
class PrimaryLayout extends React.Component {
constructor(props){
constructor(props) {
super(props)
window.PrimaryComponent = this;
window.PrimaryComponent = this
this.state = {
collapsed: (ycore.AppSettings.default_collapse_sider? true : false),
collapsed: ycore.AppSettings.default_collapse_sider ? true : false,
isMobile: false,
desktop_mode: false,
userData: ''
userData: '',
}
}
componentDidMount() {
this.setState({
userData: ycore.userData(),
desktop_mode: ycore.CheckThisApp.desktop_mode()
desktop_mode: ycore.CheckThisApp.desktop_mode(),
})
this.enquireHandler = enquireScreen(mobile => {
@ -55,16 +60,16 @@ class PrimaryLayout extends React.Component {
onCollapseChange = () => {
const fromStore = store.get('collapsed')
this.setState({ collapsed: !this.state.collapsed })
store.set('collapsed', !fromStore)
store.set('collapsed', !fromStore)
}
isDarkMode = () => {
const {app} = this.props
const { app } = this.props
const { theme } = app
if (theme == "light") {
return false;
if (theme == 'light') {
return false
}
return true;
return true
}
render() {
@ -95,30 +100,47 @@ class PrimaryLayout extends React.Component {
theme,
}
return (
<React.Fragment >
<div className={classnames(styles.AppWrapper, {[styles.desktop_mode]: desktop_mode})}>
{isMobile? <MobileWarning /> : null}
<div className={styles.BarControlWrapper}><Control /></div>
<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>
return (
<React.Fragment>
<div
className={classnames(styles.AppWrapper, {
[styles.desktop_mode]: desktop_mode,
})}
>
{isMobile ? <MobileWarning /> : null}
<div className={styles.BarControlWrapper}>
<Control />
</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,9 +1,9 @@
@import '~themes/vars.less';
.AppWrapper{
&.desktop_mode{
padding: 0 30px 0 30px;
border-radius: 10px;
.AppWrapper {
&.desktop_mode {
padding: 0 30px 0 30px;
border-radius: 10px;
}
}
@ -13,86 +13,104 @@
float: right;
padding: 35px 25px 15px 60px;
transition: all 0.2s ease;
&.collapsed {
width: ~'calc(100% - 180px)';
transition: all 0.2s ease;
}
}
.layout{
.layout {
background-color: @Theme-Layout-Backgroud; //#E2E6E9;
transition: background-color 200ms linear;
&.desktop_mode{
&.desktop_mode {
border-radius: 12px;
}
&.md_radius{
&.md_radius {
width: 95%;
margin: auto;
position: relative;
border-radius: 15px;
}
&.md_dark{
&.md_dark {
background-color: @DarkMode-backgroud_container;
color: @DarkMode-color_container;
transition: background-color 200ms linear;
:global {
h1{
h1 {
color: @DarkMode-color_container;
}
h2{
h2 {
color: @DarkMode-color_container;
}
h3{
h3 {
color: @DarkMode-color_container;
}
h4{
h4 {
color: @DarkMode-color_container;
}
h5{
h5 {
color: @DarkMode-color_container;
}
h6{
h6 {
color: @DarkMode-color_container;
}
p{
p {
color: @DarkMode-color_container;
}
span{
span {
color: @DarkMode-color_container;
}
pre{
pre {
color: @DarkMode-color_container;
}
.ant-pro-page-header-wrap-page-header-warp {
color: @DarkMode-color_container;
background-color: @DarkMode-backgroud_container;
transition: background-color 200ms linear;
}
.ant-card{
.ant-card {
background-color: @DarkMode-backgroud;
}
.ant-input {
color: @DarkMode-color_container;
background-color: @DarkMode-backgroud;
}
.ant-btn-primary[disabled]{
.ant-btn-primary[disabled] {
color: @DarkMode-color_container;
background-color: @DarkMode-backgroud;
}
transition: background-color 200ms linear;
}
}
}
.BarControlWrapper{
.BarControlWrapper {
width: 100%;
position: absolute;
bottom: 0;
z-index: 30;
}
.leftContainer{
.leftContainer {
align-self: center;
width: 100vw;
position: relative;
@ -100,12 +118,13 @@
overflow-x: hidden;
height: 100vh;
bottom: 0;
:global{
#scroller{
overflow-y: scroll !important;
}
}
:global {
#scroller {
overflow-y: scroll !important;
}
}
}
@ -114,6 +133,7 @@
.content {
padding: 12px;
}
.layout {
height: 100vh;
flex: 1;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,16 @@
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 styles from './404.less'
const Error404 = () => (
<div className={styles.error}>
<div className={styles.error}>
<LegacyIcon type="api" />
<h1>OBA BLYAT</h1>
<p><strong>ERROR 404</strong></p>
</div>
<h1>OBA BLYAT</h1>
<p>
<strong>ERROR 404</strong>
</p>
</div>
)
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');
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 */
@font-face {
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');
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 */
@font-face {
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');
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 {
background-color: transparent;
color: black;
@ -45,7 +48,8 @@
font-family: 'Poppins', sans-serif;
}
p {
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 antd from 'antd'
import * as Icons from '@ant-design/icons';
import * as Icons from '@ant-design/icons'
import jwt from 'jsonwebtoken'
import styles from './style.less'
import MainFeed from '../../components/MainFeed';
import MainFeed from '../../components/MainFeed'
const UserData = ycore.userData()
export default class __m extends React.Component {
constructor(props){
constructor(props) {
super(props),
this.state = {
s_id: '',
coninfo: 'Getting info...',
s_token: '',
s_ses: ''
};
(this.state = {
s_id: '',
coninfo: 'Getting info...',
s_token: '',
s_ses: '',
})
}
componentDidMount() {
@ -30,133 +28,199 @@ export default class __m extends React.Component {
this.handleToken()
}
handleSID(){
ycore.get_app_session.get_id((err, response)=> {
if (err){
return ycore.notifyError(err)
handleSID() {
ycore.get_app_session.get_id((err, response) => {
if (err) {
return ycore.notify.error(err)
}
this.setState({ s_id: response})
this.setState({ s_id: response })
})
}
handleToken(){
const a = ycore.handlerYIDT.getRaw()
handleToken() {
const a = ycore.token_data.getRaw()
const b = jwt.decode(a)
this.setState({ s_token: b})
{ycore.ValidLoginSession(res => {
this.setState({s_ses: res})
})}
this.setState({ s_token: b })
{
ycore.validate.session(res => {
this.setState({ s_ses: res })
})
}
}
handleDesktop(){
handleDesktop() {
const a = localStorage.getItem('desktop_src')
let to;
let to
if (a == 'false') {
to = true
}else {
} else {
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)
setTimeout(() => ycore.RefreshONCE(), 2000)
}
DescompileSDCP(){
let result = {};
DescompileSDCP() {
let result = {}
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])
}
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 { 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 (
<div className={styles.Wrapper}>
<div className={styles.titleHeader}>
<h1><Icons.DeploymentUnitOutlined /> yCore Server</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<h2><Icons.CloudServerOutlined /> Server UID</h2>
<span> {ycore.yConfig.server_key} </span>
</antd.Card>
<antd.Card>
<h2><Icons.UserOutlined /> Your SID</h2>
<span> {this.state.s_id} </span>
</antd.Card>
<antd.Card>
<h2><Icons.UserOutlined /> Current Session</h2>
<p> Raw => {JSON.stringify(this.state.s_token)} </p>
<p> UID => {UserID} </p>
<p> Session Token => {UserToken} </p>
<p> expiresIn => {expiresIn} </p>
<hr />
<p> ValidSDCP => {JSON.stringify(ValidSDCP)} </p>
<p> ValidCookiesToken => {JSON.stringify(ValidCookiesToken)} </p>
<p> Valid? => {JSON.stringify(final)} </p>
<div className={styles.titleHeader}>
<h1>
<Icons.DeploymentUnitOutlined /> yCore Server
</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<h2>
<Icons.CloudServerOutlined /> Server UID
</h2>
<span> {ycore.yConfig.server_key} </span>
</antd.Card>
<antd.Card>
<h2>
<Icons.UserOutlined /> Your SID
</h2>
<span> {this.state.s_id} </span>
</antd.Card>
<antd.Card>
<h2>
<Icons.UserOutlined /> Current Session
</h2>
<p> Raw => {JSON.stringify(this.state.s_token)} </p>
<p> UID => {UserID} </p>
<p> Session Token => {UserToken} </p>
<p> expiresIn => {expiresIn} </p>
<hr />
<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>
</antd.Card>
<antd.Card>
<span> Using v{ycore.AppInfo.version} | User @{UserData.username}#{UserData.id} | </span>
</antd.Card>
</div>
<div className={styles.titleHeader}>
<h1><Icons.DeploymentUnitOutlined /> Test yCore </h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Button onClick={() => ycore.notifyError('Yep, its not empty, jeje funny')} > Send empty notifyError() </antd.Button>
<antd.Button onClick={() => ycore.notifyError(`
<div className={styles.titleHeader}>
<h1>
<Icons.DeploymentUnitOutlined /> Test yCore{' '}
</h1>
</div>
<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) => {
const parsed = JSON.parse(result)['data']
const isEnd = parsed.length < ycore.AppSettings.limit_post_catch? true : 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.proccess('Proccess Mock 1')} > notify.proccess </antd.Button>
<antd.Button onClick={() => this.handleDesktop()} > Switch to Desktop_mode </antd.Button>
</div>
<antd.Button onClick={() => ycore.notify.error('Error Mock 1')}>
{' '}
notify.error{' '}
</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}>
<h1><Icons.DatabaseOutlined /> SDCP</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<h2><Icons.CloudServerOutlined /> UserData</h2>
<antd.Collapse>
<antd.Collapse.Panel header="WARNING: High Heap when descompile data! " key="1">
{ JSON.stringify(arrayOfSDCP) }
</antd.Collapse.Panel>
</antd.Collapse>
</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.DatabaseOutlined /> SDCP
</h1>
</div>
<div className={styles.sectionWrapper}>
<antd.Card>
<h2>
<Icons.CloudServerOutlined /> UserData
</h2>
<antd.Collapse>
<antd.Collapse.Panel
header="WARNING: High Heap when descompile data! "
key="1"
>
{JSON.stringify(arrayOfSDCP)}
</antd.Collapse.Panel>
</antd.Collapse>
</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>
)
}

View File

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

View File

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

View File

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

View File

@ -4,92 +4,97 @@ import { SearchCard } from 'components'
import styles from './styles.less'
import * as ycore from 'ycore'
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'
class GroupIndexer extends PureComponent {
constructor(props){
super(props),
this.state = {
constructor(props) {
super(props),
(this.state = {
SearchResult: '',
loading: true
}
}
toogleLoading(){
this.setState({loading: !this.state.loading})
}
componentDidMount(){
try {
const {location} = this.props
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);
loading: true,
})
}
toogleLoading() {
this.setState({ loading: !this.state.loading })
}
componentDidMount() {
try {
const { location } = this.props
const matchSearch = pathMatchRegexp('/s/: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>)
const string = raw.replace('/s/', '')
} catch (err) {
ycore.notify.error(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 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

View File

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

View File

@ -1,34 +1,38 @@
import React, { Component } from 'react'
import * as antd from 'antd'
import * as ycore from 'ycore'
import {YulioID} from 'components'
import styles from './index.less';
import { YulioID } from 'components'
import styles from './index.less'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
showYulioID: true
showYulioID: true,
}
}
toogleYulioID(){
toogleYulioID() {
this.setState({ showYulioID: !this.state.showYulioID })
}
render() {
return (
<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.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 className={styles.version}><h2>{`v${ycore.AppInfo.version}`}</h2>{ycore.DetectNoNStableBuild('TagComponent')}</div>
<YulioID visible={this.state.showYulioID} />
</div>
)
}
}

View File

@ -2,99 +2,115 @@
/* Animation */
.parallax > use {
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);
}
.parallax>use {
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);
}
.backgroud{
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
top: 0;
left: 0;
100% {
transform: translate3d(85px, 0, 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;
}
}
.backgroud {
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
top: 0;
left: 0;
}
.loginLandingWrapper{
background-color: #F9F9F9;
width: 100%;
height: 100%;
font-family: "Nunito", sans-serif;
padding: 15px 30px 15px 35px;
}
.brand{
width: 100%;
top: 0;
float: left;
vertical-align: middle;
position: relative;
img{
max-width: 250px;
width: 11vw;
.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;
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;
}
}
}
.loginLandingWrapper {
background-color: #F9F9F9;
width: 100%;
height: 100%;
font-family: "Nunito", sans-serif;
padding: 15px 30px 15px 35px;
}
.brand {
width: 100%;
top: 0;
float: left;
vertical-align: middle;
position: relative;
img {
max-width: 250px;
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 * as ycore from 'ycore'
import {PostCreator, MainFeed} from 'components'
import { PostCreator, MainFeed } from 'components'
import styles from './index.less'
export default class Main extends React.Component {
render(){
return (
<div className={styles.mainWrapper}>
<PostCreator userData={ycore.userData()} />
<MainFeed get="feed" />
</div>
)
}
render() {
return (
<div className={styles.mainWrapper}>
<PostCreator userData={ycore.userData()} />
<MainFeed get="feed" />
</div>
)
}
}

View File

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

View File

@ -2,47 +2,46 @@ import React from 'react'
import { pathMatchRegexp } from 'utils'
import * as ycore from 'ycore'
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{
constructor(props){
super(props),
this.state = {
loading: true,
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)
toSwap(id) {
const payload = { post_id: id }
ycore.comty_post.get((err, res) => {
if (err) {
return false
}
}
ycore.SecondarySwap.openPost(res)
}, payload)
}
render(){
ycore.crouter.native('main')
return null
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.notify.error(err)
}
}
render() {
ycore.crouter.native('main')
return null
}
}

View File

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

View File

@ -4,143 +4,162 @@ import { SearchCard } from 'components'
import styles from './styles.less'
import * as ycore from 'ycore'
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'
class SearchPageIndexer extends PureComponent {
constructor(props){
super(props),
this.state = {
constructor(props) {
super(props),
(this.state = {
SearchResult: '',
loading: true
}
}
toogleLoading(){
this.setState({loading: !this.state.loading})
}
componentDidMount(){
try {
const {location} = this.props
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);
loading: true,
})
}
toogleLoading() {
this.setState({ loading: !this.state.loading })
}
componentDidMount() {
try {
const { location } = this.props
const matchSearch = pathMatchRegexp('/s/:id', location.pathname)
const parsed = matchSearch.shift()
const raw = parsed.toString()
const string = raw.replace('/s/', "")
const string = raw.replace('/s/', '')
const payload = { key: string }
ycore.comty_search.keywords((err, res) => {
if (err) {
ycore.notify.error(err)
}
ycore.yconsole.log('Founded entries => ', JSON.parse(res))
this.setState({ SearchResult: res })
this.toogleLoading()
}, payload)
} catch (err) {
ycore.notify.error(err)
}
}
if (matchSearch) {
renderResult = source => {
try {
const Empty = (
<div>
<antd.Result
status="404"
title="Nothing..."
subTitle="Sorry, this does not exist."
/>
</div>
)
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>
)
// 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)
}
}
return(<div><center> Render Error </center></div>)
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

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