mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
*update: contextual menu
*upadate: theme handlers & darkmodes *added: window controllers api
This commit is contained in:
parent
a863864644
commit
c75f0744c2
@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
app_config: {
|
||||
id: "comty",
|
||||
siteName: 'Comty',
|
||||
copyright: 'RageStudio©',
|
||||
MainPath: '/',
|
||||
@ -12,6 +13,7 @@ module.exports = {
|
||||
api_prefix: 'ycorejs_apiv3',
|
||||
app_settings_storage: 'app_settings',
|
||||
endpoint_global: 'https://comty.pw',
|
||||
proxy_local: 'http://localhost:8000',
|
||||
|
||||
session_token_storage: 'cid',
|
||||
session_data_storage: 'data',
|
||||
|
14
globals/contextMenu.js
Normal file
14
globals/contextMenu.js
Normal file
@ -0,0 +1,14 @@
|
||||
import * as Icons from 'components/Icons'
|
||||
|
||||
export default [
|
||||
{
|
||||
key: "inspect_element",
|
||||
title: "Inspect",
|
||||
icon: <Icons.Command />,
|
||||
params: {
|
||||
onClick: (e) => {
|
||||
window.inspectElement(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
@ -20,8 +20,9 @@ const packagejson = require('../package.json')
|
||||
const is = require('electron-is')
|
||||
const waitOn = require('wait-on');
|
||||
const { getDoNotDisturb } = require('electron-notification-state');
|
||||
const { app_config } = require("../config");
|
||||
|
||||
let app_path = is.dev()? 'http://127.0.0.1:8000/' : `file://${path.join(__dirname, '..', 'renderer')}/index.html`;
|
||||
let app_path = is.dev()? app_config.proxy_local : `file://${path.join(__dirname, '..', 'renderer')}/index.html`;
|
||||
let mainWindow;
|
||||
let tray;
|
||||
let watcher;
|
||||
@ -272,6 +273,5 @@ ipcMain.handle('contextualMenu', (event, payload) => {
|
||||
})
|
||||
|
||||
ipcMain.handle('inspectElement', (event, payload) => {
|
||||
log.log(payload)
|
||||
mainWindow.inspectElement(payload.x, payload.y)
|
||||
})
|
@ -51,6 +51,7 @@
|
||||
"electron-updater": "^4.3.4",
|
||||
"enquire-js": "^0.2.1",
|
||||
"feather-reactjs": "^2.0.13",
|
||||
"html2canvas": "^1.0.0-rc.7",
|
||||
"jquery": "^3.5.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"less-vars-to-js": "^1.3.0",
|
||||
|
@ -10,8 +10,10 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
|
||||
> div{
|
||||
transition: all 100ms linear;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
|
||||
@ -26,4 +28,8 @@
|
||||
background-color: #e3e3e3;
|
||||
color: rgba(36, 36, 36, 0.7);
|
||||
}
|
||||
> div:active{
|
||||
transform: scale(0.98);
|
||||
filter: brightness(110%);
|
||||
}
|
||||
}
|
@ -18,27 +18,26 @@ export default class ContextMenu extends React.Component<ContextMenu_props>{
|
||||
this.setWrapperRef = this.setWrapperRef.bind(this)
|
||||
this.handleClickOutside = this.handleClickOutside.bind(this)
|
||||
|
||||
this.eventListener = document.addEventListener('click', this.handleClickOutside, false)
|
||||
this.eventListener = () => {
|
||||
document.addEventListener('click', this.handleClickOutside, false)
|
||||
this.listening = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setWrapperRef(node){
|
||||
this.wrapperRef = node
|
||||
}
|
||||
|
||||
handleClickOutside(event) {
|
||||
if ( this.props.visible || this.wrapperRef && !this.wrapperRef.contains(event.target)) {
|
||||
window.contextMenu.toogle()
|
||||
if ( this.props.visible && this.wrapperRef && !this.wrapperRef.contains(event.target)) {
|
||||
this.listening = false
|
||||
window.contextMenu.toogle()
|
||||
document.removeEventListener('click', this.eventListener, false)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(){
|
||||
if (!this.listening) {
|
||||
this.listening = true
|
||||
this.eventListener
|
||||
}
|
||||
!this.listening ? this.eventListener() : null
|
||||
}
|
||||
|
||||
render(){
|
||||
|
@ -9,10 +9,8 @@ import classnames from 'classnames'
|
||||
|
||||
import settings from 'core/libs/settings'
|
||||
import { router } from 'core/cores'
|
||||
import { notify } from 'core/libs/interface'
|
||||
import LikeBtn from './components/like'
|
||||
import { connect } from 'umi'
|
||||
import config from 'config'
|
||||
|
||||
const { Meta } = antd.Card
|
||||
|
||||
@ -33,6 +31,44 @@ const defaultPayload = {
|
||||
ReportIgnore: false,
|
||||
}
|
||||
|
||||
const contextMenuPost = [
|
||||
{
|
||||
key: "inspect_element",
|
||||
title: "Copy URL",
|
||||
icon: <Icons.Clipboard />,
|
||||
params: {
|
||||
onClick: (e) => {
|
||||
core.writeToClipboard(core.generatePostURI(e.id))
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "screenshot",
|
||||
title: "Save screenshot",
|
||||
icon: <Icons.Aperture />,
|
||||
params: {
|
||||
itemProps: {
|
||||
style: { color: "#40a9ff" }
|
||||
},
|
||||
onClick: (e) => {
|
||||
core.createScreenshotFromElement(document.getElementById(e.id))
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "require_test",
|
||||
title: "Require Test => DEV",
|
||||
icon: <Icons.Cloud />,
|
||||
params: {
|
||||
onClick: (e) => {
|
||||
console.log('Heeeey you developeeer')
|
||||
},
|
||||
keepOnClick: true,
|
||||
require: "dev"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@connect(({ app }) => ({ app }))
|
||||
export default class PostCard extends React.Component {
|
||||
state = {
|
||||
@ -47,13 +83,6 @@ export default class PostCard extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
generatePostURI(id){
|
||||
if(config.app_config.endpoint_global && id){
|
||||
return `${config.app_config.endpoint_global}/post/${id}`
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
goElementById(id){
|
||||
document.getElementById(id).scrollIntoView({
|
||||
behavior: "smooth",
|
||||
@ -66,19 +95,6 @@ export default class PostCard extends React.Component {
|
||||
this.setState({ visibleMoreMenu: !this.state.visibleMoreMenu })
|
||||
}
|
||||
|
||||
handleActions(){
|
||||
|
||||
}
|
||||
|
||||
writeToClipboard(text){
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => {
|
||||
notify.info('Copy to clipboard')
|
||||
}, () => {
|
||||
/* failure */
|
||||
})
|
||||
}
|
||||
|
||||
renderReportedPost(){
|
||||
if(this.state.ReportIgnore) return null
|
||||
return (
|
||||
@ -160,6 +176,8 @@ export default class PostCard extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
//
|
||||
|
||||
const actions = [
|
||||
<LikeBtn count={this.state.payload.post_likes} liked={core.booleanFix(this.state.payload.is_liked)} />,
|
||||
<Icons.Share2 />,
|
||||
@ -169,12 +187,12 @@ export default class PostCard extends React.Component {
|
||||
]
|
||||
|
||||
return (
|
||||
<div className={styles.post_card_wrapper}>
|
||||
<div key={this.state.payload.id} id={this.state.payload.id} className={styles.post_card_wrapper}>
|
||||
<antd.Card
|
||||
className={settings("post_hidebar") ? null : styles.showMode}
|
||||
onDoubleClick={() => null}
|
||||
onClick={() => this.goElementById(this.state.payload.id)}
|
||||
onContextMenu={() => this.writeToClipboard(this.generatePostURI(this.state.payload.id))}
|
||||
onContextMenu={(e) => { window.contextMenu.open({ xPos: e.clientX, yPos: e.clientY, fragment: window.contextMenu.generate(contextMenuPost, this.state.payload) }) }}
|
||||
actions={actions}
|
||||
hoverable
|
||||
>
|
||||
|
@ -6,14 +6,14 @@ import { i18n, app_config } from 'config';
|
||||
import * as errorHandlers from 'core/libs/errorhandler'
|
||||
import platform from 'platform'
|
||||
import request from 'request'
|
||||
import html2canvas from 'html2canvas'
|
||||
|
||||
const { pathToRegexp } = require('path-to-regexp');
|
||||
|
||||
export const languages = i18n ? i18n.languages.map(item => item.key) : [];
|
||||
export const defaultLanguage = i18n ? i18n.defaultLanguage : '';
|
||||
|
||||
import './libs'
|
||||
import './cores'
|
||||
import * as libs from './libs'
|
||||
|
||||
export const package_json = require('../../package.json');
|
||||
export const UUAID = `${package_json.name}==${package_json.UUID}`;
|
||||
@ -29,6 +29,35 @@ export const app_info = {
|
||||
layout: platform.layout
|
||||
};
|
||||
|
||||
export function createScreenshotFromElement(element){
|
||||
if (!element) return false
|
||||
html2canvas(element, {
|
||||
useCORS: true,
|
||||
proxy: app_config.proxy_local,
|
||||
scale: 4,
|
||||
backgroundColor: "transparent"
|
||||
}).then(canvas => {
|
||||
downloadEncodedURI({ data: canvas.toDataURL() })
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function generatePostURI(id){
|
||||
if(app_config.endpoint_global && id){
|
||||
return `${app_config.endpoint_global}/post/${id}`
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function writeToClipboard(text){
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => {
|
||||
libs.Interface.notify.info('Copy to clipboard')
|
||||
}, () => {
|
||||
/* failure */
|
||||
})
|
||||
}
|
||||
|
||||
// [Experimental], not in use
|
||||
export function getGlobals(params, callback) {
|
||||
if (!params || !params.server) return false
|
||||
@ -79,12 +108,32 @@ export function urlToBase64(url, callback){
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
export function b64toBlob(b64Data, contentType='', sliceSize=512){
|
||||
const byteCharacters = atob(b64Data);
|
||||
const byteArrays = [];
|
||||
|
||||
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
||||
const slice = byteCharacters.slice(offset, offset + sliceSize);
|
||||
|
||||
const byteNumbers = new Array(slice.length);
|
||||
for (let i = 0; i < slice.length; i++) {
|
||||
byteNumbers[i] = slice.charCodeAt(i);
|
||||
}
|
||||
|
||||
const byteArray = new Uint8Array(byteNumbers);
|
||||
byteArrays.push(byteArray);
|
||||
}
|
||||
|
||||
const blob = new Blob(byteArrays, {type: contentType});
|
||||
return blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a download with encoded uri
|
||||
*
|
||||
* @param {object} payload - Generation Data
|
||||
*/
|
||||
export function downloadEncodedURI(payload){
|
||||
export function downloadDecodedURI(payload){
|
||||
if(!payload) return false
|
||||
let { data, type, charset, filename } = payload
|
||||
/**
|
||||
@ -94,17 +143,37 @@ export function downloadEncodedURI(payload){
|
||||
if (!data || !type) return false
|
||||
try {
|
||||
if (!filename) {
|
||||
filename = `export_${time.now()}.${type.split("/")[1]}`
|
||||
filename = `${app_config.id}_${time.now()}.${type.split("/")[1]}`
|
||||
}
|
||||
let tmp = document.createElement('a')
|
||||
tmp.href = `data:${type};charset=${charset},${encodeURIComponent(data)}`
|
||||
tmp.download=filename
|
||||
tmp.download= filename
|
||||
tmp.click()
|
||||
} catch (error) {
|
||||
errorHandlers.onError.internal_proccess(error)
|
||||
}
|
||||
}
|
||||
|
||||
export function downloadEncodedURI(payload){
|
||||
if(!payload) return false
|
||||
let { data, filename } = payload
|
||||
/**
|
||||
*
|
||||
* @param {object} payload - Generation Data
|
||||
*/
|
||||
if (!data) return false
|
||||
try {
|
||||
if (!filename) {
|
||||
filename = `${app_config.id}_${time.now()}.${data.split("/")[1].split(";")[0]}`
|
||||
}
|
||||
let tmp = document.createElement('a')
|
||||
tmp.href = data
|
||||
tmp.download= filename
|
||||
tmp.click()
|
||||
} catch (error) {
|
||||
errorHandlers.onError.internal_proccess(error)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the last object from array
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react'
|
||||
import * as antd from 'antd'
|
||||
import * as Icons from 'components/Icons'
|
||||
import { downloadEncodedURI } from 'core'
|
||||
import { downloadDecodedURI } from 'core'
|
||||
|
||||
export interface exportData_props {
|
||||
data: string;
|
||||
@ -25,7 +25,7 @@ const exportData_render = (props: exportData_props) => {
|
||||
antd.Modal.confirm({
|
||||
title: <div><Icons.Code /> Your export <antd.Tag> {`${props.type.split("/")[1]}`} </antd.Tag></div>,
|
||||
icon: null,
|
||||
onOk: () => downloadEncodedURI({data: props.data, type: props.type}),
|
||||
onOk: () => downloadDecodedURI({data: props.data, type: props.type}),
|
||||
okText: <><Icons.Download />Download as File</> ,
|
||||
cancelText: "Done",
|
||||
content: exportCodeRender(props.data),
|
||||
|
@ -13,22 +13,12 @@ import classnames from 'classnames'
|
||||
import { app_config } from 'config'
|
||||
import { theme } from 'core/libs/style'
|
||||
import * as antd from 'antd'
|
||||
import * as Icons from 'components/Icons'
|
||||
|
||||
import contextMenuList from 'globals/contextMenu'
|
||||
import styles from './PrimaryLayout.less'
|
||||
|
||||
const contextMenuList = [
|
||||
{
|
||||
key: "inspect_element",
|
||||
title: "Inspect",
|
||||
icon: <Icons.Command />
|
||||
}
|
||||
]
|
||||
|
||||
const { Content } = antd.Layout
|
||||
const { Sider, Overlay, ContextMenu } = AppLayout
|
||||
const isActive = (key) => { return key? key.active : false }
|
||||
const currentTheme = theme.get()
|
||||
|
||||
@withRouter
|
||||
@connect(({ app, loading }) => ({ app, loading }))
|
||||
@ -39,53 +29,90 @@ class PrimaryLayout extends React.Component {
|
||||
collapsed: app_config.default_collapse_sider ? true : false,
|
||||
isMobile: false
|
||||
},
|
||||
|
||||
this.handleContextMenu = window.addEventListener("contextmenu", (e) => {
|
||||
this.handleContextMenu = document.getElementById("root").addEventListener("contextmenu", (e) => {
|
||||
e.preventDefault()
|
||||
window.contextMenu.open({ xPos: e.clientX, yPos: e.clientY, fragment: this.generateContextMenu() })
|
||||
},false )
|
||||
window.DarkMode = isActive(currentTheme["darkmode"])? true : false
|
||||
window.contextMenu.open({ xPos: e.clientX, yPos: e.clientY, fragment: window.contextMenu.generate(contextMenuList, e) })
|
||||
}, false)
|
||||
|
||||
// include API extensions
|
||||
window.requireQuery = (require) =>{
|
||||
return new Promise(resolve => {
|
||||
this.props.dispatch({
|
||||
type: 'app/isUser',
|
||||
payload: require,
|
||||
callback: (e) => {
|
||||
resolve(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
window.inspectElement = (e) => this.props.dispatch({
|
||||
type: "app/ipcInvoke",
|
||||
payload: {
|
||||
key: "inspectElement",
|
||||
payload: { x: e.clientX, y: e.clientY }
|
||||
}
|
||||
})
|
||||
|
||||
window.contextMenu = this.props.app.contextMenu
|
||||
window.contextMenu.open = (payload) => {
|
||||
if (!payload) return false
|
||||
this.props.dispatch({
|
||||
type: "app/updateState",
|
||||
payload: {contextMenu: {
|
||||
...this.props.app.contextMenu,
|
||||
xPos: payload.xPos,
|
||||
yPos: payload.yPos,
|
||||
fragment: payload.fragment,
|
||||
visible: true
|
||||
}}
|
||||
})
|
||||
}
|
||||
|
||||
window.contextMenu.handle = (e, ...rest) => {
|
||||
if(!e || typeof(e) == 'undefined') {
|
||||
return false
|
||||
}
|
||||
|
||||
typeof(e.onClick) !== 'undefined' && e.onClick ? e.onClick(...rest) : null
|
||||
typeof(e.keepOnClick) !== 'undefined' && e.keepOnClick ? null : window.contextMenu.toogle()
|
||||
}
|
||||
|
||||
window.contextMenu.generate = (payload, ...rest) => {
|
||||
if(!payload) return false
|
||||
let tmp = []
|
||||
|
||||
payload.forEach(async(e) => {
|
||||
if (typeof(e.params.require) !== 'undefined') {
|
||||
if(await window.requireQuery(e.params.require)){
|
||||
e.valid = true
|
||||
tmp.push(e)
|
||||
}else{
|
||||
// bruh
|
||||
}
|
||||
|
||||
}else{
|
||||
tmp.push(e)
|
||||
}
|
||||
})
|
||||
return tmp.map((e) => {
|
||||
return(
|
||||
<div {...e.params.itemProps} onClick={() => window.contextMenu.handle(e.params, ...rest)} key={e.key}>
|
||||
{e.icon}{e.title}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
window.contextMenu.toogle = () => {
|
||||
this.props.dispatch({
|
||||
type: "app/updateState",
|
||||
payload: {contextMenu: {...this.props.app.contextMenu, visible: !this.props.app.contextMenu.visible} }
|
||||
})
|
||||
}
|
||||
window.contextMenu.open = (payload) => {
|
||||
if (!payload) return false
|
||||
const fragment = payload.fragment || null
|
||||
const xPos = payload.xPos || null
|
||||
const yPos = payload.yPos || null
|
||||
this.props.dispatch({
|
||||
type: "app/updateState",
|
||||
payload: {contextMenu: {...this.props.app.contextMenu, xPos, yPos, fragment, visible: true}}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenuActions = {
|
||||
inspect_element: (e) =>{
|
||||
this.props.dispatch({
|
||||
type: "app/ipcInvoke",
|
||||
payload: {
|
||||
key: "inspectElement",
|
||||
payload: { x: e.clientX, y: e.clientY }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
generateContextMenu() {
|
||||
return contextMenuList.map((e) => {
|
||||
return(
|
||||
<div onClick={this.handleContextMenuActions[e.key]} key={e.key}>
|
||||
{e.icon}{e.title}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this.handleContextMenu
|
||||
@ -116,32 +143,14 @@ class PrimaryLayout extends React.Component {
|
||||
const { collapsed, isMobile } = this.state
|
||||
const { onCollapseChange } = this
|
||||
const { contextMenu } = app
|
||||
const app_theme = isActive(currentTheme["darkmode"])? "dark" : null
|
||||
const currentTheme = theme.get()
|
||||
|
||||
const SiderProps = { isMobile, collapsed, onCollapseChange }
|
||||
const OverlayProps = { isMobile }
|
||||
|
||||
const breakpoint = {
|
||||
xs: '480px',
|
||||
sm: '576px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px',
|
||||
xxl: '1600px',
|
||||
}
|
||||
window.darkMode = isActive(currentTheme["darkmode"])? true : false
|
||||
document.getElementsByTagName("body")[0].setAttribute("class", window.darkMode? "dark" : "light")
|
||||
|
||||
const SiderProps = {
|
||||
breakpoint,
|
||||
isMobile,
|
||||
collapsed,
|
||||
onCollapseChange,
|
||||
app_theme
|
||||
}
|
||||
|
||||
const OverlayProps = {
|
||||
breakpoint,
|
||||
isMobile,
|
||||
app_theme
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ContextMenu
|
||||
@ -164,7 +173,10 @@ class PrimaryLayout extends React.Component {
|
||||
overflow: "hidden",
|
||||
opacity: currentTheme.backgroundImage.opacity
|
||||
}} /> : null}
|
||||
<antd.Layout id="app" className={classnames(styles.app, {[styles.interfaced]: this.props.app.electron, [styles.dark_mode]: isActive(currentTheme['darkmode']) } )}>
|
||||
<antd.Layout id="app" className={classnames(styles.app, {
|
||||
[styles.interfaced]: this.props.app.electron,
|
||||
[styles.dark_mode]: window.darkMode
|
||||
} )}>
|
||||
<Sider {...SiderProps} />
|
||||
<div className={styles.primary_layout_container}>
|
||||
<Content
|
||||
|
@ -1,9 +1,14 @@
|
||||
import React, { Component } from 'react'
|
||||
import React from 'react'
|
||||
import BaseLayout from './BaseLayout'
|
||||
import { withRouter } from 'umi'
|
||||
const appBody = document.getElementsByTagName("body")[0]
|
||||
|
||||
@withRouter
|
||||
class Layout extends Component {
|
||||
class Layout extends React.Component {
|
||||
componentDidMount(){
|
||||
const appBody = document.getElementsByTagName("body")[0]
|
||||
appBody.setAttribute("id", "appWrapper")
|
||||
}
|
||||
render() {
|
||||
const { children } = this.props
|
||||
return (
|
||||
|
@ -87,14 +87,14 @@ export default {
|
||||
},
|
||||
effects: {
|
||||
*query({ payload }, { call, put, select }) {
|
||||
const service = yield select(state => state.app.service_valid);
|
||||
const session = yield select(state => state.app.session_valid);
|
||||
const service = yield select(state => state.app.service_valid)
|
||||
const session = yield select(state => state.app.session_valid)
|
||||
const sessionDataframe = yield select(state => state.app.session_data)
|
||||
|
||||
if (!service) {
|
||||
console.error('❌ Cannot connect with validate session service!');
|
||||
console.error('❌ Cannot connect with validate session service!')
|
||||
}
|
||||
|
||||
|
||||
if (!sessionDataframe && session ) {
|
||||
console.log('Updating dataframe!')
|
||||
yield put({ type: 'handleUpdateData' })
|
||||
@ -141,7 +141,7 @@ export default {
|
||||
let container = yield select(state => state.app.app_theme)
|
||||
let style_keys = []
|
||||
let tmp = []
|
||||
|
||||
|
||||
container.forEach((e)=>{style_keys[e.key] = e.value})
|
||||
|
||||
if(!style_keys[payload.key]){
|
||||
@ -163,7 +163,7 @@ export default {
|
||||
const session = yield select(state => state.app.session_valid);
|
||||
let sessionAuthframe = cookie.get(app_config.session_token_storage)
|
||||
let sessionDataframe = sessionStorage.getItem(app_config.session_data_storage)
|
||||
|
||||
|
||||
if (sessionAuthframe) {
|
||||
try {
|
||||
sessionAuthframe = jwt.decode(sessionAuthframe)
|
||||
@ -172,18 +172,18 @@ export default {
|
||||
verbosity.error('Invalid AUTHFRAME !', error)
|
||||
cookie.remove(app_config.session_token_storage)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sessionDataframe) {
|
||||
try {
|
||||
sessionDataframe = JSON.parse(atob(sessionDataframe))
|
||||
yield put({ type: 'handleUpdateDataFrames', payload: sessionDataframe })
|
||||
} catch (error) {
|
||||
verbosity.error('Invalid DATAFRAME !', error, session)
|
||||
sessionDataframe = null
|
||||
verbosity.error('Invalid DATAFRAME !', error, session)
|
||||
sessionDataframe = null
|
||||
sessionStorage.clear()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
verbosity.error(error)
|
||||
}
|
||||
@ -212,7 +212,7 @@ export default {
|
||||
if (state.session_authframe) {
|
||||
if (settings("session_noexpire")) {
|
||||
state.session_valid = true
|
||||
return
|
||||
return
|
||||
}
|
||||
const tokenExp = state.session_authframe.exp * 1000
|
||||
const tokenExpLocale = new Date(tokenExp).toLocaleString()
|
||||
@ -223,7 +223,7 @@ export default {
|
||||
settings("session_noexpire") ? '( Infinite )' : `( ${tokenExpLocale} )`
|
||||
} || NOW => ${now}`
|
||||
)
|
||||
|
||||
|
||||
if (tokenExp < now) {
|
||||
verbosity.debug('This token is expired !!!')
|
||||
state.session_valid = false
|
||||
@ -251,11 +251,9 @@ export default {
|
||||
isDev: sessionData.dev,
|
||||
isPro: sessionData.is_pro
|
||||
},
|
||||
exp: settings("session_noexpire")
|
||||
? 0
|
||||
: Math.floor(Date.now() / 1000) + 60 * 60,
|
||||
}
|
||||
|
||||
exp: Math.floor(Date.now() / 1000) * 120
|
||||
}
|
||||
|
||||
jwt.sign(frame, state.server_key, (err, token) => {
|
||||
if (err) {
|
||||
verbosity.error(err)
|
||||
@ -273,7 +271,7 @@ export default {
|
||||
},
|
||||
handleUpdateData(state){
|
||||
const frame = {
|
||||
id: state.session_uuid,
|
||||
id: state.session_uuid,
|
||||
access_token: state.session_token,
|
||||
serverKey: state.server_key
|
||||
}
|
||||
@ -285,7 +283,7 @@ export default {
|
||||
try {
|
||||
const session_data = JSON.stringify(JSON.parse(res)["user_data"])
|
||||
sessionStorage.setItem(app_config.session_data_storage, btoa(session_data))
|
||||
state.session_data = session_data
|
||||
location.reload()
|
||||
} catch (error) {
|
||||
verbosity.error(error)
|
||||
}
|
||||
@ -364,6 +362,8 @@ export default {
|
||||
state.session_authframe = null;
|
||||
cookie.remove(app_config.session_token_storage)
|
||||
sessionStorage.clear()
|
||||
router.push('/')
|
||||
location.reload()
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ import { connect } from 'umi'
|
||||
import settings from 'core/libs/settings'
|
||||
import { PostCard, PostCreator } from 'components'
|
||||
import * as antd from 'antd'
|
||||
import styles from './index.less'
|
||||
|
||||
@connect(({ app }) => ({ app }))
|
||||
export default class Explore extends React.Component {
|
||||
@ -55,14 +56,12 @@ export default class Explore extends React.Component {
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div className={styles.exploreWrapper}>
|
||||
<List
|
||||
//loadMore={loadMore}
|
||||
dataSource={this.state.feed}
|
||||
renderItem={item => (
|
||||
<div id={item.id}>
|
||||
<PostCard payload={item} key={item.id} />
|
||||
</div>
|
||||
<PostCard payload={item}/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
3
src/pages/explore/index.less
Normal file
3
src/pages/explore/index.less
Normal file
@ -0,0 +1,3 @@
|
||||
.exploreWrapper{
|
||||
|
||||
}
|
@ -8,6 +8,9 @@ import * as Icons from 'components/Icons'
|
||||
export default class Logout extends React.Component{
|
||||
|
||||
componentDidMount(){
|
||||
if (!this.props.app.session_valid) {
|
||||
return false
|
||||
}
|
||||
const dispatchLogout = () => this.props.dispatch({ type: "app/logout" })
|
||||
|
||||
antd.Modal.confirm({
|
||||
|
@ -128,8 +128,8 @@ class BackgroundImage extends ThemeConfigurator{
|
||||
key: "backgroundImage",
|
||||
model: { active: false, opacity: null, src: null },
|
||||
|
||||
textColor: this.rgbToScheme(getComputedStyle(document.getElementById("root")).color),
|
||||
overlayColor: this.rgbToScheme(getComputedStyle(document.getElementById("root")).backgroundColor),
|
||||
textColor: this.rgbToScheme(getComputedStyle(document.getElementById("appWrapper")).color),
|
||||
overlayColor: this.rgbToScheme(getComputedStyle(document.getElementById("appWrapper")).backgroundColor),
|
||||
|
||||
processing: null,
|
||||
customURL: '',
|
||||
|
@ -36,26 +36,20 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#root{
|
||||
background-color: @AppTheme_global_background!important;
|
||||
color: @AppTheme_global_color!important;
|
||||
}
|
||||
|
||||
.app{
|
||||
&.interfaced{
|
||||
height: calc(100% - @AppTheme_global_winavbar_height)!important;
|
||||
}
|
||||
|
||||
&.dark_mode{
|
||||
filter: invert(100%);
|
||||
|
||||
|
||||
:global{
|
||||
.ant-card{
|
||||
background: @AppTheme_global_background_dark!important;
|
||||
filter: invert(100%);
|
||||
img, svg, video {
|
||||
filter: invert(100%);
|
||||
color: @AppTheme_global_background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#app {
|
||||
@ -64,7 +58,6 @@
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
||||
color: @AppTheme_global_color!important;
|
||||
background-repeat: repeat-x;
|
||||
background-size: cover;
|
||||
background-position-y: center;
|
||||
@ -89,6 +82,8 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
body {
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
@ -101,7 +96,12 @@ body {
|
||||
line-height: @base-line-height;
|
||||
|
||||
font-family: @__Global_texted_font;
|
||||
background-color: @AppTheme_global_background!important;
|
||||
color: @AppTheme_global_color!important;
|
||||
background-color: @AppTheme_global_background;
|
||||
|
||||
&.dark{
|
||||
background-color: @AppTheme_global_color;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @bp-small){
|
||||
|
Loading…
x
Reference in New Issue
Block a user