mirror of
https://github.com/RetroShare/RSNewWebUI.git
synced 2026-09-14 11:05:47 +05:00
commit
806d13efca
@ -2,10 +2,9 @@ const m = require('mithril');
|
||||
const rs = require('rswebui');
|
||||
const util = require('boards/boards_util');
|
||||
const Data = util.Data;
|
||||
const peopleUtil = require('people/people_util');
|
||||
|
||||
const messageGroups = ['Public', 'Restricted Circle', 'Restricted Node Group'];
|
||||
const messageGroupsCode = [util.PUBLIC, util.EXTERNAL, util.NODES_GROUP]; //rsgxscirles.h:50
|
||||
const messageGroupsCode = [util.PUBLIC, util.EXTERNAL, util.NODES_GROUP]; // rsgxscirles.h:50
|
||||
|
||||
function createboard() {
|
||||
let title;
|
||||
@ -156,7 +155,6 @@ function createboard() {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const BoardView = () => {
|
||||
let bname = '';
|
||||
let bimage = '';
|
||||
@ -187,109 +185,113 @@ const BoardView = () => {
|
||||
plist = Data.Posts[v.attrs.id];
|
||||
}
|
||||
},
|
||||
view: (v) =>
|
||||
view: (v) => [
|
||||
m(
|
||||
'.widget',
|
||||
'a[title=Back]',
|
||||
{
|
||||
key: v.attrs.id,
|
||||
onclick: () =>
|
||||
m.route.set('/boards/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
[
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/boards/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('h3', bname),
|
||||
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsposted/subscribeToBoard', {
|
||||
boardId: v.attrs.id,
|
||||
subscribe: !bsubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
bsubscribed = !bsubscribed;
|
||||
Data.DisplayBoards[v.attrs.id].isSubscribed = bsubscribed;
|
||||
}
|
||||
},
|
||||
},
|
||||
bsubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
m('img.boardpic', {
|
||||
src: 'data:image/png;base64,' + bimage.mData.base64,
|
||||
}),
|
||||
m('[id=boarddetails]', [
|
||||
m('p', m('b', 'Posts: '), bposts),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Date created: '),
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m('p', m('b', 'Admin: '), bauthor),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Last activity: '),
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
]),
|
||||
m('hr'),
|
||||
m('boarddesc', m('b', 'Description: '), Data.DisplayBoards[v.attrs.id].description),
|
||||
m('hr'),
|
||||
m(
|
||||
'postdetails',
|
||||
{
|
||||
style: 'display:' + (bsubscribed ? 'block' : 'none'),
|
||||
},
|
||||
m('h3', 'Posts'),
|
||||
|
||||
m(
|
||||
'[id=grid]',
|
||||
Object.keys(plist).map((key, index) => [
|
||||
m(
|
||||
'div',
|
||||
{
|
||||
class: 'card',
|
||||
style: 'display: ' + (plist[key].isSearched? 'block': 'none'),
|
||||
onclick: () => {
|
||||
m.route.set('/boards/:tab/:mGroupId/:mMsgId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: v.attrs.id,
|
||||
mMsgId: key,
|
||||
});
|
||||
},
|
||||
},
|
||||
[
|
||||
m('img', {
|
||||
class: 'card-img',
|
||||
src: 'data:image/png;base64,' + plist[key].post.mThumbnail.mData.base64,
|
||||
|
||||
alt: 'No Thumbnail',
|
||||
}),
|
||||
m('div', { class: 'card-info' }, [
|
||||
m('h4', { class: 'card-title' }, plist[key].post.mMeta.mMsgName),
|
||||
]),
|
||||
]
|
||||
),
|
||||
])
|
||||
)
|
||||
),
|
||||
]
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('.widget__heading', [
|
||||
m('h3', bname),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsposted/subscribeToBoard', {
|
||||
boardId: v.attrs.id,
|
||||
subscribe: !bsubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
bsubscribed = !bsubscribed;
|
||||
Data.DisplayBoards[v.attrs.id].isSubscribed = bsubscribed;
|
||||
}
|
||||
},
|
||||
},
|
||||
bsubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
]),
|
||||
m('.widget__body', [
|
||||
m('.media-item', [
|
||||
m('.media-item__details', [
|
||||
m('img', {
|
||||
src:
|
||||
bimage.mData.base64 === ''
|
||||
? 'data/streaming.png'
|
||||
: `data:image/png;base64,${bimage.mData.base64}`,
|
||||
}),
|
||||
m('.media-item__details-info', [
|
||||
m('div', [m('b', 'Posts: '), m('span', bposts)]),
|
||||
m('div', [
|
||||
m('b', 'Date created: '),
|
||||
m(
|
||||
'span',
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'Unknown'
|
||||
),
|
||||
]),
|
||||
m('div', [m('b', 'Admin: '), m('span', bauthor)]),
|
||||
m('div', [
|
||||
m('b', 'Last activity: '),
|
||||
m(
|
||||
'span',
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'Unknown'
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
m('.media-item__desc', [
|
||||
m('b', 'Description: '),
|
||||
m('span', Data.DisplayBoards[v.attrs.id].description || 'No Description'),
|
||||
]),
|
||||
]),
|
||||
m(
|
||||
'.posts',
|
||||
{
|
||||
style: 'display:' + (bsubscribed ? 'flex' : 'none'),
|
||||
},
|
||||
m('.posts__heading', m('h3', 'Posts')),
|
||||
m(
|
||||
'.posts-container',
|
||||
Object.keys(plist).map((key, index) => [
|
||||
m(
|
||||
'.posts-container-card',
|
||||
{
|
||||
style: 'display: ' + (plist[key].isSearched ? 'flex' : 'none'),
|
||||
onclick: () => {
|
||||
m.route.set('/boards/:tab/:mGroupId/:mMsgId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: v.attrs.id,
|
||||
mMsgId: key,
|
||||
});
|
||||
},
|
||||
},
|
||||
[
|
||||
m('img', {
|
||||
src:
|
||||
plist[key].post.mThumbnail.mData.base64 === ''
|
||||
? 'data/streaming.png'
|
||||
: 'data:image/png;base64,' + plist[key].post.mThumbnail.mData.base64,
|
||||
alt: 'No Thumbnail',
|
||||
}),
|
||||
m('p', plist[key].post.mMeta.mMsgName),
|
||||
]
|
||||
),
|
||||
])
|
||||
)
|
||||
),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports = {
|
||||
BoardView,
|
||||
createboard,
|
||||
|
||||
@ -5,14 +5,13 @@ const util = require('boards/boards_util');
|
||||
const viewUtil = require('boards/board_view');
|
||||
const peopleUtil = require('people/people_util');
|
||||
|
||||
const getBoards =
|
||||
{
|
||||
All : [],
|
||||
PopularBoards : [],
|
||||
SubscribedBoards : [],
|
||||
MyBoards : [],
|
||||
OtherBoards : [],
|
||||
async load(){
|
||||
const getBoards = {
|
||||
All: [],
|
||||
PopularBoards: [],
|
||||
SubscribedBoards: [],
|
||||
MyBoards: [],
|
||||
OtherBoards: [],
|
||||
async load() {
|
||||
const res = await rs.rsJsonApiRequest('/rsPosted/getBoardsSummaries');
|
||||
const data = res.body;
|
||||
getBoards.All = data.groupInfo;
|
||||
@ -21,11 +20,10 @@ const getBoards =
|
||||
getBoards.OtherBoards = getBoards.PopularBoards.slice(5);
|
||||
getBoards.PopularBoards = getBoards.PopularBoards.slice(0, 5);
|
||||
getBoards.SubscribedBoards = getBoards.All.filter(
|
||||
(board) =>
|
||||
board.mSubscribeFlags === util.GROUP_SUBSCRIBE_SUBSCRIBED
|
||||
(board) => board.mSubscribeFlags === util.GROUP_SUBSCRIBE_SUBSCRIBED
|
||||
);
|
||||
getBoards.MyBoards = getBoards.All.filter(
|
||||
(board) => board.mSubscribeFlags === util.GROUP_MY_BOARD
|
||||
(board) => board.mSubscribeFlags === util.GROUP_MY_BOARD
|
||||
);
|
||||
},
|
||||
};
|
||||
@ -34,7 +32,7 @@ const sections = {
|
||||
MyBoards: require('boards/my_boards'),
|
||||
SubscribedBoards: require('boards/subscribed_boards'),
|
||||
PopularBoards: require('boards/popular_boards'),
|
||||
OtherBoards: require('boards/other_boards')
|
||||
OtherBoards: require('boards/other_boards'),
|
||||
};
|
||||
|
||||
const Layout = () => {
|
||||
@ -56,49 +54,49 @@ const Layout = () => {
|
||||
});
|
||||
},
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m(util.SearchBar, {
|
||||
list: getBoards.All,
|
||||
}),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
style: {fontSize: '1.2em', width: '200px'},
|
||||
onclick: () =>
|
||||
ownId && util.popupmessage(
|
||||
m(viewUtil.createboard, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Board'
|
||||
),
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/boards/',
|
||||
}),
|
||||
m('.board-node-panel',
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId')
|
||||
? m(viewUtil.PostView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
forumId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId')
|
||||
? m(viewUtil.BoardView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
list: getBoards[vnode.attrs.pathInfo.tab],
|
||||
})
|
||||
),
|
||||
m('.widget', [
|
||||
m('.top-heading', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () =>
|
||||
ownId &&
|
||||
util.popupmessage(
|
||||
m(viewUtil.createboard, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Board'
|
||||
),
|
||||
m(util.SearchBar, {
|
||||
list: getBoards.All,
|
||||
}),
|
||||
]),
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId')
|
||||
? m(viewUtil.PostView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
forumId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId')
|
||||
? m(viewUtil.BoardView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
list: getBoards[vnode.attrs.pathInfo.tab],
|
||||
}),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout, {
|
||||
pathInfo: vnode.attrs,
|
||||
});
|
||||
return [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/boards/',
|
||||
}),
|
||||
m('.node-panel', m(Layout, { pathInfo: vnode.attrs })),
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('boards/boards_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'My Boards'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'My Boards')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.BoardTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('boards/boards_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Other Boards'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Other Boards')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.BoardTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('boards/boards_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Popular Boards'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Popular Boards')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.BoardTable,
|
||||
m('tbody', [
|
||||
@ -14,13 +13,13 @@ const Layout = () => {
|
||||
m(util.BoardSummary, {
|
||||
details: board,
|
||||
category: 'PopularBoards',
|
||||
}),
|
||||
})
|
||||
),
|
||||
v.attrs.list.map((board) =>
|
||||
m(util.DisplayBoardsFromList, {
|
||||
id: board.mGroupId,
|
||||
category: 'PopularBoards',
|
||||
}),
|
||||
})
|
||||
),
|
||||
])
|
||||
),
|
||||
@ -30,4 +29,3 @@ const Layout = () => {
|
||||
};
|
||||
|
||||
module.exports = Layout;
|
||||
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('boards/boards_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Subscribed Boards'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Subscribed Boards')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.BoardTable,
|
||||
m('tbody', [
|
||||
@ -14,13 +13,13 @@ const Layout = () => {
|
||||
m(util.BoardSummary, {
|
||||
details: board,
|
||||
category: 'SubscribedBoards',
|
||||
}),
|
||||
})
|
||||
),
|
||||
v.attrs.list.map((board) =>
|
||||
m(util.DisplayBoardsFromList, {
|
||||
id: board.mGroupId,
|
||||
category: 'SubscribedBoards',
|
||||
}),
|
||||
})
|
||||
),
|
||||
])
|
||||
),
|
||||
@ -30,4 +29,3 @@ const Layout = () => {
|
||||
};
|
||||
|
||||
module.exports = Layout;
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@ async function parsefile(file, type) {
|
||||
return ansList;
|
||||
}
|
||||
const messageGroups = ['Public', 'Restricted Circle', 'Restricted Node Group'];
|
||||
const messageGroupsCode = [util.PUBLIC, util.EXTERNAL, util.NODES_GROUP]; //rsgxscirles.h:50
|
||||
const messageGroupsCode = [util.PUBLIC, util.EXTERNAL, util.NODES_GROUP]; // rsgxscirles.h:50
|
||||
|
||||
function createchannel() {
|
||||
let title;
|
||||
@ -200,10 +200,10 @@ function createchannel() {
|
||||
name: title,
|
||||
description: body,
|
||||
thumbnail: { mData: { base64: thumbnail } },
|
||||
...(Number(identity) !== 0 && { authorId: identity }), //checks if some identity has to be assigned
|
||||
...(Number(identity) !== 0 && { authorId: identity }), // checks if some identity has to be assigned
|
||||
circleType: selectedGroupCode,
|
||||
...(selectedGroupCode === util.EXTERNAL &&
|
||||
selectedCircle && { circleId: selectedCircle.mGroupId }), //checks if the selectedGroup code is EXTERNAL
|
||||
selectedCircle && { circleId: selectedCircle.mGroupId }), // checks if the selectedGroup code is EXTERNAL
|
||||
});
|
||||
if (res.body.retval) {
|
||||
util.updatedisplaychannels(res.body.channelId);
|
||||
@ -287,7 +287,7 @@ const AddPost = () => {
|
||||
channelId: vnode.attrs.chanId,
|
||||
title: ptitle,
|
||||
mBody: content,
|
||||
files: pfiles, //does not work for now
|
||||
files: pfiles, // does not work for now
|
||||
thumbnail: { mData: { base64: pthumbnail } },
|
||||
});
|
||||
res.body.retval === false
|
||||
@ -340,90 +340,95 @@ const ChannelView = () => {
|
||||
plist = Data.Posts[v.attrs.id];
|
||||
}
|
||||
},
|
||||
view: (v) =>
|
||||
view: (v) => [
|
||||
m(
|
||||
'.widget',
|
||||
'a[title=Back]',
|
||||
{
|
||||
key: v.attrs.id,
|
||||
onclick: () =>
|
||||
m.route.set('/channels/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
[
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/channels/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('.widget__heading', [
|
||||
m('h3', cname),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsgxschannels/subscribeToChannel', {
|
||||
channelId: v.attrs.id,
|
||||
subscribe: !csubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
csubscribed = !csubscribed;
|
||||
Data.DisplayChannels[v.attrs.id].isSubscribed = csubscribed;
|
||||
}
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('h3', cname),
|
||||
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsgxschannels/subscribeToChannel', {
|
||||
channelId: v.attrs.id,
|
||||
subscribe: !csubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
csubscribed = !csubscribed;
|
||||
Data.DisplayChannels[v.attrs.id].isSubscribed = csubscribed;
|
||||
}
|
||||
},
|
||||
},
|
||||
csubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
m('img.channelpic', {
|
||||
src:
|
||||
cimage.mData.base64 === ''
|
||||
? 'data/streaming.png'
|
||||
: 'data:image/png;base64,' + cimage.mData.base64,
|
||||
}),
|
||||
m('[id=channeldetails]', [
|
||||
m('p', m('b', 'Posts: '), cposts),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Date created: '),
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m('p', m('b', 'Admin: '), cauthor),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Last activity: '),
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
},
|
||||
csubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
]),
|
||||
m('.widget__body', [
|
||||
m('.media-item', [
|
||||
m('.media-item__details', [
|
||||
m('img', {
|
||||
src:
|
||||
cimage.mData.base64 === ''
|
||||
? 'data/streaming.png'
|
||||
: `data:image/png;base64,${cimage.mData.base64}`,
|
||||
}),
|
||||
m('.media-item__details-info', [
|
||||
m('div', [m('b', 'Posts: '), m('span', cposts)]),
|
||||
m('div', [
|
||||
m('b', 'Date created: '),
|
||||
m(
|
||||
'span',
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'Unknown'
|
||||
),
|
||||
]),
|
||||
m('div', [m('b', 'Admin: '), m('span', cauthor)]),
|
||||
m('div', [
|
||||
m('b', 'Last activity: '),
|
||||
m(
|
||||
'span',
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'Unknown'
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
m('hr'),
|
||||
m('channeldesc', m('b', 'Description: '), Data.DisplayChannels[v.attrs.id].description),
|
||||
m('hr'),
|
||||
m(
|
||||
'postdetails',
|
||||
{
|
||||
style: 'display:' + (csubscribed ? 'block' : 'none'),
|
||||
},
|
||||
m('h3', 'Posts'),
|
||||
mychannel &&
|
||||
m(
|
||||
'button',
|
||||
{ onclick: () => widget.popupMessage(m(AddPost, { chanId: v.attrs.id })) },
|
||||
['Add Post', m('i.fas.fa-edit')]
|
||||
),
|
||||
m('hr'),
|
||||
|
||||
m('.media-item__desc', [
|
||||
m('b', 'Description: '),
|
||||
m('span', Data.DisplayChannels[v.attrs.id].description || 'No Description'),
|
||||
]),
|
||||
]),
|
||||
m(
|
||||
'.posts',
|
||||
{
|
||||
style: 'display: ' + (csubscribed ? 'flex' : 'none'),
|
||||
},
|
||||
[
|
||||
m('.posts__heading', [
|
||||
m('h3', 'Posts'),
|
||||
mychannel &&
|
||||
m(
|
||||
'button',
|
||||
{ onclick: () => widget.popupMessage(m(AddPost, { chanId: v.attrs.id })) },
|
||||
['Add Post', m('i.fas.fa-edit')]
|
||||
),
|
||||
]),
|
||||
m(
|
||||
'[id=grid]',
|
||||
'.posts-container',
|
||||
Object.keys(plist).map((key, index) => [
|
||||
m(
|
||||
'div',
|
||||
'.posts-container-card',
|
||||
{
|
||||
class: 'card',
|
||||
style: 'display: ' + (plist[key].isSearched ? 'block' : 'none'), // for search
|
||||
style: 'display: ' + (plist[key].isSearched ? 'flex' : 'none'), // for search
|
||||
onclick: () => {
|
||||
m.route.set('/channels/:tab/:mGroupId/:mMsgId', {
|
||||
tab: m.route.param().tab,
|
||||
@ -434,24 +439,21 @@ const ChannelView = () => {
|
||||
},
|
||||
[
|
||||
m('img', {
|
||||
class: 'card-img',
|
||||
src:
|
||||
plist[key].post.mThumbnail.mData.base64 === ''
|
||||
? 'data/streaming.png'
|
||||
: 'data:image/png;base64,' + plist[key].post.mThumbnail.mData.base64,
|
||||
|
||||
alt: '',
|
||||
alt: 'No Thumbnail',
|
||||
}),
|
||||
m('div', { class: 'card-info' }, [
|
||||
m('h4', { class: 'card-title' }, plist[key].post.mMeta.mMsgName),
|
||||
]),
|
||||
m('p', plist[key].post.mMeta.mMsgName),
|
||||
]
|
||||
),
|
||||
])
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
@ -544,14 +546,16 @@ function displaycomment() {
|
||||
oninit: (v) => {},
|
||||
view: ({ attrs: { commentStruct, identity, replyDepth, voteIdentity } }) => {
|
||||
const comment = commentStruct.comment;
|
||||
let cUpVotes = 0;
|
||||
let cUpVotes = 0;
|
||||
let cDownVotes = 0;
|
||||
let parMap = {};
|
||||
if (Data.ParentCommentMap[comment.mMeta.mMsgId]) {
|
||||
parMap = Data.ParentCommentMap[comment.mMeta.mMsgId];
|
||||
}
|
||||
if(Data.Votes[comment.mMeta.mThreadId] && Data.Votes[comment.mMeta.mThreadId][comment.mMeta.mMsgId])
|
||||
{
|
||||
if (
|
||||
Data.Votes[comment.mMeta.mThreadId] &&
|
||||
Data.Votes[comment.mMeta.mThreadId][comment.mMeta.mMsgId]
|
||||
) {
|
||||
cUpVotes = Data.Votes[comment.mMeta.mThreadId][comment.mMeta.mMsgId].upvotes;
|
||||
cDownVotes = Data.Votes[comment.mMeta.mThreadId][comment.mMeta.mMsgId].downvotes;
|
||||
}
|
||||
@ -695,132 +699,132 @@ const PostView = () => {
|
||||
});
|
||||
fileDown.Downloads.loadStatus(); // for retrieving downloading files.
|
||||
},
|
||||
view: (v) =>
|
||||
m('.widget', { key: v.attrs.msgId }, [
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/channels/:tab/:mGroupId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: m.route.param().mGroupId,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('h3', post.mMeta.mMsgName),
|
||||
m('p', m.trust(post.mMsg)),
|
||||
m('hr'),
|
||||
m('h3', 'Files(' + post.mAttachmentCount + ')'),
|
||||
m(
|
||||
util.FilesTable,
|
||||
view: (v) => [
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/channels/:tab/:mGroupId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: m.route.param().mGroupId,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('.widget__heading', m('h3', post.mMeta.mMsgName)),
|
||||
m('.widget__body', [
|
||||
m('p', { style: { whiteSpace: 'normal' } }, m.trust(post.mMsg)),
|
||||
m('.file-section', [
|
||||
m('h3', 'Files(' + post.mAttachmentCount + ')'),
|
||||
m(
|
||||
'tbody',
|
||||
post.mFiles.map((file) =>
|
||||
m('tr', [
|
||||
m('td', file.mName),
|
||||
m('td', util.formatbytes(file.mSize.xint64)),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
style: { fontSize: '0.9em' },
|
||||
onclick: async () =>
|
||||
widget.popupMessage([
|
||||
m('p', 'Start Download?'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
if (filesInfo[file.mHash] && !filesInfo[file.mHash].retval) {
|
||||
const res = await rs.rsJsonApiRequest('/rsFiles/FileRequest', {
|
||||
fileName: file.mName,
|
||||
hash: file.mHash,
|
||||
flags: util.RS_FILE_REQ_ANONYMOUS_ROUTING,
|
||||
size: {
|
||||
xstr64: file.mSize.xstr64,
|
||||
},
|
||||
});
|
||||
res.body.retval === false
|
||||
? widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', res.body.errorMessage),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('h3', 'Success'),
|
||||
m('hr'),
|
||||
m('p', 'Download Started'),
|
||||
]);
|
||||
m.redraw();
|
||||
}
|
||||
util.FilesTable,
|
||||
m(
|
||||
'tbody',
|
||||
post.mFiles.map((file) =>
|
||||
m('tr', [
|
||||
m('td', file.mName),
|
||||
m('td', util.formatbytes(file.mSize.xint64)),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
style: { fontSize: '0.9em' },
|
||||
onclick: async () =>
|
||||
widget.popupMessage([
|
||||
m('p', 'Start Download?'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
if (filesInfo[file.mHash] && !filesInfo[file.mHash].retval) {
|
||||
const res = await rs.rsJsonApiRequest('/rsFiles/FileRequest', {
|
||||
fileName: file.mName,
|
||||
hash: file.mHash,
|
||||
flags: util.RS_FILE_REQ_ANONYMOUS_ROUTING,
|
||||
size: {
|
||||
xstr64: file.mSize.xstr64,
|
||||
},
|
||||
});
|
||||
res.body.retval === false
|
||||
? widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', res.body.errorMessage),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('h3', 'Success'),
|
||||
m('hr'),
|
||||
m('p', 'Download Started'),
|
||||
]);
|
||||
m.redraw();
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'Start Download'
|
||||
),
|
||||
]),
|
||||
},
|
||||
filesInfo[file.mHash]
|
||||
? filesInfo[file.mHash].retval
|
||||
? 'Open File'
|
||||
: ['Download', m('i.fas.fa-download')]
|
||||
: 'Please Wait...'
|
||||
),
|
||||
fileDown.list[file.mHash] && // using the file from files_util to display download.
|
||||
m(fileUtil.File, {
|
||||
info: fileDown.list[file.mHash],
|
||||
direction: 'down',
|
||||
transferred: fileDown.list[file.mHash].transfered.xint64,
|
||||
parts: [],
|
||||
}),
|
||||
])
|
||||
'Start Download'
|
||||
),
|
||||
]),
|
||||
},
|
||||
filesInfo[file.mHash]
|
||||
? filesInfo[file.mHash].retval
|
||||
? 'Open File'
|
||||
: ['Download', m('i.fas.fa-download')]
|
||||
: 'Please Wait...'
|
||||
),
|
||||
fileDown.list[file.mHash] && // using the file from files_util to display download.
|
||||
m(fileUtil.File, {
|
||||
info: fileDown.list[file.mHash],
|
||||
direction: 'down',
|
||||
transferred: fileDown.list[file.mHash].transfered.xint64,
|
||||
parts: [],
|
||||
}),
|
||||
])
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
m('hr'),
|
||||
m('h3', 'Comments'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
widget.popupMessage(
|
||||
m(AddComment, {
|
||||
parent_comment: '',
|
||||
channelId: v.attrs.channelId,
|
||||
authorId: ownId,
|
||||
threadId: v.attrs.msgId,
|
||||
parentId: v.attrs.msgId,
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
'Add Comment'
|
||||
),
|
||||
m(
|
||||
'label[for=idtags',
|
||||
{
|
||||
style: { marginLeft: '10px' },
|
||||
},
|
||||
'Voter ID: '
|
||||
),
|
||||
m(
|
||||
'select[id=idtags]',
|
||||
{
|
||||
value: voteIdentity,
|
||||
onchange: (e) => {
|
||||
voteIdentity = ownId[e.target.selectedIndex];
|
||||
},
|
||||
},
|
||||
[
|
||||
ownId &&
|
||||
ownId.map((o) =>
|
||||
m(
|
||||
'option',
|
||||
{ value: o },
|
||||
rs.userList.userMap[o].toLocaleString() + ' (' + o.slice(0, 8) + '...)'
|
||||
)
|
||||
),
|
||||
]),
|
||||
m('.comments-section', [
|
||||
m('h3', 'Comments'),
|
||||
m('.comments-section__menu', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
widget.popupMessage(
|
||||
m(AddComment, {
|
||||
parent_comment: '',
|
||||
channelId: v.attrs.channelId,
|
||||
authorId: ownId,
|
||||
threadId: v.attrs.msgId,
|
||||
parentId: v.attrs.msgId,
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
'Add Comment'
|
||||
),
|
||||
m('.comments-section__menu-id', [
|
||||
m('label[for=idtags', 'Voter ID: '),
|
||||
m(
|
||||
'select[id=idtags]',
|
||||
{
|
||||
value: voteIdentity,
|
||||
onchange: (e) => {
|
||||
voteIdentity = ownId[e.target.selectedIndex];
|
||||
},
|
||||
},
|
||||
[
|
||||
ownId &&
|
||||
ownId.map((o) =>
|
||||
m(
|
||||
'option',
|
||||
{ value: o },
|
||||
`${rs.userList.userMap[o].toLocaleString()} (${o.slice(0, 8)}...)`
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
]
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
m(
|
||||
util.CommentsTable,
|
||||
m(
|
||||
@ -843,6 +847,7 @@ const PostView = () => {
|
||||
)
|
||||
),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -61,60 +61,57 @@ const Layout = () => {
|
||||
},
|
||||
// onupdate: getChannels.load,
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId')
|
||||
? ''
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId')
|
||||
? m(util.SearchBar, {
|
||||
category: 'posts',
|
||||
channelId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(util.SearchBar, {
|
||||
category: 'channels',
|
||||
}),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
style: { fontSize: '1.2em', width: '200px' },
|
||||
onclick: () =>
|
||||
ownId &&
|
||||
widget.popupMessage(
|
||||
m(viewUtil.createchannel, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Channel'
|
||||
),
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/channels/',
|
||||
}),
|
||||
m(
|
||||
'.channel-node-panel',
|
||||
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId') // posts
|
||||
? m(viewUtil.PostView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
m('.widget', [
|
||||
m('.top-heading', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () =>
|
||||
ownId &&
|
||||
widget.popupMessage(
|
||||
m(viewUtil.createchannel, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Channel'
|
||||
),
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId')
|
||||
? ''
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId')
|
||||
? m(util.SearchBar, {
|
||||
category: 'posts',
|
||||
channelId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId') // channels view
|
||||
? m(viewUtil.ChannelView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
// subscribed, all, popular, other
|
||||
list: getChannels[vnode.attrs.pathInfo.tab],
|
||||
})
|
||||
),
|
||||
: m(util.SearchBar, {
|
||||
category: 'channels',
|
||||
}),
|
||||
]),
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId') // posts
|
||||
? m(viewUtil.PostView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
channelId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId') // channels view
|
||||
? m(viewUtil.ChannelView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
// subscribed, all, popular, other
|
||||
list: getChannels[vnode.attrs.pathInfo.tab],
|
||||
}),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout, {
|
||||
pathInfo: vnode.attrs,
|
||||
});
|
||||
return [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/channels/',
|
||||
}),
|
||||
m('.node-panel', m(Layout, { pathInfo: vnode.attrs })),
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@ -17,9 +17,9 @@ const RS_FILE_REQ_ANONYMOUS_ROUTING = 0x00000040;
|
||||
const GXS_VOTE_DOWN = 0x0001;
|
||||
const GXS_VOTE_UP = 0x0002;
|
||||
|
||||
//rsgxscircles.h:50
|
||||
const PUBLIC = 1; /// Public distribution
|
||||
const EXTERNAL = 2; /// Restricted to an external circle, based on GxsIds
|
||||
// rsgxscircles.h:50
|
||||
const PUBLIC = 1; // Public distribution
|
||||
const EXTERNAL = 2; // Restricted to an external circle, based on GxsIds
|
||||
const NODES_GROUP = 3;
|
||||
|
||||
const Data = {
|
||||
@ -201,7 +201,7 @@ const SearchBar = () => {
|
||||
let searchString = '';
|
||||
return {
|
||||
view: (v) =>
|
||||
m('input[type=text][id=searchchannel][placeholder=Search Subject].searchbar', {
|
||||
m('input[type=text][placeholder=Search Subject].searchbar', {
|
||||
value: searchString,
|
||||
placeholder:
|
||||
v.attrs.category.localeCompare('channels') === 0 ? 'Search Channels' : 'Search Posts',
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('channels/channels_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'My Channels'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'My Channels')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ChannelTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('channels/channels_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Other Channels'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Other Channels')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ChannelTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('channels/channels_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Popular Channels'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Popular Channels')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ChannelTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('channels/channels_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Subscribed Channels'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Subscribed Channels')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ChannelTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -297,7 +297,6 @@ const LobbyList = {
|
||||
const lobbytagname = vnode.attrs.lobbytagname;
|
||||
const onclick = vnode.attrs.onclick || (() => null);
|
||||
return [
|
||||
m('hr'),
|
||||
vnode.attrs.rooms.map((info) =>
|
||||
m(Lobby, {
|
||||
info,
|
||||
@ -327,12 +326,14 @@ const SubscribedLeftLobbies = {
|
||||
const SubscribedLobbies = {
|
||||
view() {
|
||||
return m('.widget', [
|
||||
m('h3', 'Subscribed chat rooms'),
|
||||
m(LobbyList, {
|
||||
rooms: sortLobbies(Object.values(ChatRoomsModel.subscribedRooms)),
|
||||
tagname: '.lobby.subscribed',
|
||||
onclick: ChatLobbyModel.switchToEvent,
|
||||
}),
|
||||
m('.widget__heading', m('h3', 'Subscribed chat rooms')),
|
||||
m('.widget__body', [
|
||||
m(LobbyList, {
|
||||
rooms: sortLobbies(Object.values(ChatRoomsModel.subscribedRooms)),
|
||||
tagname: '.lobby.subscribed',
|
||||
onclick: ChatLobbyModel.switchToEvent,
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
@ -355,12 +356,14 @@ const PublicLeftLobbies = {
|
||||
|
||||
const PublicLobbies = () => {
|
||||
return m('.widget', [
|
||||
m('h3', 'Public chat rooms'),
|
||||
m(LobbyList, {
|
||||
rooms: ChatRoomsModel.allRooms.filter((info) => !ChatRoomsModel.subscribed(info)),
|
||||
tagname: '.lobby.public',
|
||||
onclick: ChatLobbyModel.setupEvent,
|
||||
}),
|
||||
m('.widget__heading', m('h3', 'Public chat rooms')),
|
||||
m('.widget__body', [
|
||||
m(LobbyList, {
|
||||
rooms: ChatRoomsModel.allRooms.filter((info) => !ChatRoomsModel.subscribed(info)),
|
||||
tagname: '.lobby.public',
|
||||
onclick: ChatLobbyModel.setupEvent,
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
};
|
||||
|
||||
@ -405,7 +408,7 @@ const LobbyName = () => {
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: () => m('.tab-page', [m(SubscribedLobbies), PublicLobbies()]),
|
||||
view: () => m('.node-panel', [m(SubscribedLobbies), PublicLobbies()]),
|
||||
};
|
||||
};
|
||||
|
||||
@ -413,7 +416,7 @@ const LayoutSingle = () => {
|
||||
return {
|
||||
oninit: () => ChatLobbyModel.loadLobby(m.route.param('lobby')),
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m('.node-panel', [
|
||||
LobbyName(),
|
||||
m('.lobbies', m(SubscribedLeftLobbies), m(PublicLeftLobbies)),
|
||||
m('.messages', ChatLobbyModel.messages),
|
||||
@ -442,7 +445,7 @@ const LayoutSetup = () => {
|
||||
return {
|
||||
oninit: () => peopleUtil.ownIds((data) => (ownIds = data)),
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m('.node-panel', [
|
||||
LobbyName(),
|
||||
m('.lobbies', m(SubscribedLeftLobbies), m(PublicLeftLobbies)),
|
||||
m('.setup', [
|
||||
@ -475,7 +478,7 @@ const LayoutCreateDistant = () => {
|
||||
return {
|
||||
oninit: () => peopleUtil.ownIds((data) => (ownIds = data)),
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m('.node-panel', [
|
||||
m('.createDistantChat', [
|
||||
'choose identitiy to chat with ',
|
||||
rs.userList.username(m.route.param('lobby')),
|
||||
|
||||
@ -9,9 +9,8 @@ const SharedDirectories = () => {
|
||||
rs.rsJsonApiRequest('/rsFiles/getSharedDirectories', {}, (data) => (directories = data.dirs));
|
||||
},
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('h3', 'Shared Directories'),
|
||||
m('hr'),
|
||||
m('.widget__body-box', [
|
||||
m('.widget__heading', m('h3', 'Shared Directories')),
|
||||
directories.map((dir) =>
|
||||
m('input[type=text].stretched', {
|
||||
value: dir.filename,
|
||||
@ -33,9 +32,8 @@ const DownloadDirectory = () => {
|
||||
rs.rsJsonApiRequest('/rsFiles/getDownloadDirectory', {}, (data) => (dlDir = data.retval));
|
||||
},
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('h3', 'Downloads Directory'),
|
||||
m('hr'),
|
||||
m('.widget__body-box', [
|
||||
m('.widget__heading', m('h3', 'Downloads Directory')),
|
||||
m('input[type=text].stretched#dl-dir-input', {
|
||||
oninput: (e) => (dlDir = e.target.value),
|
||||
value: dlDir,
|
||||
@ -62,9 +60,8 @@ const PartialsDirectory = () => {
|
||||
(data) => (partialsDir = data.retval)
|
||||
),
|
||||
view: () =>
|
||||
m('.widget.widget-halfwidth', [
|
||||
m('h3', 'Partials Directory'),
|
||||
m('hr'),
|
||||
m('.widget__body-box', [
|
||||
m('.widget__heading', m('h3', 'Partials Directory')),
|
||||
m('input[type=text].stretched#partial-dir-input', {
|
||||
oninput: (e) => (partialsDir = e.target.value),
|
||||
value: partialsDir,
|
||||
@ -123,9 +120,8 @@ const TransferOptions = () => {
|
||||
);
|
||||
},
|
||||
view: () =>
|
||||
m('.widget.widget-half', [
|
||||
m('h3', 'Transfer options'),
|
||||
m('hr'),
|
||||
m('.widget__body-box', [
|
||||
m('.widget__heading', m('h3', 'Transfer options')),
|
||||
m('.grid-2col', [
|
||||
m('p', 'Maximum simultaneous downloads:'),
|
||||
m('input[type=number]', {
|
||||
@ -221,13 +217,17 @@ const TransferOptions = () => {
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: () => [
|
||||
m(SharedDirectories),
|
||||
m(DownloadDirectory),
|
||||
m(PartialsDirectory),
|
||||
m(TransferOptions),
|
||||
],
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('.widget__heading', m('h3', 'Files Configuration')),
|
||||
m('.widget__body.config-files', [
|
||||
m(SharedDirectories),
|
||||
m(DownloadDirectory),
|
||||
m(PartialsDirectory),
|
||||
m(TransferOptions),
|
||||
]),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Layout;
|
||||
module.exports = Layout;
|
||||
@ -76,111 +76,110 @@ const Mail = () => {
|
||||
);
|
||||
},
|
||||
view: () =>
|
||||
m('.widget.widget-half.mail', [
|
||||
m('.mail-tags__heading', m('h3', 'Distant Messages')),
|
||||
m('hr'),
|
||||
m('.permission-flag', [
|
||||
m('p', 'Accept encrypted distant messages from: '),
|
||||
m(
|
||||
'select[id=setDistantMessagingPermission]',
|
||||
{
|
||||
value: distantMessagingPermissionFlag,
|
||||
oninput: (e) => (distantMessagingPermissionFlag = e.target.value),
|
||||
onchange: () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/setDistantMessagingPermissionFlags', {
|
||||
flags: parseInt(distantMessagingPermissionFlag),
|
||||
});
|
||||
m('.widget.mail', [
|
||||
m('.widget__heading', m('h3', 'Mail Configuration')),
|
||||
m('.widget__body', [
|
||||
m('.permission-flag', [
|
||||
m('p', 'Accept encrypted distant messages from: '),
|
||||
m(
|
||||
'select',
|
||||
{
|
||||
value: distantMessagingPermissionFlag,
|
||||
oninput: (e) => (distantMessagingPermissionFlag = e.target.value),
|
||||
onchange: () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/setDistantMessagingPermissionFlags', {
|
||||
flags: parseInt(distantMessagingPermissionFlag),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
[
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_NONE,
|
||||
[
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_NONE,
|
||||
},
|
||||
'Everybody'
|
||||
),
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_NON_CONTACTS,
|
||||
},
|
||||
'Contacts'
|
||||
),
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_EVERYBODY,
|
||||
},
|
||||
'Nobody'
|
||||
),
|
||||
]
|
||||
),
|
||||
]),
|
||||
m('.widget__heading', [
|
||||
m('h3', 'Mail Tags'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
// set form fields to default values
|
||||
msgTagObj.tagName = '';
|
||||
msgTagObj.tagColor = '';
|
||||
widget.popupMessage(m(MessageTagForm));
|
||||
},
|
||||
'Everybody'
|
||||
),
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_NON_CONTACTS,
|
||||
},
|
||||
'Contacts'
|
||||
),
|
||||
m(
|
||||
'option',
|
||||
{
|
||||
value: util.RS_DISTANT_MESSAGING_PERMISSION_FLAG_FILTER_EVERYBODY,
|
||||
},
|
||||
'Nobody'
|
||||
),
|
||||
]
|
||||
),
|
||||
]),
|
||||
m('br'),
|
||||
m('.mail-tags__heading', [
|
||||
m('h3', 'Mail Tags'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
// set form fields to default values
|
||||
msgTagObj.tagName = '';
|
||||
msgTagObj.tagColor = '';
|
||||
widget.popupMessage(m(MessageTagForm));
|
||||
},
|
||||
},
|
||||
'Create New Tag'
|
||||
),
|
||||
]),
|
||||
m('hr'),
|
||||
m(
|
||||
'div.mail-tags',
|
||||
tagArr.length === 0
|
||||
? m('h4', 'No Message Tags')
|
||||
: m(
|
||||
'div.mail-tags__container',
|
||||
tagArr.map((tag) =>
|
||||
m('.tag-item', { key: tag.key }, [
|
||||
m('div.tag-item__color', {
|
||||
style: {
|
||||
backgroundColor: `#${tag.value.second.toString(16).padStart(6, '0')}`,
|
||||
},
|
||||
}),
|
||||
m('p.tag-item__name', tag.value.first),
|
||||
m('.tag-item__modify', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
msgTagObj.tagName = tag.value.first;
|
||||
msgTagObj.tagColor = `#${tag.value.second
|
||||
.toString(16)
|
||||
.padStart(6, '0')}`;
|
||||
widget.popupMessage(m(MessageTagForm, { tagItem: tag }));
|
||||
},
|
||||
'Create New Tag'
|
||||
),
|
||||
]),
|
||||
m(
|
||||
'.mail-tags',
|
||||
tagArr.length === 0
|
||||
? m('h4', 'No Message Tags')
|
||||
: m(
|
||||
'.mail-tags__container',
|
||||
tagArr.map((tag) =>
|
||||
m('.tag-item', { key: tag.key }, [
|
||||
m('.tag-item__color', {
|
||||
style: {
|
||||
backgroundColor: `#${tag.value.second.toString(16).padStart(6, '0')}`,
|
||||
},
|
||||
m('i.fas.fa-pen')
|
||||
),
|
||||
m(
|
||||
'button.red',
|
||||
{
|
||||
onclick: () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/removeMessageTagType', {
|
||||
tagId: tag.key,
|
||||
}).then((res) => {
|
||||
if (res.body.retval)
|
||||
tagArr = tagArr.filter((item) => item.key !== tag.key);
|
||||
});
|
||||
}),
|
||||
m('p.tag-item__name', tag.value.first),
|
||||
m('.tag-item__modify', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
msgTagObj.tagName = tag.value.first;
|
||||
msgTagObj.tagColor = `#${tag.value.second
|
||||
.toString(16)
|
||||
.padStart(6, '0')}`;
|
||||
widget.popupMessage(m(MessageTagForm, { tagItem: tag }));
|
||||
},
|
||||
},
|
||||
},
|
||||
m('i.fas.fa-trash')
|
||||
),
|
||||
]),
|
||||
])
|
||||
m('i.fas.fa-pen')
|
||||
),
|
||||
m(
|
||||
'button.red',
|
||||
{
|
||||
onclick: () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/removeMessageTagType', {
|
||||
tagId: tag.key,
|
||||
}).then((res) => {
|
||||
if (res.body.retval)
|
||||
tagArr = tagArr.filter((item) => item.key !== tag.key);
|
||||
});
|
||||
},
|
||||
},
|
||||
m('i.fas.fa-trash')
|
||||
),
|
||||
]),
|
||||
])
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
]),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
@ -332,7 +332,7 @@ const SetSocksProxy = () => {
|
||||
),
|
||||
Object.keys(socksProxyObj).map((proxyItem) => {
|
||||
return m(`.proxy-server__${proxyItem}`, [
|
||||
m('h4', `${proxyItem.toUpperCase()} Socks Proxy: `),
|
||||
m('h6', `${proxyItem.toUpperCase()} Socks Proxy: `),
|
||||
m('input[type=text]', {
|
||||
value: socksProxyObj[proxyItem].addr,
|
||||
oninput: (e) => (socksProxyObj[proxyItem].addr = e.target.value),
|
||||
@ -379,27 +379,24 @@ const Component = () => {
|
||||
}
|
||||
});
|
||||
},
|
||||
view: () => [
|
||||
m('.widget.widget-half', [
|
||||
m('h3', 'Network Configuration'),
|
||||
m('hr'),
|
||||
m('.grid-2col', [
|
||||
m(SetNwMode),
|
||||
m(SetNAT),
|
||||
m(displayLocalIPAddress, { details }),
|
||||
m(displayExternalIPAddress, { details }),
|
||||
m(SetDynamicDNS),
|
||||
m(SetLimits),
|
||||
m(SetOpMode),
|
||||
m(displayIPAddresses, { details }),
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('.widget__heading', m('h3', 'Network Configuration')),
|
||||
m('.widget__body', [
|
||||
m('.grid-2col', [
|
||||
m(SetNwMode),
|
||||
m(SetNAT),
|
||||
m(displayLocalIPAddress, { details }),
|
||||
m(displayExternalIPAddress, { details }),
|
||||
m(SetDynamicDNS),
|
||||
m(SetLimits),
|
||||
m(SetOpMode),
|
||||
m(displayIPAddresses, { details }),
|
||||
]),
|
||||
m('.widget__heading', m('h3', 'Hidden Service Configuration')),
|
||||
m('.widget__body', [m('.grid-2col', [m(SetSocksProxy)])]),
|
||||
]),
|
||||
]),
|
||||
m('.widget.widget-half', [
|
||||
m('h3', 'Hidden Service Configuration'),
|
||||
m('hr'),
|
||||
m('.grid-2col', [m(SetSocksProxy)]),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -13,17 +13,18 @@ const Node = () => {
|
||||
},
|
||||
view() {
|
||||
return [
|
||||
m('.widget.widget-half', [
|
||||
m('h3', 'Public Information'),
|
||||
m('hr'),
|
||||
m('ul', [
|
||||
m('li', 'Name: ' + nodeInfo.ownName),
|
||||
m('li', 'Location ID: ' + nodeInfo.ownId),
|
||||
m('li', 'Firewall: ' + nodeInfo.firewalled),
|
||||
m('li', 'Port Forwarding: ' + nodeInfo.forwardPort),
|
||||
m('li', 'DHT: ' + nodeInfo.DHTActive),
|
||||
m('li', 'uPnP: ' + nodeInfo.uPnPActive),
|
||||
m('li', 'Local Address: ' + nodeInfo.localAddr + ' Port: ' + nodeInfo.localPort),
|
||||
m('.widget', [
|
||||
m('.widget__heading', m('h3', 'Public Information')),
|
||||
m('.widget__body', [
|
||||
m('ul', [
|
||||
m('li', 'Name: ' + nodeInfo.ownName),
|
||||
m('li', 'Location ID: ' + nodeInfo.ownId),
|
||||
m('li', 'Firewall: ' + nodeInfo.firewalled),
|
||||
m('li', 'Port Forwarding: ' + nodeInfo.forwardPort),
|
||||
m('li', 'DHT: ' + nodeInfo.DHTActive),
|
||||
m('li', 'uPnP: ' + nodeInfo.uPnPActive),
|
||||
m('li', 'Local Address: ' + nodeInfo.localAddr + ' Port: ' + nodeInfo.localPort),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
];
|
||||
|
||||
@ -38,76 +38,77 @@ const Reputation = () => {
|
||||
},
|
||||
view: (vnode) =>
|
||||
m('.widget', [
|
||||
m('h3', 'Reputation'),
|
||||
m('hr'),
|
||||
m('.grid-2col', [
|
||||
m('p', 'Use "positive" as the default opinion for contacts(instead of neutral):'),
|
||||
m('input[type=checkbox]', {
|
||||
checked: usePositiveDefault,
|
||||
oninput: (e) => {
|
||||
usePositiveDefault = e.target.checked;
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setAutoPositiveOpinionForContacts',
|
||||
{
|
||||
b: usePositiveDefault,
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
}),
|
||||
m('p', 'Automatically add identities owned by friend nodes to my contacts:'),
|
||||
m('input[type=checkbox]', {
|
||||
checked: addFriendIdAsContacts,
|
||||
oninput: (e) => {
|
||||
addFriendIdAsContacts = e.target.checked;
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsIdentity/setAutoAddFriendIdsAsContact',
|
||||
{
|
||||
enabled: addFriendIdAsContacts,
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
}),
|
||||
m('p', 'Difference in votes (+/-) to rate an ID positively:'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (positiveThreshold = e.target.value),
|
||||
value: positiveThreshold,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setThresholdForRemotelyPositiveReputation',
|
||||
{
|
||||
thresh: positiveThreshold,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Difference in votes (+/-) to rate an ID negatively:'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (negativeThreshold = e.target.value),
|
||||
value: negativeThreshold,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setThresholdForRemotelyNegativeReputation',
|
||||
{
|
||||
thresh: negativeThreshold,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Delete banned identities after(in days, 0 means indefinitely):'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (deleteBannedAfter = e.target.value),
|
||||
value: deleteBannedAfter,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsIdentity/setDeleteBannedNodesThreshold',
|
||||
{
|
||||
days: deleteBannedAfter,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('.widget__heading', m('h3', 'Reputation')),
|
||||
m('.widget__body', [
|
||||
m('.grid-2col', [
|
||||
m('p', 'Use "positive" as the default opinion for contacts(instead of neutral):'),
|
||||
m('input[type=checkbox]', {
|
||||
checked: usePositiveDefault,
|
||||
oninput: (e) => {
|
||||
usePositiveDefault = e.target.checked;
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setAutoPositiveOpinionForContacts',
|
||||
{
|
||||
b: usePositiveDefault,
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
}),
|
||||
m('p', 'Automatically add identities owned by friend nodes to my contacts:'),
|
||||
m('input[type=checkbox]', {
|
||||
checked: addFriendIdAsContacts,
|
||||
oninput: (e) => {
|
||||
addFriendIdAsContacts = e.target.checked;
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsIdentity/setAutoAddFriendIdsAsContact',
|
||||
{
|
||||
enabled: addFriendIdAsContacts,
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
}),
|
||||
m('p', 'Difference in votes (+/-) to rate an ID positively:'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (positiveThreshold = e.target.value),
|
||||
value: positiveThreshold,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setThresholdForRemotelyPositiveReputation',
|
||||
{
|
||||
thresh: positiveThreshold,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Difference in votes (+/-) to rate an ID negatively:'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (negativeThreshold = e.target.value),
|
||||
value: negativeThreshold,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setThresholdForRemotelyNegativeReputation',
|
||||
{
|
||||
thresh: negativeThreshold,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Delete banned identities after(in days, 0 means indefinitely):'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (deleteBannedAfter = e.target.value),
|
||||
value: deleteBannedAfter,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsIdentity/setDeleteBannedNodesThreshold',
|
||||
{
|
||||
days: deleteBannedAfter,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
};
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
const m = require('mithril');
|
||||
const rs = require('rswebui');
|
||||
|
||||
const widget = require('widgets');
|
||||
|
||||
const sections = {
|
||||
@ -13,14 +11,13 @@ const sections = {
|
||||
};
|
||||
|
||||
const Layout = {
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/config/',
|
||||
}),
|
||||
m('.config-node-panel', vnode.children),
|
||||
]),
|
||||
view: (vnode) => [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/config/',
|
||||
}),
|
||||
m('.node-panel', vnode.children),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
@ -56,28 +56,28 @@ const MyServices = {
|
||||
},
|
||||
view() {
|
||||
return m('.widget', [
|
||||
m('h3', 'My Services'),
|
||||
m('hr'),
|
||||
m('table', [
|
||||
m('tr', [m('th', 'Name'), m('th', 'ID'), m('th', 'Version'), m('th', 'Allow by default')]),
|
||||
servicesInfo.list.map((data) =>
|
||||
m(Service, {
|
||||
data,
|
||||
})
|
||||
),
|
||||
m('.widget__heading', m('h3', 'My Services')),
|
||||
m('.widget__body', [
|
||||
m('table', [
|
||||
m('tr', [
|
||||
m('th', 'Name'),
|
||||
m('th', 'ID'),
|
||||
m('th', 'Version'),
|
||||
m('th', 'Allow by default'),
|
||||
]),
|
||||
servicesInfo.list.map((data) =>
|
||||
m(Service, {
|
||||
data,
|
||||
})
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (vnode) => [m(MyServices)],
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout);
|
||||
view: () => {
|
||||
return m(MyServices);
|
||||
},
|
||||
};
|
||||
|
||||
@ -4,17 +4,24 @@ const util = require('files/files_util');
|
||||
const widget = require('widgets');
|
||||
|
||||
const Downloads = {
|
||||
strategies: {},
|
||||
statusMap: {},
|
||||
hashes: [],
|
||||
|
||||
async loadHashes() {
|
||||
const res = await rs.rsJsonApiRequest(
|
||||
'/rsFiles/FileDownloads',
|
||||
{},
|
||||
(d) => (Downloads.hashes = d.hashs)
|
||||
loadStrategy() {
|
||||
rs.rsJsonApiRequest('/rsFiles/FileDownloads', {}, (d) =>
|
||||
d.hashs.map((hash) => {
|
||||
rs.rsJsonApiRequest('/rsFiles/getChunkStrategy', { hash }).then((res) => {
|
||||
if (res.body.retval) Downloads.strategies[hash] = res.body.s;
|
||||
});
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
async loadHashes() {
|
||||
await rs.rsJsonApiRequest('/rsFiles/FileDownloads', {}, (d) => (Downloads.hashes = d.hashs));
|
||||
},
|
||||
|
||||
async loadStatus() {
|
||||
await Downloads.loadHashes();
|
||||
const fileKeys = Object.keys(Downloads.statusMap);
|
||||
@ -132,38 +139,45 @@ const NewFileDialog = () => {
|
||||
const Component = () => {
|
||||
return {
|
||||
oninit: () => {
|
||||
Downloads.loadStrategy();
|
||||
rs.setBackgroundTask(Downloads.loadStatus, 1000, () => {
|
||||
return m.route.get() === '/files/files';
|
||||
});
|
||||
Downloads.resetSearch();
|
||||
},
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('h3', 'Downloads (' + Downloads.hashes.length + ' files)'),
|
||||
m('hr'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => widget.popupMessage(m(NewFileDialog)),
|
||||
},
|
||||
'Add new file'
|
||||
),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => rs.rsJsonApiRequest('/rsFiles/FileClearCompleted'),
|
||||
},
|
||||
'Clear completed'
|
||||
),
|
||||
Object.keys(Downloads.statusMap).map((hash) =>
|
||||
m(util.File, {
|
||||
info: Downloads.statusMap[hash],
|
||||
direction: 'down',
|
||||
transferred: Downloads.statusMap[hash].transfered.xint64,
|
||||
parts: [],
|
||||
})
|
||||
),
|
||||
view: () => [
|
||||
m('.widget__body-heading', [
|
||||
m('h3', 'Downloads (' + (Downloads.hashes && Downloads.hashes.length) + ' files)'),
|
||||
m('.action', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => widget.popupMessage(m(NewFileDialog)),
|
||||
},
|
||||
'Add new file'
|
||||
),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => rs.rsJsonApiRequest('/rsFiles/FileClearCompleted'),
|
||||
},
|
||||
'Clear completed'
|
||||
),
|
||||
]),
|
||||
]),
|
||||
m('.widget__body-content', [
|
||||
Downloads.statusMap &&
|
||||
Object.keys(Downloads.statusMap).map((hash) =>
|
||||
m(util.File, {
|
||||
info: Downloads.statusMap[hash],
|
||||
strategy: Downloads.strategies[hash],
|
||||
direction: 'down',
|
||||
transferred: Downloads.statusMap[hash].transfered.xint64,
|
||||
parts: [],
|
||||
})
|
||||
),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -11,12 +11,14 @@ const friendfile = require('files/friends_files');
|
||||
|
||||
const MyFiles = () => {
|
||||
return {
|
||||
view: (vnode) => [
|
||||
m(util.SearchBar, {
|
||||
list: Object.assign({}, downloads.list, uploads.list),
|
||||
}),
|
||||
m(downloads.Component),
|
||||
m(uploads.Component),
|
||||
view: () => [
|
||||
m('.widget__heading', [
|
||||
m('h3', 'File Transfers'),
|
||||
m(util.SearchBar, {
|
||||
list: Object.assign({}, downloads.list, uploads.list),
|
||||
}),
|
||||
]),
|
||||
m('.widget__body', [m(downloads.Component), m(uploads.Component)]),
|
||||
],
|
||||
};
|
||||
};
|
||||
@ -29,14 +31,13 @@ const sections = {
|
||||
};
|
||||
|
||||
const Layout = {
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/files/',
|
||||
}),
|
||||
m('.file-node-panel', vnode.children),
|
||||
]),
|
||||
view: (vnode) => [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/files/',
|
||||
}),
|
||||
m('.node-panel', m('.widget', vnode.children)),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
@ -4,13 +4,13 @@ const futil = require('files/files_util');
|
||||
const widget = require('widgets');
|
||||
|
||||
let matchString = '';
|
||||
const reqObj = {};
|
||||
let currentItem = 0;
|
||||
const reqObj = {};
|
||||
|
||||
async function handleSubmit() {
|
||||
await rs
|
||||
.rsJsonApiRequest('/rsFiles/turtleSearch', { matchString })
|
||||
function handleSubmit() {
|
||||
rs.rsJsonApiRequest('/rsFiles/turtleSearch', { matchString })
|
||||
.then((res) => {
|
||||
// Add prefix to obj keys so that javascript doesn't sort them
|
||||
reqObj['_' + res.body.retval] = matchString;
|
||||
currentItem = '_' + res.body.retval;
|
||||
})
|
||||
@ -21,16 +21,16 @@ const SearchBar = () => {
|
||||
return {
|
||||
view: () =>
|
||||
m(
|
||||
'form',
|
||||
'form.search-form',
|
||||
{
|
||||
onsubmit: handleSubmit,
|
||||
},
|
||||
[
|
||||
m('input[type=text][placeholder=search]', {
|
||||
m('input[type=text][placeholder=search keyword]', {
|
||||
value: matchString,
|
||||
oninput: (e) => (matchString = e.target.value),
|
||||
}),
|
||||
m('button[type=submit]', 'Submit'),
|
||||
m('button[type=submit]', m('i.fas.fa-search')),
|
||||
]
|
||||
),
|
||||
};
|
||||
@ -39,14 +39,12 @@ const SearchBar = () => {
|
||||
const Layout = () => {
|
||||
let active = 0;
|
||||
return {
|
||||
view: (vnode) =>
|
||||
m('.widget', [
|
||||
m('h3', 'Search'),
|
||||
m('hr'),
|
||||
m(SearchBar),
|
||||
view: () => [
|
||||
m('.widget__heading', [m('h3', 'Search'), m(SearchBar)]),
|
||||
m('.widget__body', [
|
||||
m('div.file-search-container', [
|
||||
m('div.file-search-container__keywords', [
|
||||
m('h4', 'Keywords'),
|
||||
m('h5.bold', 'Keywords'),
|
||||
m(
|
||||
'div.keywords-container',
|
||||
Object.keys(reqObj)
|
||||
@ -69,7 +67,7 @@ const Layout = () => {
|
||||
]),
|
||||
m('div.file-search-container__results', [
|
||||
Object.keys(futil.proxyObj).length === 0
|
||||
? m('h4', 'Results')
|
||||
? m('h5.bold', 'Results')
|
||||
: m('table.results-container', [
|
||||
m(
|
||||
'thead.results-header',
|
||||
@ -96,32 +94,28 @@ const Layout = () => {
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
try {
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsFiles/FileRequest',
|
||||
{
|
||||
fileName: item.fName,
|
||||
hash: item.fHash,
|
||||
flags: futil.RS_FILE_REQ_ANONYMOUS_ROUTING,
|
||||
size: {
|
||||
xstr64: item.fSize.xstr64,
|
||||
},
|
||||
},
|
||||
(status) => {
|
||||
status.retval
|
||||
? widget.popupMessage([
|
||||
m('i.fas.fa-file-medical'),
|
||||
m('h3', 'File is being downloaded!'),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('i.fas.fa-file-medical'),
|
||||
m('h3', 'File is already downloaded!'),
|
||||
]);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.log('error in sending download request: ', error);
|
||||
}
|
||||
rs.rsJsonApiRequest('/rsFiles/FileRequest', {
|
||||
fileName: item.fName,
|
||||
hash: item.fHash,
|
||||
flags: futil.RS_FILE_REQ_ANONYMOUS_ROUTING,
|
||||
size: {
|
||||
xstr64: item.fSize.xstr64,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
res.retval
|
||||
? widget.popupMessage([
|
||||
m('i.fas.fa-file-medical'),
|
||||
m('h3', 'File is being downloaded!'),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('i.fas.fa-file-medical'),
|
||||
m('h3', 'File is already downloaded!'),
|
||||
]);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('error in sending download request: ', error);
|
||||
});
|
||||
},
|
||||
},
|
||||
'Download'
|
||||
@ -134,6 +128,7 @@ const Layout = () => {
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -192,39 +192,30 @@ function actionButton(file, action) {
|
||||
const ProgressBar = () => {
|
||||
return {
|
||||
view: (v) =>
|
||||
m(
|
||||
'.progressbar',
|
||||
{
|
||||
m('.progressbar', [
|
||||
m('span.progressbar-status', {
|
||||
style: {
|
||||
content: v.attrs.rate + '%',
|
||||
width: v.attrs.rate + '%',
|
||||
},
|
||||
},
|
||||
m(
|
||||
'span.progress-status',
|
||||
{
|
||||
style: {
|
||||
width: v.attrs.rate + '%',
|
||||
},
|
||||
},
|
||||
v.attrs.rate.toPrecision(3) + '%'
|
||||
)
|
||||
),
|
||||
}),
|
||||
m('span.progressbar-percent', v.attrs.rate.toPrecision(3) + '%'),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
const chunkStrats = [
|
||||
'CHUNK_STRATEGY_STREAMING',
|
||||
'CHUNK_STRATEGY_RANDOM',
|
||||
'CHUNK_STRATEGY_PROGRESSIVE',
|
||||
];
|
||||
const chunkStratsOptions = ['Streaming', 'Random', 'Progressive'];
|
||||
const chunkStrats = {
|
||||
0: 'Streaming', // CHUNK_STRATEGY_STREAMING
|
||||
1: 'Random', // CHUNK_STRATEGY_RANDOM
|
||||
2: 'Progressive', // CHUNK_STRATEGY_PROGRESSIVE
|
||||
};
|
||||
// rstypes.h :: 366
|
||||
|
||||
const File = () => {
|
||||
let chunkStrat;
|
||||
return {
|
||||
view: (v) =>
|
||||
m(
|
||||
view: (v) => {
|
||||
chunkStrat = v.attrs && v.attrs.strategy;
|
||||
return m(
|
||||
'.file-view',
|
||||
{
|
||||
key: v.attrs.info.hash,
|
||||
@ -233,62 +224,80 @@ const File = () => {
|
||||
},
|
||||
},
|
||||
[
|
||||
m('p', v.attrs.info.fname),
|
||||
v.attrs.direction === 'up' || v.attrs.info.downloadStatus === FT_STATE_COMPLETE
|
||||
? []
|
||||
: [
|
||||
actionButton(v.attrs.info, 'cancel'),
|
||||
actionButton(
|
||||
v.attrs.info,
|
||||
v.attrs.info.downloadStatus === FT_STATE_PAUSED ? 'resume' : 'pause'
|
||||
),
|
||||
|
||||
m('.file-view__heading', [
|
||||
m('h6', v.attrs.info.fname),
|
||||
!(v.attrs.direction === 'up') && [
|
||||
m('.file-view__heading-chunk', [
|
||||
m('label[for=chunkTag]', 'Set Chunk Strategy: '),
|
||||
m(
|
||||
'select[id=chunkTag]',
|
||||
{
|
||||
value: chunkStrat,
|
||||
onchange: async (e) => {
|
||||
chunkStrat = chunkStrats[e.target.selectedIndex];
|
||||
const res = await rs.rsJsonApiRequest('/rsFiles/setChunkStrategy', {
|
||||
onchange: (e) => {
|
||||
chunkStrat = e.target.selectedIndex;
|
||||
rs.rsJsonApiRequest('/rsFiles/setChunkStrategy', {
|
||||
hash: v.attrs.info.hash,
|
||||
newStrategy: chunkStrat,
|
||||
});
|
||||
},
|
||||
},
|
||||
[chunkStratsOptions.map((opt) => m('option', { value: opt }, opt))]
|
||||
),
|
||||
m('label[for=chunkTag]', 'Set Chunk Strategy: '),
|
||||
],
|
||||
v.attrs.direction === 'up'
|
||||
? []
|
||||
: m(ProgressBar, {
|
||||
rate: (v.attrs.transferred / v.attrs.info.size.xint64) * 100,
|
||||
}),
|
||||
m('span.filestat', m('i.fas.fa-download'), makeFriendlyUnit(v.attrs.transferred)),
|
||||
|
||||
m('span.filestat', m('i.fas.fa-file'), makeFriendlyUnit(v.attrs.info.size.xint64)),
|
||||
m(
|
||||
'span.filestat',
|
||||
m('i.fas.fa-arrow-circle-' + v.attrs.direction),
|
||||
makeFriendlyUnit(v.attrs.info.tfRate * 1024) + '/s'
|
||||
),
|
||||
v.attrs.direction === 'up'
|
||||
? []
|
||||
: m('span.filestat', { title: 'time remaining' }, [
|
||||
m('i.fas.fa-clock'),
|
||||
calcRemainingTime(
|
||||
v.attrs.info.size.xint64 - v.attrs.transferred,
|
||||
v.attrs.info.tfRate
|
||||
[
|
||||
Object.keys(chunkStrats).map((opt) =>
|
||||
m('option', { value: opt }, chunkStrats[opt])
|
||||
),
|
||||
]
|
||||
),
|
||||
]),
|
||||
m(
|
||||
'span.filestat',
|
||||
{ title: 'peers' },
|
||||
[m('i.fas.fa-users'), v.attrs.info.peers.length],
|
||||
v.attrs.parts.reduce((a, e) => [...a, ' - ' + makeFriendlyUnit(e)], [])
|
||||
),
|
||||
],
|
||||
]),
|
||||
m('.file-view__body', [
|
||||
m(
|
||||
'.file-view__body-progress',
|
||||
!(v.attrs.direction === 'up') &&
|
||||
m(ProgressBar, {
|
||||
rate: (v.attrs.transferred / v.attrs.info.size.xint64) * 100,
|
||||
})
|
||||
),
|
||||
m('.file-view__body-details', [
|
||||
m('.file-view__body-details-stat', [
|
||||
m('span', m('i.fas.fa-download'), makeFriendlyUnit(v.attrs.transferred)),
|
||||
|
||||
m('span', m('i.fas.fa-file'), makeFriendlyUnit(v.attrs.info.size.xint64)),
|
||||
m(
|
||||
'span',
|
||||
m('i.fas.fa-arrow-circle-' + v.attrs.direction),
|
||||
makeFriendlyUnit(v.attrs.info.tfRate * 1024) + '/s'
|
||||
),
|
||||
!(v.attrs.direction === 'up') &&
|
||||
m('span', { title: 'time remaining' }, [
|
||||
m('i.fas.fa-clock'),
|
||||
calcRemainingTime(
|
||||
v.attrs.info.size.xint64 - v.attrs.transferred,
|
||||
v.attrs.info.tfRate
|
||||
),
|
||||
]),
|
||||
m(
|
||||
'span',
|
||||
{ title: 'peers' },
|
||||
[m('i.fas.fa-users'), v.attrs.info.peers.length],
|
||||
v.attrs.parts.reduce((a, e) => [...a, ' - ' + makeFriendlyUnit(e)], [])
|
||||
),
|
||||
]),
|
||||
m(
|
||||
'.file-view__body-details-action',
|
||||
!(v.attrs.info.downloadStatus === FT_STATE_COMPLETE) && [
|
||||
actionButton(
|
||||
v.attrs.info,
|
||||
v.attrs.info.downloadStatus === FT_STATE_PAUSED ? 'resume' : 'pause'
|
||||
),
|
||||
actionButton(v.attrs.info, 'cancel'),
|
||||
]
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -296,7 +305,7 @@ const SearchBar = () => {
|
||||
let searchString = '';
|
||||
return {
|
||||
view: (v) =>
|
||||
m('input[type=text][placeholder=SearchDownloads].searchbar', {
|
||||
m('input[type=text][placeholder=Search].searchbar', {
|
||||
value: searchString,
|
||||
oninput: (e) => {
|
||||
searchString = e.target.value.toLowerCase();
|
||||
|
||||
@ -145,15 +145,14 @@ const Layout = () => {
|
||||
// let root_handle;
|
||||
let parent;
|
||||
return {
|
||||
oninit: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsfiles/requestDirDetails', {
|
||||
oninit: () => {
|
||||
rs.rsJsonApiRequest('/rsfiles/requestDirDetails', {
|
||||
flags: util.RS_FILE_HINTS_REMOTE,
|
||||
});
|
||||
parent = res;
|
||||
}).then((res) => (parent = res));
|
||||
},
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Friends Files'),
|
||||
view: () => [
|
||||
m('.widget__heading', [m('h3', 'Friends Files')]),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.FriendsFilesTable,
|
||||
m(
|
||||
|
||||
@ -21,7 +21,8 @@ function displayfiles() {
|
||||
class: 'fa-rotate-' + (parStruct.showChild ? '90' : '0'),
|
||||
style: 'margin-top:12px',
|
||||
onclick: () => {
|
||||
if (!loaded) { // if it is not already retrieved
|
||||
if (!loaded) {
|
||||
// if it is not already retrieved
|
||||
parStruct.details.children.map(async (child) => {
|
||||
const res = await rs.rsJsonApiRequest('/rsfiles/requestDirDetails', {
|
||||
handle: child.handle.xint64,
|
||||
@ -43,7 +44,6 @@ function displayfiles() {
|
||||
position: 'relative',
|
||||
'--replyDepth': v.attrs.replyDepth,
|
||||
left: `calc(30px*${v.attrs.replyDepth})`,
|
||||
|
||||
},
|
||||
},
|
||||
parStruct.details.name
|
||||
@ -52,7 +52,8 @@ function displayfiles() {
|
||||
]),
|
||||
parStruct.showChild &&
|
||||
childrenList.map((child) =>
|
||||
m(displayfiles, { // recursive call
|
||||
m(displayfiles, {
|
||||
// recursive call
|
||||
par_directory: { details: child, showChild: false },
|
||||
replyDepth: v.attrs.replyDepth + 1,
|
||||
})
|
||||
@ -65,13 +66,12 @@ const Layout = () => {
|
||||
// let root_handle;
|
||||
let parent;
|
||||
return {
|
||||
oninit: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsfiles/requestDirDetails', {});
|
||||
parent = res;
|
||||
oninit: () => {
|
||||
rs.rsJsonApiRequest('/rsfiles/requestDirDetails', {}).then((res) => (parent = res));
|
||||
},
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'My Files'),
|
||||
view: () => [
|
||||
m('.widget__heading', [m('h3', 'My Files')]),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.MyFilesTable,
|
||||
m(
|
||||
|
||||
@ -123,7 +123,7 @@ const EditThread = () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsgxsforums/createPost', {
|
||||
forumId: vnode.attrs.forumId,
|
||||
mBody: body,
|
||||
title: title,
|
||||
title,
|
||||
authorId: vnode.attrs.authorId,
|
||||
parentId: vnode.attrs.current_parent,
|
||||
origPostId: vnode.attrs.current_msgid,
|
||||
@ -198,14 +198,14 @@ const AddThread = () => {
|
||||
? await rs.rsJsonApiRequest('/rsgxsforums/createPost', {
|
||||
forumId: vnode.attrs.forumId,
|
||||
mBody: body,
|
||||
title: title,
|
||||
title,
|
||||
authorId: identity,
|
||||
parentId: vnode.attrs.parentId,
|
||||
})
|
||||
: await rs.rsJsonApiRequest('/rsgxsforums/createPost', {
|
||||
forumId: vnode.attrs.forumId,
|
||||
mBody: body,
|
||||
title: title,
|
||||
title,
|
||||
authorId: identity,
|
||||
});
|
||||
|
||||
@ -479,126 +479,117 @@ const ForumView = () => {
|
||||
}
|
||||
});
|
||||
},
|
||||
view: (v) =>
|
||||
view: (v) => [
|
||||
m(
|
||||
'.widget',
|
||||
'a[title=Back]',
|
||||
{
|
||||
key: v.attrs.id,
|
||||
onclick: () =>
|
||||
m.route.set('/forums/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
[
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/forums/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
|
||||
m('h3', fname),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsgxsforums/subscribeToForum', {
|
||||
m('h3', fname),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsgxsforums/subscribeToForum', {
|
||||
forumId: v.attrs.id,
|
||||
subscribe: !fsubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
fsubscribed = !fsubscribed;
|
||||
util.Data.DisplayForums[v.attrs.id].isSubscribed = fsubscribed;
|
||||
}
|
||||
},
|
||||
},
|
||||
fsubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
m('[id=forumdetails]', [
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Date created: '),
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m('p', m('b', 'Admin: '), fauthor),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Last activity: '),
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
]),
|
||||
m('hr'),
|
||||
m('forumdesc', m('b', 'Description: '), util.Data.DisplayForums[v.attrs.id].description),
|
||||
m('hr'),
|
||||
m(
|
||||
'threaddetails',
|
||||
{
|
||||
style: 'display:' + (fsubscribed ? 'block' : 'none'),
|
||||
},
|
||||
m('h3', 'Threads'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
util.popupmessage(
|
||||
m(AddThread, {
|
||||
parent_thread: '',
|
||||
forumId: v.attrs.id,
|
||||
subscribe: !fsubscribed,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
fsubscribed = !fsubscribed;
|
||||
util.Data.DisplayForums[v.attrs.id].isSubscribed = fsubscribed;
|
||||
}
|
||||
},
|
||||
authorId: ownId,
|
||||
parentId: '',
|
||||
})
|
||||
);
|
||||
},
|
||||
fsubscribed ? 'Subscribed' : 'Subscribe'
|
||||
),
|
||||
m('[id=forumdetails]', [
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Date created: '),
|
||||
typeof createDate === 'object'
|
||||
? new Date(createDate.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m('p', m('b', 'Admin: '), fauthor),
|
||||
m(
|
||||
'p',
|
||||
m('b', 'Last activity: '),
|
||||
typeof lastActivity === 'object'
|
||||
? new Date(lastActivity.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
]),
|
||||
m('hr'),
|
||||
m('forumdesc', m('b', 'Description: '), util.Data.DisplayForums[v.attrs.id].description),
|
||||
m('hr'),
|
||||
},
|
||||
['New Thread', m('i.fas.fa-pencil-alt')]
|
||||
),
|
||||
m('hr'),
|
||||
m(
|
||||
util.ThreadsTable,
|
||||
m(
|
||||
'threaddetails',
|
||||
{
|
||||
style: 'display:' + (fsubscribed ? 'block' : 'none'),
|
||||
},
|
||||
m('h3', 'Threads'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
util.popupmessage(
|
||||
m(AddThread, {
|
||||
parent_thread: '',
|
||||
forumId: v.attrs.id,
|
||||
authorId: ownId,
|
||||
parentId: '',
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
['New Thread', m('i.fas.fa-pencil-alt')]
|
||||
),
|
||||
m('hr'),
|
||||
m(
|
||||
util.ThreadsTable,
|
||||
'tbody',
|
||||
Object.keys(topThreads).map((key, index) =>
|
||||
m(
|
||||
'tbody',
|
||||
Object.keys(topThreads).map((key, index) =>
|
||||
'tr',
|
||||
{
|
||||
style:
|
||||
topThreads[key].mMsgStatus === util.THREAD_UNREAD ? { fontWeight: 'bold' } : '',
|
||||
onclick: () => {
|
||||
m.route.set('/forums/:tab/:mGroupId/:mMsgId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: v.attrs.id,
|
||||
mMsgId: topThreads[key].mOrigMsgId,
|
||||
});
|
||||
},
|
||||
},
|
||||
[
|
||||
m('td', topThreads[key].mMsgName),
|
||||
m(
|
||||
'tr',
|
||||
{
|
||||
style:
|
||||
topThreads[key].mMsgStatus === util.THREAD_UNREAD
|
||||
? { fontWeight: 'bold' }
|
||||
: '',
|
||||
onclick: () => {
|
||||
m.route.set('/forums/:tab/:mGroupId/:mMsgId', {
|
||||
tab: m.route.param().tab,
|
||||
mGroupId: v.attrs.id,
|
||||
mMsgId: topThreads[key].mOrigMsgId,
|
||||
});
|
||||
},
|
||||
},
|
||||
[
|
||||
m('td', topThreads[key].mMsgName),
|
||||
m(
|
||||
'td',
|
||||
typeof topThreads[key].mPublishTs === 'object'
|
||||
? new Date(topThreads[key].mPublishTs.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m(
|
||||
'td',
|
||||
rs.userList.userMap[topThreads[key].mAuthorId]
|
||||
? rs.userList.userMap[topThreads[key].mAuthorId]
|
||||
: 'Unknown'
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
'td',
|
||||
typeof topThreads[key].mPublishTs === 'object'
|
||||
? new Date(topThreads[key].mPublishTs.xint64 * 1000).toLocaleString()
|
||||
: 'undefined'
|
||||
),
|
||||
m(
|
||||
'td',
|
||||
rs.userList.userMap[topThreads[key].mAuthorId]
|
||||
? rs.userList.userMap[topThreads[key].mAuthorId]
|
||||
: 'Unknown'
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -50,51 +50,49 @@ const Layout = () => {
|
||||
});
|
||||
},
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m(util.SearchBar, {
|
||||
list: getForums.All,
|
||||
}),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
style: { fontSize: '1.2em', width: '200px' },
|
||||
onclick: () =>
|
||||
util.popupmessage(
|
||||
m(viewUtil.createforum, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Forum'
|
||||
),
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/forums/',
|
||||
}),
|
||||
m(
|
||||
'.forums-node-panel',
|
||||
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId') // thread's view
|
||||
? m(viewUtil.ThreadView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
forumId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId') // Forum's view
|
||||
? m(viewUtil.ForumView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
list: getForums[vnode.attrs.pathInfo.tab],
|
||||
})
|
||||
),
|
||||
m('.widget', [
|
||||
m('.top-heading', [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () =>
|
||||
ownId &&
|
||||
util.popupmessage(
|
||||
m(viewUtil.createforum, {
|
||||
authorId: ownId,
|
||||
})
|
||||
),
|
||||
},
|
||||
'Create Forum'
|
||||
),
|
||||
m(util.SearchBar, {
|
||||
list: getForums.All,
|
||||
}),
|
||||
]),
|
||||
Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mMsgId') // thread's view
|
||||
? m(viewUtil.ThreadView, {
|
||||
msgId: vnode.attrs.pathInfo.mMsgId,
|
||||
forumId: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: Object.prototype.hasOwnProperty.call(vnode.attrs.pathInfo, 'mGroupId') // Forum's view
|
||||
? m(viewUtil.ForumView, {
|
||||
id: vnode.attrs.pathInfo.mGroupId,
|
||||
})
|
||||
: m(sections[vnode.attrs.pathInfo.tab], {
|
||||
list: getForums[vnode.attrs.pathInfo.tab],
|
||||
}),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout, {
|
||||
pathInfo: vnode.attrs,
|
||||
});
|
||||
return [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/forums/',
|
||||
}),
|
||||
m('.node-panel', m(Layout, { pathInfo: vnode.attrs })),
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@ -86,7 +86,6 @@ async function updatedisplayforums(keyid, details = {}) {
|
||||
|
||||
const DisplayForumsFromList = () => {
|
||||
return {
|
||||
oninit: (v) => {},
|
||||
view: (v) =>
|
||||
m(
|
||||
'tr',
|
||||
@ -115,7 +114,6 @@ const ForumSummary = () => {
|
||||
keyid = v.attrs.details.mGroupId;
|
||||
updatedisplayforums(keyid);
|
||||
},
|
||||
|
||||
view: (v) => {},
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('forums/forums_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'My Forums'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'My Forums')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ForumTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -2,7 +2,7 @@ const m = require('mithril');
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: () => [m('.widget', [m('h2', 'Other Forums'), m('hr')])],
|
||||
view: () => [m('.widget__heading', m('h3', 'Other Forums'))],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('forums/forums_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Popular Forums'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Popular Forums')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ForumTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('forums/forums_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Subscribed Forums'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Subscribed Forums')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.ForumTable,
|
||||
m('tbody', [
|
||||
|
||||
@ -2,45 +2,18 @@ const m = require('mithril');
|
||||
const rs = require('rswebui');
|
||||
const widget = require('widgets');
|
||||
|
||||
const retrosemitext = () => {
|
||||
return {
|
||||
view() {
|
||||
return m(
|
||||
'.retrotext',
|
||||
{
|
||||
style: 'font-weight:500;font-size:2.4rem',
|
||||
},
|
||||
[
|
||||
m(
|
||||
'span',
|
||||
{
|
||||
style: 'color: #3ba4d7',
|
||||
},
|
||||
'RETRO'
|
||||
),
|
||||
'SHARE',
|
||||
]
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
const retroshareText = () => {
|
||||
return {
|
||||
view() {
|
||||
return m('.retroshareText', [m(retrosemitext), m('b', 'secure connection for everyone')]);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const logo = () => {
|
||||
return {
|
||||
view() {
|
||||
return m('.logo', [
|
||||
m('img.logo[width=20%][height=10%]', {
|
||||
m('img', {
|
||||
src: '../data/retroshare.svg',
|
||||
alt: 'retroshare_icon',
|
||||
}),
|
||||
m(retroshareText),
|
||||
m('.retroshareText', [
|
||||
m('.retrotext', [m('span', 'RETRO'), 'SHARE']),
|
||||
m('b', 'secure communication for everyone'),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
@ -77,23 +50,18 @@ const webhelp = () => {
|
||||
widget.popupMessage(m(webhelpConfirm));
|
||||
},
|
||||
},
|
||||
[
|
||||
m('i.fas .fa-globe-europe', { style: 'color:green' }),
|
||||
m('p', { style: 'border-width:1px' }, 'Open Web Help'),
|
||||
]
|
||||
[m('i.fas.fa-globe-europe'), m('p', 'Open Web Help')]
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const ConfirmCopied = () => {
|
||||
return {
|
||||
view: () => [
|
||||
m('h3', 'Copied to Clipboard'),
|
||||
m('hr'),
|
||||
m(
|
||||
'p[style="margin: 12px 0 4px"]',
|
||||
'Your Retroshare ID has been copied to Clipboard.'
|
||||
),
|
||||
m('p[style="margin: 12px 0 4px"]', 'Your Retroshare ID has been copied to Clipboard.'),
|
||||
m(
|
||||
'p[style="margin: 4px 0 12px"]',
|
||||
'Now, you can paste and send it to your friend via email or some other way.'
|
||||
@ -107,17 +75,8 @@ const retroshareId = () => {
|
||||
return {
|
||||
view(v) {
|
||||
return m('.retroshareID', [
|
||||
m('i.fas .fa-copy', {
|
||||
style: 'color: #3ba4d7; margin-right: 3px; cursor: pointer',
|
||||
onclick: () => {
|
||||
document.getElementById('retroId').select();
|
||||
document.execCommand('copy');
|
||||
widget.popupMessage(m(ConfirmCopied));
|
||||
},
|
||||
}),
|
||||
|
||||
m(
|
||||
'textarea[readonly] .textArea',
|
||||
'textarea[readonly].textArea',
|
||||
{
|
||||
id: 'retroId',
|
||||
rows: 1,
|
||||
@ -129,78 +88,14 @@ const retroshareId = () => {
|
||||
},
|
||||
v.attrs.ownCert.substring(31)
|
||||
),
|
||||
m('i.fas .fa-share-alt', { style: 'color: #3ba4d7' }),
|
||||
]);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const Certificate = () => {
|
||||
let ownCert = '';
|
||||
function loadOwnCert() {
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsPeers/GetShortInvite',
|
||||
{ formatRadix: true },
|
||||
(data) => (ownCert = data.invite)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
oninit() {
|
||||
// Load long cert by default
|
||||
loadOwnCert();
|
||||
},
|
||||
|
||||
view() {
|
||||
return m('.certificate ', [
|
||||
m(logo),
|
||||
m(
|
||||
'p',
|
||||
{
|
||||
style: 'margin-top:25px;font-size:1.1rem;font-weight:500;',
|
||||
m('i.fas.fa-copy', {
|
||||
onclick: () => {
|
||||
document.getElementById('retroId').select();
|
||||
document.execCommand('copy');
|
||||
widget.popupMessage(m(ConfirmCopied));
|
||||
},
|
||||
'Open Source cross-platform,'
|
||||
),
|
||||
m(
|
||||
'p',
|
||||
{
|
||||
style: 'margin:0;padding:0; margin-top:5px;font-size:1.1rem;',
|
||||
},
|
||||
'private and secure decentralized communication platform'
|
||||
),
|
||||
m(
|
||||
'p',
|
||||
{
|
||||
style: 'margin-top:80px;color: #3ba4d7;font-size:1.1rem;font-weight:600;',
|
||||
},
|
||||
'This is your Retroshare ID. Copy and share with your friends!'
|
||||
),
|
||||
m(retroshareId, { ownCert }),
|
||||
m(
|
||||
'p',
|
||||
{
|
||||
style: 'margin-bottom:5px;margin-top:40px;font-size:1.1rem',
|
||||
},
|
||||
'Did you receive a Retroshare ID from your friend ?'
|
||||
),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
widget.popupMessage(m(AddFriend));
|
||||
},
|
||||
},
|
||||
'Add Friend'
|
||||
),
|
||||
m(
|
||||
'p',
|
||||
{
|
||||
style: 'margin-bottom:5px;margin-top:40px;font-size:1.1rem',
|
||||
},
|
||||
'Do you need help with Retoshare ?'
|
||||
),
|
||||
|
||||
m(webhelp),
|
||||
}),
|
||||
m('i.fas.fa-share-alt'),
|
||||
]);
|
||||
},
|
||||
};
|
||||
@ -224,52 +119,52 @@ function confirmAddPrompt(details, cert, long) {
|
||||
|
||||
long
|
||||
? m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsPeers/loadCertificateFromString', { cert });
|
||||
if (res.body.retval) {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Successful'),
|
||||
m('hr'),
|
||||
m('p', 'Successfully added friend.'),
|
||||
]);
|
||||
} else {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', 'An error occoured during adding. Friend not added.'),
|
||||
]);
|
||||
}
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsPeers/loadCertificateFromString', { cert });
|
||||
if (res.body.retval) {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Successful'),
|
||||
m('hr'),
|
||||
m('p', 'Successfully added friend.'),
|
||||
]);
|
||||
} else {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', 'An error occoured during adding. Friend not added.'),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'Finish'
|
||||
)
|
||||
'Finish'
|
||||
)
|
||||
: m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsPeers/addSslOnlyFriend', {
|
||||
sslId: details.id,
|
||||
pgpId: details.gpg_id,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Successful'),
|
||||
m('hr'),
|
||||
m('p', 'Successfully added friend.'),
|
||||
]);
|
||||
} else {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', 'An error occoured during adding. Friend not added.'),
|
||||
]);
|
||||
}
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
const res = await rs.rsJsonApiRequest('/rsPeers/addSslOnlyFriend', {
|
||||
sslId: details.id,
|
||||
pgpId: details.gpg_id,
|
||||
});
|
||||
if (res.body.retval) {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Successful'),
|
||||
m('hr'),
|
||||
m('p', 'Successfully added friend.'),
|
||||
]);
|
||||
} else {
|
||||
widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', 'An error occoured during adding. Friend not added.'),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'Finish'
|
||||
),
|
||||
'Finish'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -311,10 +206,7 @@ const AddFriend = () => {
|
||||
view: (vnode) =>
|
||||
m('.widget', [
|
||||
m('h3', 'Add friend'),
|
||||
m(
|
||||
'p',
|
||||
'Did you recieve a certificate from a friend?'
|
||||
),
|
||||
m('h5', 'Did you recieve a certificate from a friend?'),
|
||||
m('hr'),
|
||||
m(
|
||||
'.cert-drop-zone',
|
||||
@ -324,11 +216,7 @@ const AddFriend = () => {
|
||||
ondragexit: () => (vnode.state.isDragged = false),
|
||||
|
||||
// Styling element when file is dragged
|
||||
style: vnode.state.isDragged
|
||||
? {
|
||||
border: '5px solid #3ba4d7',
|
||||
}
|
||||
: {},
|
||||
style: { border: vnode.state.isDragged && '5px solid #3ba4d7' },
|
||||
|
||||
ondragover: (e) => e.preventDefault(),
|
||||
ondrop: (e) => {
|
||||
@ -339,7 +227,10 @@ const AddFriend = () => {
|
||||
},
|
||||
|
||||
[
|
||||
m('p[style="margin: 16px 0 4px; font-size: 12px;"]', 'You can directly upload or Drag and drop the file below'),
|
||||
m(
|
||||
'p[style="margin: 16px 0 4px"]',
|
||||
'You can directly upload or Drag and drop the file below'
|
||||
),
|
||||
m('input[type=file][name=certificate]', {
|
||||
onchange: (e) => {
|
||||
// Note: this one is for the 'browse' button
|
||||
@ -347,10 +238,13 @@ const AddFriend = () => {
|
||||
},
|
||||
}),
|
||||
m('p[style="width: 100%; text-align: center; margin: 5px 0;"]', 'OR'),
|
||||
m('textarea[rows=5][placeholder="Paste the certificate here"][style="width: 100%; display: block; resize: vertical;"]', {
|
||||
oninput: (e) => (certificate = e.target.value),
|
||||
value: certificate,
|
||||
}),
|
||||
m(
|
||||
'textarea[rows=5][placeholder="Paste the certificate here"][style="width: 100%; display: block; resize: vertical;"]',
|
||||
{
|
||||
oninput: (e) => (certificate = e.target.value),
|
||||
value: certificate,
|
||||
}
|
||||
),
|
||||
m(
|
||||
'button[style="margin-top: 10px;"]',
|
||||
{
|
||||
@ -364,9 +258,60 @@ const AddFriend = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const Certificate = () => {
|
||||
let ownCert = '';
|
||||
function loadOwnCert() {
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsPeers/GetShortInvite',
|
||||
{ formatRadix: true },
|
||||
(data) => (ownCert = data.invite)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
oninit() {
|
||||
// Load long cert by default
|
||||
loadOwnCert();
|
||||
},
|
||||
|
||||
view() {
|
||||
return m('.homepage ', [
|
||||
m(logo),
|
||||
m('.certificate', [
|
||||
m('.certificate__heading', [
|
||||
m('h1', 'Welcome to Web Interface of Retroshare!'),
|
||||
'Retroshare is an Open Source Cross-platform,',
|
||||
m('br'),
|
||||
'Private and Secure Decentralized Communication Platform.',
|
||||
]),
|
||||
m('.certificate__content', [
|
||||
m('.rsId', [
|
||||
m('p', 'This is your Retroshare ID. Copy and share with your friends!'),
|
||||
m(retroshareId, { ownCert }),
|
||||
]),
|
||||
m('.add-friend', [
|
||||
m('h6', 'Did you receive a Retroshare ID from your friend ?'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => {
|
||||
widget.popupMessage(m(AddFriend));
|
||||
},
|
||||
},
|
||||
'Add Friend'
|
||||
),
|
||||
]),
|
||||
m('.webhelp-container', [m('h6', 'Do you need help with Retoshare ?'), m(webhelp)]),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: () => m('.tab-page ', [m(Certificate)]),
|
||||
view: () => m(Certificate),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -20,29 +20,28 @@ const Layout = () => {
|
||||
});
|
||||
},
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('div.msg-attachment-container', [
|
||||
m('h3', 'Attachments'),
|
||||
m('.view-toggle', [
|
||||
m(
|
||||
'.mail-view',
|
||||
{
|
||||
onclick: () => (viewChanged = false),
|
||||
style: { backgroundColor: viewChanged ? '#fff' : '#019DFF' },
|
||||
},
|
||||
m('i.fas.fa-mail-bulk')
|
||||
),
|
||||
m(
|
||||
'.attachment-view',
|
||||
{
|
||||
onclick: () => (viewChanged = true),
|
||||
style: { backgroundColor: viewChanged ? '#019DFF' : '#fff' },
|
||||
},
|
||||
m('i.fas.fa-file')
|
||||
),
|
||||
]),
|
||||
m('.widget__heading', [
|
||||
m('h3', 'Attachments'),
|
||||
m('.view-toggle', [
|
||||
m(
|
||||
'.mail-view',
|
||||
{
|
||||
onclick: () => (viewChanged = false),
|
||||
style: { backgroundColor: viewChanged ? '#fff' : '#019DFF' },
|
||||
},
|
||||
m('i.fas.fa-mail-bulk')
|
||||
),
|
||||
m(
|
||||
'.attachment-view',
|
||||
{
|
||||
onclick: () => (viewChanged = true),
|
||||
style: { backgroundColor: viewChanged ? '#019DFF' : '#fff' },
|
||||
},
|
||||
m('i.fas.fa-file')
|
||||
),
|
||||
]),
|
||||
m('hr'),
|
||||
]),
|
||||
m('.widget__body', [
|
||||
viewChanged
|
||||
? m(util.AttachmentSection, {
|
||||
files,
|
||||
|
||||
@ -5,9 +5,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Drafts'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Draft')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Important'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Important')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Inbox'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Inbox')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Later'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Later')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Outbox'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Outbox')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Personal'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Personal')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
const m = require('mithril');
|
||||
const rs = require('rswebui');
|
||||
const util = require('mail/mail_util');
|
||||
const widget = require('widgets');
|
||||
const peopleUtil = require('people/people_util');
|
||||
const compose = require('mail/mail_compose');
|
||||
|
||||
@ -116,9 +115,9 @@ const Layout = {
|
||||
};
|
||||
|
||||
return [
|
||||
m('.tab-page', [
|
||||
m('.side-bar', [
|
||||
m(
|
||||
'button[id=composebtn]',
|
||||
'button.mail-compose-btn',
|
||||
{
|
||||
onclick: () =>
|
||||
composeData.allUsers &&
|
||||
@ -129,19 +128,6 @@ const Layout = {
|
||||
},
|
||||
'Compose'
|
||||
),
|
||||
m(
|
||||
'select[id=tags]',
|
||||
{
|
||||
value: tagselect.showval,
|
||||
onchange: (e) => {
|
||||
tagselect.showval = tagselect.opts[e.target.selectedIndex];
|
||||
},
|
||||
},
|
||||
[tagselect.opts.map((o) => m('option', { value: o }, o.toLocaleString()))]
|
||||
),
|
||||
m(util.SearchBar, {
|
||||
list: {},
|
||||
}),
|
||||
m(util.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
size: sectionsSize,
|
||||
@ -152,8 +138,28 @@ const Layout = {
|
||||
size: sectionsquickviewSize,
|
||||
baseRoute: '/mail/',
|
||||
}),
|
||||
m('.mail-node-panel', vnode.children),
|
||||
]),
|
||||
m(
|
||||
'.node-panel',
|
||||
m('.widget', [
|
||||
m('.top-heading', [
|
||||
m(
|
||||
'select.mail-tag',
|
||||
{
|
||||
value: tagselect.showval,
|
||||
onchange: (e) => {
|
||||
tagselect.showval = tagselect.opts[e.target.selectedIndex];
|
||||
},
|
||||
},
|
||||
[tagselect.opts.map((o) => m('option', { value: o }, o.toLocaleString()))]
|
||||
),
|
||||
m(util.SearchBar, {
|
||||
list: {},
|
||||
}),
|
||||
]),
|
||||
vnode.children,
|
||||
])
|
||||
),
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@ -5,9 +5,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Sent'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Sent')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Spam'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Spam')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Starred'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Starred')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'System'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'System')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Todo'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Todo')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Trash'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Trash')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -237,145 +237,163 @@ const MessageView = () => {
|
||||
(data) => (details = { ...details, avatar: data.details.mAvatar })
|
||||
);
|
||||
},
|
||||
view: (v) =>
|
||||
view: () =>
|
||||
m(
|
||||
'.widget.msgview',
|
||||
'.msg-view',
|
||||
{
|
||||
key: details.msgId,
|
||||
},
|
||||
[
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/mail/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('h3', details.title),
|
||||
m('.msgHeader', [
|
||||
details.from &&
|
||||
m(peopleUtil.UserAvatar, {
|
||||
avatar: details.avatar,
|
||||
firstLetter: rs.userList.userMap[details.from._addr_string]
|
||||
? rs.userList.userMap[details.from._addr_string].slice(0, 1).toUpperCase()
|
||||
: '',
|
||||
}),
|
||||
m('.msgHeaderDetails', [
|
||||
details.from &&
|
||||
m('from', { style: { display: 'block ruby' } }, [
|
||||
m('p', { style: { fontWeight: 'bold' } }, 'From: '),
|
||||
rs.userList.userMap[details.from._addr_string],
|
||||
]),
|
||||
toList &&
|
||||
Object.keys(toList).length > 0 &&
|
||||
// TODO: optimize javascript for show-more and show-less working
|
||||
m('to', { style: { display: 'block ruby' } }, [
|
||||
m('p', { style: { fontWeight: 'bold' } }, 'To: '),
|
||||
m(
|
||||
'div.truncate[id=truncate]',
|
||||
Object.keys(toList).map((key, index) => m('p', rs.userList.userMap[key] + ', '))
|
||||
),
|
||||
m(
|
||||
'button[id=show-more]',
|
||||
{
|
||||
style: {
|
||||
display: Object.keys(toList).length > 10 ? 'block' : 'none',
|
||||
},
|
||||
onclick: () => {
|
||||
document.querySelector('#show-more').style.display = 'none';
|
||||
document.querySelector('#truncate').style.height = 'max-content';
|
||||
document.querySelector('#show-less').style.display = 'block';
|
||||
},
|
||||
},
|
||||
'Show More'
|
||||
),
|
||||
m(
|
||||
'button[id=show-less][style="display: none;"]',
|
||||
{
|
||||
onclick: () => {
|
||||
document.querySelector('#show-more').style.display = 'block';
|
||||
document.querySelector('#truncate').style.height = '22px';
|
||||
document.querySelector('#show-less').style.display = 'none';
|
||||
},
|
||||
},
|
||||
'Show Less'
|
||||
),
|
||||
]),
|
||||
ccList &&
|
||||
Object.keys(ccList).length > 0 &&
|
||||
m('cc', { style: { display: 'block ruby' } }, [
|
||||
m('p', { style: { fontWeight: 'bold' } }, 'CC: '),
|
||||
Object.keys(ccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')),
|
||||
]),
|
||||
bccList &&
|
||||
Object.keys(bccList).length > 0 &&
|
||||
m('bcc', { style: { display: 'block ruby' } }, [
|
||||
m('p', { style: { fontWeight: 'bold' } }, 'BCC: '),
|
||||
Object.keys(bccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')),
|
||||
]),
|
||||
m('.msg-view-nav', [
|
||||
m(
|
||||
'a[title=Back]',
|
||||
{
|
||||
onclick: () =>
|
||||
m.route.set('/mail/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
}),
|
||||
},
|
||||
m('i.fas.fa-arrow-left')
|
||||
),
|
||||
m('.msg-view-nav__action', [
|
||||
m('button', 'Reply'),
|
||||
m('button', 'Reply All'),
|
||||
m('button', 'Forward'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () =>
|
||||
widget.popupMessage([
|
||||
m('p', 'Are you sure you want to delete this mail?'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/MessageToTrash', {
|
||||
msgId: details.msgId,
|
||||
bTrash: true,
|
||||
});
|
||||
const res = await rs.rsJsonApiRequest('/rsMsgs/MessageDelete', {
|
||||
msgId: details.msgId,
|
||||
});
|
||||
res.body.retval
|
||||
? widget.popupMessage([
|
||||
m('h3', 'Success'),
|
||||
m('hr'),
|
||||
m('p', 'Mail Deleted.'),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', res.body.errorMessage),
|
||||
]);
|
||||
m.redraw();
|
||||
m.route.set('/mail/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
});
|
||||
},
|
||||
},
|
||||
'Delete'
|
||||
),
|
||||
]),
|
||||
},
|
||||
'Delete'
|
||||
),
|
||||
]),
|
||||
]),
|
||||
m('button', 'Reply'),
|
||||
m('button', 'Reply All'),
|
||||
m('button', 'Forward'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () =>
|
||||
widget.popupMessage([
|
||||
m('p', 'Are you sure you want to delete this mail?'),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: async () => {
|
||||
rs.rsJsonApiRequest('/rsMsgs/MessageToTrash', {
|
||||
msgId: details.msgId,
|
||||
bTrash: true,
|
||||
});
|
||||
const res = await rs.rsJsonApiRequest('/rsMsgs/MessageDelete', {
|
||||
msgId: details.msgId,
|
||||
});
|
||||
res.body.retval
|
||||
? widget.popupMessage([
|
||||
m('h3', 'Success'),
|
||||
m('hr'),
|
||||
m('p', 'Mail Deleted.'),
|
||||
])
|
||||
: widget.popupMessage([
|
||||
m('h3', 'Error'),
|
||||
m('hr'),
|
||||
m('p', res.body.errorMessage),
|
||||
]);
|
||||
m.redraw();
|
||||
m.route.set('/mail/:tab', {
|
||||
tab: m.route.param().tab,
|
||||
});
|
||||
m('.msg-view__header', [
|
||||
m('h3', details.title),
|
||||
m('.msg-details', [
|
||||
details.from &&
|
||||
m(peopleUtil.UserAvatar, {
|
||||
avatar: details.avatar,
|
||||
firstLetter: rs.userList.userMap[details.from._addr_string]
|
||||
? rs.userList.userMap[details.from._addr_string].slice(0, 1).toUpperCase()
|
||||
: '',
|
||||
}),
|
||||
m('.msg-details__info', [
|
||||
details.from &&
|
||||
m('.msg-details__info-item', [
|
||||
m('b', 'From: '),
|
||||
rs.userList.userMap[details.from._addr_string] || 'Unknown',
|
||||
]),
|
||||
toList &&
|
||||
Object.keys(toList).length > 0 &&
|
||||
// TODO: optimize javascript for show-more and show-less working
|
||||
m('.msg-details__info-item', [
|
||||
m('b', 'To: '),
|
||||
m(
|
||||
'#truncate',
|
||||
Object.keys(toList).map((key, index) =>
|
||||
m('span', `${rs.userList.userMap[key]}, `)
|
||||
)
|
||||
),
|
||||
m(
|
||||
'button[id=show-more]',
|
||||
{
|
||||
style: {
|
||||
display: Object.keys(toList).length > 10 ? 'block' : 'none',
|
||||
},
|
||||
onclick: () => {
|
||||
document.querySelector('#show-more').style.display = 'none';
|
||||
document.querySelector('#truncate').style.height = '6rem';
|
||||
document.querySelector('#truncate').style.overflow = 'auto';
|
||||
document.querySelector('#show-less').style.display = 'block';
|
||||
},
|
||||
},
|
||||
},
|
||||
'Delete'
|
||||
),
|
||||
]),
|
||||
},
|
||||
'Delete'
|
||||
),
|
||||
m('hr'),
|
||||
'...'
|
||||
),
|
||||
m(
|
||||
'button[id=show-less][style="display: none;"]',
|
||||
{
|
||||
onclick: () => {
|
||||
document.querySelector('#show-more').style.display = 'block';
|
||||
document.querySelector('#truncate').style.height = '1.75rem';
|
||||
document.querySelector('#truncate').style.overflow = 'hidden';
|
||||
document.querySelector('#show-less').style.display = 'none';
|
||||
},
|
||||
},
|
||||
'less'
|
||||
),
|
||||
]),
|
||||
ccList &&
|
||||
Object.keys(ccList).length > 0 &&
|
||||
m('.msg-details__info-item', [
|
||||
m('b', 'CC: '),
|
||||
Object.keys(ccList).map((key, index) =>
|
||||
m('p', `${rs.userList.userMap[key]}, `)
|
||||
),
|
||||
]),
|
||||
bccList &&
|
||||
Object.keys(bccList).length > 0 &&
|
||||
m('.msg-details__info-item', [
|
||||
m('b', 'BCC: '),
|
||||
Object.keys(bccList).map((key, index) =>
|
||||
m('p', `${rs.userList.userMap[key]}, `)
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
m(
|
||||
'iframe[title=message].msg',
|
||||
{
|
||||
srcdoc: message,
|
||||
},
|
||||
message
|
||||
'.msg-view__body',
|
||||
m(
|
||||
'iframe[title=message]',
|
||||
{
|
||||
srcdoc: message,
|
||||
},
|
||||
message
|
||||
)
|
||||
),
|
||||
files.length > 0 && [
|
||||
m('hr'),
|
||||
m('h3', 'Attachments'),
|
||||
m(AttachmentSection, {
|
||||
files,
|
||||
}),
|
||||
],
|
||||
files.length > 0 &&
|
||||
m('.msg-view__attachment', [
|
||||
m('h3', 'Attachments'),
|
||||
m('.msg-view__attachment-items', [
|
||||
m(AttachmentSection, {
|
||||
files,
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
]
|
||||
),
|
||||
};
|
||||
@ -401,7 +419,7 @@ const SearchBar = () => {
|
||||
let searchString = '';
|
||||
return {
|
||||
view: (v) =>
|
||||
m('input[type=text][id=searchmail][placeholder=Search Subject].searchbar', {
|
||||
m('input[type=text][placeholder=Search Subject].searchbar', {
|
||||
value: searchString,
|
||||
oninput: (e) => {
|
||||
searchString = e.target.value.toLowerCase();
|
||||
@ -467,12 +485,11 @@ const Sidebar = () => {
|
||||
|
||||
const SidebarQuickView = () => {
|
||||
// for the Mail tab, to be moved later.
|
||||
let quickactive = -1;
|
||||
return {
|
||||
view: (v) =>
|
||||
m(
|
||||
'.sidebarquickview',
|
||||
m('h4', 'Quick View'),
|
||||
m('h6.bold', 'Quick View'),
|
||||
v.attrs.tabs.map((panelName, index) =>
|
||||
m(
|
||||
m.route.Link,
|
||||
|
||||
@ -4,9 +4,8 @@ const util = require('mail/mail_util');
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: (v) => [
|
||||
m('.widget', [
|
||||
m('h3', 'Work'),
|
||||
m('hr'),
|
||||
m('.widget__heading', m('h3', 'Work')),
|
||||
m('.widget__body', [
|
||||
m(
|
||||
util.Table,
|
||||
m(
|
||||
|
||||
@ -40,7 +40,7 @@ const navbar = () => {
|
||||
src: '../data/retroshare.svg',
|
||||
alt: 'retroshare_icon',
|
||||
}),
|
||||
m('h4', 'Retroshare'),
|
||||
m('h5', 'Retroshare'),
|
||||
]),
|
||||
m('.nav-menu__box', [
|
||||
Object.keys(vnode.attrs.links).map((linkName, i) => {
|
||||
@ -51,7 +51,7 @@ const navbar = () => {
|
||||
href: vnode.attrs.links[linkName],
|
||||
class: 'item' + (active ? ' item-selected' : ''),
|
||||
},
|
||||
[navIcon[linkName], m('p[style="margin: 0; align-self: end"]', linkName)]
|
||||
[navIcon[linkName], m('p', linkName)]
|
||||
);
|
||||
}),
|
||||
m(
|
||||
@ -85,7 +85,7 @@ const Layout = () => {
|
||||
config: '/config/network',
|
||||
},
|
||||
}),
|
||||
m('#tab-content', vnode.children),
|
||||
m('.tab-content', vnode.children),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
@ -125,24 +125,24 @@ const FriendsList = () => {
|
||||
},
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('h3', 'Friend nodes'),
|
||||
m('hr'),
|
||||
|
||||
Object.entries(Data.gpgDetails)
|
||||
.sort((a, b) => {
|
||||
return a[1].isOnline === b[1].isOnline ? 0 : a[1].isOnline ? -1 : 1;
|
||||
})
|
||||
.map((item) => {
|
||||
const id = item[0];
|
||||
return m(Friend, { id });
|
||||
}),
|
||||
m('.widget__heading', [m('h3', 'Friend nodes'), m(SearchBar)]),
|
||||
m('.widget__body', [
|
||||
Object.entries(Data.gpgDetails)
|
||||
.sort((a, b) => {
|
||||
return a[1].isOnline === b[1].isOnline ? 0 : a[1].isOnline ? -1 : 1;
|
||||
})
|
||||
.map((item) => {
|
||||
const id = item[0];
|
||||
return m(Friend, { id });
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
const Layout = () => {
|
||||
return {
|
||||
view: () => m('.tab-page', [m(SearchBar), m(FriendsList)]),
|
||||
view: () => m('.node-panel', m(FriendsList)),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -8,20 +8,18 @@ const AllContacts = () => {
|
||||
return {
|
||||
view: () => {
|
||||
return m('.widget', [
|
||||
m('h3', 'Contacts', m('span.counter', list.length)),
|
||||
m('hr'),
|
||||
list.map((id) => m(peopleUtil.regularcontactInfo, { id })),
|
||||
m('.widget__heading', [
|
||||
m('h3', 'Contacts', m('span.counter', list.length)),
|
||||
m(peopleUtil.SearchBar),
|
||||
]),
|
||||
m('.widget__body', [list.map((id) => m(peopleUtil.regularcontactInfo, { id }))]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const Layout = {
|
||||
view: (vnode) => m('.tab-page', [m(peopleUtil.SearchBar), m(AllContacts)]),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout);
|
||||
view: () => {
|
||||
return m(AllContacts);
|
||||
},
|
||||
};
|
||||
|
||||
@ -7,20 +7,18 @@ const MyContacts = () => {
|
||||
return {
|
||||
view: () => {
|
||||
return m('.widget', [
|
||||
m('h3', 'MyContacts', m('span.counter', list.length)),
|
||||
m('hr'),
|
||||
list.map((id) => m(peopleUtil.regularcontactInfo, { id })),
|
||||
m('.widget__heading', [
|
||||
m('h3', 'MyContacts', m('span.counter', list.length)),
|
||||
m(peopleUtil.SearchBar),
|
||||
]),
|
||||
m('.widget__body', [list.map((id) => m(peopleUtil.regularcontactInfo, { id }))]),
|
||||
]);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const Layout = {
|
||||
view: (vnode) => m('.tab-page', [m(peopleUtil.SearchBar), m(MyContacts)]),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
view: (vnode) => {
|
||||
return m(Layout);
|
||||
view: () => {
|
||||
return m(MyContacts);
|
||||
},
|
||||
};
|
||||
|
||||
@ -29,26 +29,26 @@ const SignedIdentiy = () => {
|
||||
|
||||
owns.ids.length > 0
|
||||
? rs.rsJsonApiRequest(
|
||||
'/rsIdentity/createIdentity',
|
||||
{
|
||||
id: owns.ids[0],
|
||||
name: v.attrs.name,
|
||||
pseudonimous: false,
|
||||
pgpPassword: passphase,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully created identity.'
|
||||
: 'An error occured while creating identity.';
|
||||
console.log(message);
|
||||
widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]);
|
||||
}
|
||||
)
|
||||
'/rsIdentity/createIdentity',
|
||||
{
|
||||
id: owns.ids[0],
|
||||
name: v.attrs.name,
|
||||
pseudonimous: false,
|
||||
pgpPassword: passphase,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully created identity.'
|
||||
: 'An error occured while creating identity.';
|
||||
console.log(message);
|
||||
widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]);
|
||||
}
|
||||
)
|
||||
: widget.popupMessage([
|
||||
m('h3', 'Create new Identity'),
|
||||
m('hr'),
|
||||
'An error occured while creating identity.',
|
||||
]);
|
||||
m('h3', 'Create new Identity'),
|
||||
m('hr'),
|
||||
'An error occured while creating identity.',
|
||||
]);
|
||||
});
|
||||
},
|
||||
},
|
||||
@ -99,10 +99,10 @@ const CreateIdentity = () => {
|
||||
m(
|
||||
'p',
|
||||
'You can have one or more identities. ' +
|
||||
'They are used when you chat in lobbies, ' +
|
||||
'forums and channel comments. ' +
|
||||
'They act as the destination for distant chat and ' +
|
||||
'the Retroshare distant mail system.'
|
||||
'They are used when you chat in lobbies, ' +
|
||||
'forums and channel comments. ' +
|
||||
'They act as the destination for distant chat and ' +
|
||||
'the Retroshare distant mail system.'
|
||||
),
|
||||
m(
|
||||
'button',
|
||||
@ -111,18 +111,18 @@ const CreateIdentity = () => {
|
||||
!pseudonimous
|
||||
? widget.popupMessage(m(SignedIdentiy, { name }))
|
||||
: rs.rsJsonApiRequest(
|
||||
'/rsIdentity/createIdentity',
|
||||
{
|
||||
name,
|
||||
pseudonimous,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully created identity.'
|
||||
: 'An error occured while creating identity.';
|
||||
widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]);
|
||||
}
|
||||
);
|
||||
'/rsIdentity/createIdentity',
|
||||
{
|
||||
name,
|
||||
pseudonimous,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully created identity.'
|
||||
: 'An error occured while creating identity.';
|
||||
widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]);
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
'Create'
|
||||
@ -192,28 +192,28 @@ const EditIdentity = () => {
|
||||
onclick: () => {
|
||||
!peopleUtil.checksudo(v.attrs.details.mPgpId)
|
||||
? widget.popupMessage([
|
||||
m(SignedEditIdentity, {
|
||||
name,
|
||||
details: v.attrs.details,
|
||||
}),
|
||||
])
|
||||
m(SignedEditIdentity, {
|
||||
name,
|
||||
details: v.attrs.details,
|
||||
}),
|
||||
])
|
||||
: rs.rsJsonApiRequest(
|
||||
'/rsIdentity/updateIdentity',
|
||||
{
|
||||
id: v.attrs.details.mId,
|
||||
'/rsIdentity/updateIdentity',
|
||||
{
|
||||
id: v.attrs.details.mId,
|
||||
|
||||
name,
|
||||
name,
|
||||
|
||||
// avatar: v.attrs.details.mAvatar.mData.base64,
|
||||
pseudonimous: true,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully Updated identity.'
|
||||
: 'An error occured while updating identity.';
|
||||
widget.popupMessage([m('h3', 'Update Identity'), m('hr'), message]);
|
||||
}
|
||||
);
|
||||
// avatar: v.attrs.details.mAvatar.mData.base64,
|
||||
pseudonimous: true,
|
||||
},
|
||||
(data) => {
|
||||
const message = data.retval
|
||||
? 'Successfully Updated identity.'
|
||||
: 'An error occured while updating identity.';
|
||||
widget.popupMessage([m('h3', 'Update Identity'), m('hr'), message]);
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
'Save'
|
||||
@ -277,7 +277,10 @@ const Identity = () => {
|
||||
[
|
||||
m('h4', details.mNickname),
|
||||
details.mNickname &&
|
||||
m(peopleUtil.UserAvatar, { avatar: details.mAvatar, firstLetter: details.mNickname.slice(0, 1).toUpperCase() }),
|
||||
m(peopleUtil.UserAvatar, {
|
||||
avatar: details.mAvatar,
|
||||
firstLetter: details.mNickname.slice(0, 1).toUpperCase(),
|
||||
}),
|
||||
m('.details', [
|
||||
m('p', 'ID:'),
|
||||
m('p', details.mId),
|
||||
@ -336,21 +339,17 @@ const Layout = () => {
|
||||
oninit: () => peopleUtil.ownIds((data) => (ownIds = data)),
|
||||
view: () =>
|
||||
m('.widget', [
|
||||
m('h3', 'Own Identities', m('span.counter', ownIds.length)),
|
||||
m('hr'),
|
||||
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => widget.popupMessage(m(CreateIdentity)),
|
||||
},
|
||||
'New Identity'
|
||||
),
|
||||
ownIds.map((id) =>
|
||||
m(Identity, {
|
||||
id,
|
||||
})
|
||||
),
|
||||
m('.widget__heading', [
|
||||
m('h3', 'Own Identities', m('span.counter', ownIds.length)),
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
onclick: () => widget.popupMessage(m(CreateIdentity)),
|
||||
},
|
||||
'New Identity'
|
||||
),
|
||||
]),
|
||||
m('.widget__body', [ownIds.map((id) => m(Identity, { id }))]),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
@ -8,14 +8,13 @@ const sections = {
|
||||
};
|
||||
|
||||
const Layout = {
|
||||
view: (vnode) =>
|
||||
m('.tab-page', [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/people/',
|
||||
}),
|
||||
m('.node-panel .', vnode.children),
|
||||
]),
|
||||
view: (vnode) => [
|
||||
m(widget.Sidebar, {
|
||||
tabs: Object.keys(sections),
|
||||
baseRoute: '/people/',
|
||||
}),
|
||||
m('.node-panel .', vnode.children),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
21
webui-src/app/scss/abstracts/_colors.scss
Normal file
21
webui-src/app/scss/abstracts/_colors.scss
Normal file
@ -0,0 +1,21 @@
|
||||
//---------------------------------- Colors ----------------------------------//
|
||||
/// Primary Retro color
|
||||
$primary-retro-color: #118fcc !default;
|
||||
|
||||
/// Primary color
|
||||
$primary-color: #019dff !default;
|
||||
|
||||
/// Primary light color
|
||||
$primary-light-color: #9bdaff !default;
|
||||
|
||||
/// Light red
|
||||
$red-color: #ff3a4a !default;
|
||||
|
||||
/// Dark
|
||||
$dark-color: #14141b !default;
|
||||
|
||||
/// Light
|
||||
$light-color: #eef3f6 !default;
|
||||
|
||||
/// Message Starred Color
|
||||
$golden-yellow-color: #fcba03;
|
||||
@ -1,3 +1,5 @@
|
||||
@forward "variables";
|
||||
@forward "mixins";
|
||||
@forward "functions";
|
||||
@forward 'variables';
|
||||
@forward 'colors';
|
||||
@forward 'mixins';
|
||||
@forward 'functions';
|
||||
@forward 'typography';
|
||||
|
||||
@ -4,10 +4,12 @@
|
||||
|
||||
/// Button Mixin
|
||||
@mixin button($bg-color) {
|
||||
width: max-content;
|
||||
height: max-content;
|
||||
color: white;
|
||||
background: $bg-color;
|
||||
font-size: 1.2em;
|
||||
padding: 5px 10px;
|
||||
font-size: 1rem;
|
||||
padding: 0.4rem 1rem;
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
46
webui-src/app/scss/abstracts/_typography.scss
Normal file
46
webui-src/app/scss/abstracts/_typography.scss
Normal file
@ -0,0 +1,46 @@
|
||||
//-------------------------------- Typography --------------------------------//
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.875rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
font-weight: normal;
|
||||
}
|
||||
@ -1,22 +1,3 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all application-wide Sass variables.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------- Colors ----------------------------------//
|
||||
/// Primary color
|
||||
$primary-color: #019dff !default;
|
||||
|
||||
/// Primary light color
|
||||
$primary-light-color: #9bdaff !default;
|
||||
|
||||
/// Light red
|
||||
$red-color: #ff3a4a !default;
|
||||
|
||||
/// Dark
|
||||
$dark-color: #14141b !default;
|
||||
|
||||
/// Light
|
||||
$light-color: #eef3f6 !default;
|
||||
|
||||
/// Message Starred Color
|
||||
$golden-yellow-color: #fcba03;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/******************************
|
||||
General site-wide rules
|
||||
******************************/
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
#main {
|
||||
height: 100vh;
|
||||
@ -9,19 +10,19 @@ General site-wide rules
|
||||
/* Main base div for tabs used by m.route */
|
||||
.content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Main tab content */
|
||||
#tab-content {
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
background-color: #eef3f6;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
background-color: $light-color;
|
||||
animation: fadein 0.3s;
|
||||
overflow: auto;
|
||||
}
|
||||
/* Individual tab pages */
|
||||
.tab-page {
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='password'],
|
||||
@ -34,25 +35,29 @@ textarea {
|
||||
font-weight: 400;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
padding: 0.5rem;
|
||||
padding: 0.4rem 0.8rem;
|
||||
/* Disable chromium's focused element hinting*/
|
||||
outline: transparent;
|
||||
}
|
||||
input:focus {
|
||||
border: 1px solid #3ba4d7;
|
||||
box-shadow: inset 0 0 5px #ccc;
|
||||
input {
|
||||
&:focus {
|
||||
border: 1px solid #3ba4d7;
|
||||
box-shadow: inset 0 0 5px #ccc;
|
||||
}
|
||||
&.stretched {
|
||||
width: 90%;
|
||||
}
|
||||
&.small {
|
||||
max-width: 70%;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
&.searchbar {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
input.stretched {
|
||||
width: 90%;
|
||||
}
|
||||
input.small {
|
||||
max-width: 70%;
|
||||
font-size: 1em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
input.searchbar {
|
||||
display: block;
|
||||
margin: 0.9em 0 0 0.9em;
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table {
|
||||
@ -62,21 +67,18 @@ table {
|
||||
border-collapse: collapse;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
table th {
|
||||
font-weight: 100;
|
||||
font-size: 1.3em;
|
||||
color: black;
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
table tr {
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 1.125rem;
|
||||
& th {
|
||||
font-size: 1.125rem;
|
||||
color: black;
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
& tr {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
color: #444;
|
||||
}
|
||||
hr {
|
||||
@ -89,9 +91,9 @@ hr {
|
||||
grid-template-columns: auto auto;
|
||||
gap: 1rem;
|
||||
justify-content: start;
|
||||
}
|
||||
.grid-2col input[type='checkbox'] {
|
||||
margin-top: 20px;
|
||||
& input[type='checkbox'] {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
html {
|
||||
font-size: 100%;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
figure,
|
||||
blockquote,
|
||||
@ -26,8 +28,8 @@ dd {
|
||||
}
|
||||
|
||||
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
||||
ul[role="list"],
|
||||
ol[role="list"] {
|
||||
ul[role='list'],
|
||||
ol[role='list'] {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
@ -66,7 +68,7 @@ select {
|
||||
/* Remove all animations and transitions for people that prefer not to see them */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html:focus-within {
|
||||
scroll-behavior: auto;
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
@forward "buttons";
|
||||
@forward "navbar";
|
||||
@forward "progress-bar";
|
||||
@forward 'buttons';
|
||||
@forward 'media';
|
||||
@forward 'navbar';
|
||||
@forward 'posts';
|
||||
@forward 'progress-bar';
|
||||
|
||||
22
webui-src/app/scss/components/_media.scss
Normal file
22
webui-src/app/scss/components/_media.scss
Normal file
@ -0,0 +1,22 @@
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.media-item {
|
||||
display: flex;
|
||||
margin-top: 0.5rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid transparentize($dark-color, 0.9);
|
||||
border-radius: 4px;
|
||||
&__details {
|
||||
flex-basis: 40%;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
gap: 0.5rem;
|
||||
& img {
|
||||
width: 6rem;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
&__desc {
|
||||
flex-basis: 60%;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
@use '../abstracts/' as *;
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
/* Navbar */
|
||||
.nav-menu {
|
||||
@ -13,7 +13,6 @@
|
||||
margin-right: 0rem;
|
||||
|
||||
&__logo {
|
||||
width: 130px;
|
||||
padding: 1.2rem 0;
|
||||
display: flex;
|
||||
gap: 0.3rem;
|
||||
@ -24,9 +23,9 @@
|
||||
width: 1.6rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
h5 {
|
||||
line-height: 1;
|
||||
color: white;
|
||||
align-self: end;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +41,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
line-height: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: transparentize($light-color, 0.85);
|
||||
@ -97,6 +97,7 @@
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
a.item {
|
||||
margin: 4px;
|
||||
padding: 10px;
|
||||
@ -104,66 +105,59 @@ a.item {
|
||||
text-decoration: none;
|
||||
color: #ccc;
|
||||
font-size: 0.875em;
|
||||
/* CSS capitalization is magical! */
|
||||
text-transform: capitalize;
|
||||
transition: all 300ms;
|
||||
/* To vertically stack child nodes */
|
||||
transition: 300ms;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
height: 30%;
|
||||
width: 200px;
|
||||
background-color: white;
|
||||
}
|
||||
.sidebar a {
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 0.95em;
|
||||
color: #999;
|
||||
}
|
||||
.sidebar a:hover {
|
||||
color: #222;
|
||||
}
|
||||
.sidebar .selected-sidebar-link {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
border-left: 5px solid #3ba4d7;
|
||||
animation: expand-left-border 0.1s;
|
||||
& a {
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 0.95em;
|
||||
color: #999;
|
||||
&:hover {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
& .selected-sidebar-link {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
border-left: 5px solid #3ba4d7;
|
||||
animation: expand-left-border 0.1s;
|
||||
}
|
||||
}
|
||||
.sidebarquickview {
|
||||
height: 30%;
|
||||
width: 200px;
|
||||
top: 300px;
|
||||
background-color: white;
|
||||
}
|
||||
.sidebarquickview a {
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 0.95em;
|
||||
color: #999;
|
||||
}
|
||||
.sidebarquickview a:hover {
|
||||
color: #222;
|
||||
}
|
||||
.sidebarquickview .selected-sidebarquickview-link {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
border-left: 5px solid #3ba4d7;
|
||||
animation: expand-left-border 0.1s;
|
||||
& > h6 {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
& a {
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
padding: 0.5rem 1rem;
|
||||
display: block;
|
||||
color: #999;
|
||||
& a:hover {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
& .selected-sidebarquickview-link {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
border-left: 5px solid #3ba4d7;
|
||||
animation: expand-left-border 0.1s;
|
||||
}
|
||||
}
|
||||
/* Content adjacent to sidebar */
|
||||
.node-panel {
|
||||
position: relative;
|
||||
bottom: 155px;
|
||||
margin-left: 200px;
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
|
||||
|
||||
41
webui-src/app/scss/components/_posts.scss
Normal file
41
webui-src/app/scss/components/_posts.scss
Normal file
@ -0,0 +1,41 @@
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.posts {
|
||||
height: 100%;
|
||||
margin-top: 1rem;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
&__heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
&-container {
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
gap: 2rem;
|
||||
border: 1px solid transparentize($dark-color, 0.9);
|
||||
border-radius: 4px;
|
||||
overflow: auto;
|
||||
&-card {
|
||||
min-height: 240px;
|
||||
flex-direction: column;
|
||||
border: 1px solid transparentize($dark-color, 0.5);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
& img {
|
||||
flex-basis: 90%;
|
||||
object-fit: cover;
|
||||
}
|
||||
& p {
|
||||
padding: 0 0.125rem;
|
||||
flex-basis: 10%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,26 @@
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.progressbar {
|
||||
width: 100%;
|
||||
border-radius: 500px;
|
||||
background-color: #eef3f6;
|
||||
height: 2rem;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
.progressbar:before {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: $light-color;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
&-status {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
color: $dark-color;
|
||||
background-color: $primary-color;
|
||||
}
|
||||
&-percent {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
.progress-status {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
padding: 5px;
|
||||
border-radius: 500px;
|
||||
color: #000;
|
||||
background-color: #3ba4d7;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
.chat
|
||||
$color: black
|
||||
$header_height: 50px
|
||||
$left_width: 200px
|
||||
$right_width: 200px
|
||||
$input_height: 100px
|
||||
padding: 15px
|
||||
&.container
|
||||
height: 100%
|
||||
padding: 0px
|
||||
position: relative
|
||||
box-sizing: border-box
|
||||
&.header
|
||||
position: absolute
|
||||
top: 0px
|
||||
left: 0px
|
||||
right: 0px
|
||||
height: $header_height
|
||||
background-color: $color
|
||||
border-bottom: solid 1px gray
|
||||
box-sizing: border-box
|
||||
&.left
|
||||
position: absolute
|
||||
top: $header_height
|
||||
bottom: 0px
|
||||
left: 0px
|
||||
width: $left_width
|
||||
//border-right: solid 1px gray
|
||||
box-sizing: border-box
|
||||
background-color: black
|
||||
&.right
|
||||
position: absolute
|
||||
top: $header_height
|
||||
right: 0px
|
||||
bottom: 0px
|
||||
width: $right_width
|
||||
box-sizing: border-box
|
||||
//border-left: solid 1px gray
|
||||
&.middle
|
||||
//background-color: blue
|
||||
position: absolute
|
||||
top: 0px
|
||||
margin-top: $header_height
|
||||
left: $left_width
|
||||
right: $right_width
|
||||
box-sizing: border-box
|
||||
padding: 0px
|
||||
height: 100%
|
||||
overflow-y: scroll
|
||||
&.bottom
|
||||
position: absolute
|
||||
bottom: 0px
|
||||
right: $right_width
|
||||
left: $left_width
|
||||
padding: 5px
|
||||
&.msg
|
||||
padding: 0px
|
||||
$author_width: 100px
|
||||
&.container
|
||||
position: relative
|
||||
border-bottom: solid 1px lightgray
|
||||
padding: 10px
|
||||
height: unset
|
||||
//background-color: lime
|
||||
&.from
|
||||
position: absolute
|
||||
width: $author_width
|
||||
top: 10px
|
||||
left: 0px
|
||||
color: white
|
||||
text-align: right
|
||||
&.when
|
||||
float: right
|
||||
color: lightgray
|
||||
margin-bottom: 10px
|
||||
&.text
|
||||
padding-left: $author_width
|
||||
top: 0px
|
||||
left: $author_width
|
||||
white-space: pre-wrap
|
||||
height: initial
|
||||
@ -1,242 +0,0 @@
|
||||
body {
|
||||
background-color: azure;
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
margin: 0em;
|
||||
/*padding: 1.5em;*/
|
||||
padding: 2mm;
|
||||
font-size: 0.9em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#overlay {
|
||||
z-index: 10;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0.5, 0.5, 0.5, 0.8);
|
||||
}
|
||||
|
||||
.paddingbox {
|
||||
padding: 2mm;
|
||||
}
|
||||
|
||||
.nav {
|
||||
list-style-type: none;
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
display: inline;
|
||||
padding: 0.1em;
|
||||
margin-right: 1em;
|
||||
border-width: 0.1em;
|
||||
border-color: blue;
|
||||
border-bottom-style: solid;
|
||||
cursor: pointer;
|
||||
}
|
||||
td {
|
||||
padding: 0.3em;
|
||||
border-style: solid;
|
||||
border-width: 0.1em;
|
||||
border-color: black;
|
||||
}
|
||||
hr {
|
||||
color: black;
|
||||
}
|
||||
.menu {
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
border-width: 0.1em;
|
||||
cursor: pointer;
|
||||
padding: 0em;
|
||||
}
|
||||
.btn {
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
border-width: 0.1em;
|
||||
cursor: pointer;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
.btn2,
|
||||
.box {
|
||||
border-style: solid;
|
||||
/*border-color: black;*/
|
||||
border-color: black;
|
||||
/*border-width: 1px;*/
|
||||
border-radius: 0mm;
|
||||
padding: 2mm;
|
||||
font-size: 10mm;
|
||||
cursor: pointer;
|
||||
margin-bottom: 2mm;
|
||||
}
|
||||
.btn2:hover {
|
||||
background-color: midnightblue;
|
||||
}
|
||||
|
||||
.btnSmall {
|
||||
border-style: solid;
|
||||
/*border-color: black;*/
|
||||
border-color: black;
|
||||
/*border-width: 1px;*/
|
||||
border-radius: 0mm;
|
||||
padding: 1mm;
|
||||
font-size: 100%;
|
||||
|
||||
cursor: pointer;
|
||||
margin-bottom: 0mm;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.noBorderTable {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.noBorderTD {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
vertical-align: center;
|
||||
}
|
||||
|
||||
.filelink {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
background-color: azure;
|
||||
border-color: black;
|
||||
font-size: 10mm;
|
||||
border-radius: 0mm;
|
||||
border-width: 1mm;
|
||||
padding: 2mm;
|
||||
margin-bottom: 1mm;
|
||||
margin-right: 1mm;
|
||||
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input:hover {
|
||||
background-color: midnightblue;
|
||||
}
|
||||
|
||||
textarea#txtNewMsg {
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
background-color: azure;
|
||||
border-color: black;
|
||||
font-size: 100%;
|
||||
border-radius: 0mm;
|
||||
border-width: 1mm;
|
||||
padding: 2mm;
|
||||
margin-bottom: 0mm;
|
||||
margin-right: 1mm;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
textarea#certificate {
|
||||
color: black;
|
||||
font-family: courrier;
|
||||
background-color: azure;
|
||||
border-color: black;
|
||||
font-size: 100%;
|
||||
border-radius: 0mm;
|
||||
border-width: 1mm;
|
||||
padding: 2mm;
|
||||
margin-bottom: 0mm;
|
||||
margin-right: 1mm;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input#txtMsgKeyword {
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
background-color: azure;
|
||||
border-color: black;
|
||||
font-size: 100%;
|
||||
border-radius: 0mm;
|
||||
border-width: 1mm;
|
||||
padding: 1mm;
|
||||
margin-bottom: 0mm;
|
||||
margin-right: 1mm;
|
||||
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.flexbox {
|
||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
||||
display: -webkit-flex; /* NEW - Chrome */
|
||||
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||
}
|
||||
|
||||
.flexwidemember {
|
||||
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
||||
width: 20%; /* For old syntax, otherwise collapses. */
|
||||
-webkit-flex: 1; /* Chrome */
|
||||
-ms-flex: 1; /* IE 10 */
|
||||
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||
}
|
||||
|
||||
#logo_splash {
|
||||
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
|
||||
animation-fill-mode: forwards;
|
||||
-webkit-animation-name: logo_splash; /* Chrome, Safari, Opera */
|
||||
-webkit-animation-duration: 3s; /* Chrome, Safari, Opera */
|
||||
animation-name: logo_splash;
|
||||
animation-duration: 3s;
|
||||
text-align: center;
|
||||
}
|
||||
/* Chrome, Safari, Opera */
|
||||
@-webkit-keyframes logo_splash {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard syntax */
|
||||
@keyframes logo_splash {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@ -1,290 +0,0 @@
|
||||
body {
|
||||
background-color: #ccc;
|
||||
color: #666;
|
||||
font-family: sans;
|
||||
margin: 0em;
|
||||
/*padding: 1.5em;*/
|
||||
padding: 2mm;
|
||||
font-size: 1.1em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#overlay {
|
||||
z-index: 10;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.paddingbox {
|
||||
padding: 2mm;
|
||||
}
|
||||
|
||||
.nav {
|
||||
list-style-type: none;
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
display: inline;
|
||||
padding: 0.1em;
|
||||
margin-right: 1em;
|
||||
border-width: 0.1em;
|
||||
border-color: blue;
|
||||
border-bottom-style: solid;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.3em;
|
||||
border-style: none;
|
||||
border-width: 0.1em;
|
||||
border-color: orange;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
input[type='button'] {
|
||||
border: solid 1px rgba(0, 0, 0, 0);
|
||||
border-radius: 10px;
|
||||
font-size: 6mm;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
background-color: #f79e3a;
|
||||
width: 26vw;
|
||||
display: inline-grid;
|
||||
margin: 0.2rem;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
box-shadow: 5px 5px 9px #aaa;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.btn2,
|
||||
.box,
|
||||
.btnSmall {
|
||||
border: solid 1px rgba(0, 0, 0, 0);
|
||||
border-radius: 10px;
|
||||
font-size: 6mm;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
background-color: #f79e3a;
|
||||
display: inline-grid;
|
||||
margin: 0.2rem;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
box-shadow: 5px 5px 9px #aaa;
|
||||
}
|
||||
|
||||
.btn2,
|
||||
.box {
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.btnSmall {
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
.menu {
|
||||
border: solid 1px rgba(0, 0, 0, 0);
|
||||
border-radius: 10px;
|
||||
font-size: 0.8em;
|
||||
cursor: pointer;
|
||||
background-color: #f79e3a;
|
||||
display: inline-grid;
|
||||
margin: 0.2rem;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
span.menu:nth-child(2) {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
width: 6.3rem;
|
||||
}
|
||||
|
||||
span.menu:nth-child(16) {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
li .menu {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
div.btn2:nth-child(9) {
|
||||
border: rgba(0, 0, 0, 0);
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
text-decoration: underline;
|
||||
box-shadow: unset;
|
||||
margin-top: 1em;
|
||||
text-align: left !important;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.btn2:nth-child(9):hover {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn2:hover {
|
||||
background-color: orangered;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.noBorderTable {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.noBorderTD {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
vertical-align: center;
|
||||
}
|
||||
|
||||
.filelink {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
border-color: orange;
|
||||
font-size: 10mm;
|
||||
border-radius: 3mm;
|
||||
border-width: 1mm;
|
||||
padding: 2mm;
|
||||
margin-bottom: 1mm;
|
||||
margin-right: 1mm;
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type='button']:hover {
|
||||
background-color: orangered;
|
||||
}
|
||||
|
||||
/*chat*/
|
||||
|
||||
textarea#txtNewMsg {
|
||||
font-size: 100%;
|
||||
border-radius: 3mm;
|
||||
border-width: 1mm;
|
||||
padding: 2mm;
|
||||
margin-bottom: 0mm;
|
||||
margin-right: 1mm;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input#txtMsgKeyword {
|
||||
/* color: orange;
|
||||
font-family: monospace;
|
||||
background-color: black;*/
|
||||
border-color: orange;
|
||||
font-size: 100%;
|
||||
border-radius: 3mm;
|
||||
border-width: 1mm;
|
||||
padding: 1mm;
|
||||
margin-bottom: 0mm;
|
||||
margin-right: 1mm;
|
||||
/* make the button the whole screen width */
|
||||
width: 100%;
|
||||
/* make the text input fit small screens*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.flexbox {
|
||||
display: -webkit-box;
|
||||
/* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box;
|
||||
/* OLD - Firefox 19- (buggy but mostly works) */
|
||||
display: -ms-flexbox;
|
||||
/* TWEENER - IE 10 */
|
||||
display: -webkit-flex;
|
||||
/* NEW - Chrome */
|
||||
display: flex;
|
||||
/* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||
}
|
||||
|
||||
.flexwidemember {
|
||||
-webkit-box-flex: 1;
|
||||
/* OLD - iOS 6-, Safari 3.1-6 */
|
||||
-moz-box-flex: 1;
|
||||
/* OLD - Firefox 19- */
|
||||
width: 20%;
|
||||
/* For old syntax, otherwise collapses. */
|
||||
-webkit-flex: 1;
|
||||
/* Chrome */
|
||||
-ms-flex: 1;
|
||||
/* IE 10 */
|
||||
flex: 1;
|
||||
/* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||
}
|
||||
|
||||
#logo_splash {
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
/* Chrome, Safari, Opera */
|
||||
animation-fill-mode: forwards;
|
||||
-webkit-animation-name: logo_splash;
|
||||
/* Chrome, Safari, Opera */
|
||||
-webkit-animation-duration: 3s;
|
||||
/* Chrome, Safari, Opera */
|
||||
animation-name: logo_splash;
|
||||
animation-duration: 3s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Chrome, Safari, Opera */
|
||||
|
||||
@-webkit-keyframes logo_splash {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard syntax */
|
||||
|
||||
@keyframes logo_splash {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,55 @@
|
||||
.widget {
|
||||
margin: 1em;
|
||||
padding: 1em;
|
||||
border-radius: 10px;
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
background-color: white;
|
||||
border-radius: 6px;
|
||||
overflow: auto;
|
||||
& .top-heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
&__heading {
|
||||
padding-bottom: 0.25rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid #999;
|
||||
}
|
||||
&__body {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
&-heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
& .action {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
&-content {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
&-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
& > p {
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
}
|
||||
& .tooltip {
|
||||
float: right;
|
||||
}
|
||||
&-half {
|
||||
max-width: 50%;
|
||||
}
|
||||
}
|
||||
.widget > p {
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
}
|
||||
.widget .tooltip {
|
||||
float: right;
|
||||
}
|
||||
.widget-half {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
.board-node-panel {
|
||||
position: relative;
|
||||
bottom: 200px;
|
||||
margin-left: 200px;
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
|
||||
/* subject */
|
||||
table.boards th:nth-child(1) {
|
||||
width: 50%;
|
||||
@ -24,77 +17,15 @@ table.boards tr:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table.boards tr.hidden{
|
||||
table.boards tr.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#searchboard {
|
||||
position:relative;
|
||||
margin-left: 250px;
|
||||
}
|
||||
|
||||
img.boardpic {
|
||||
float: left;
|
||||
height: 150px;
|
||||
width:150px;
|
||||
padding: 25px;
|
||||
}
|
||||
#boarddetails {
|
||||
position: relative;
|
||||
margin-left: 150px;
|
||||
padding: 10px;
|
||||
}
|
||||
.p{
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#toggleunsub {
|
||||
position: relative;
|
||||
background: gray;
|
||||
}
|
||||
|
||||
#grid{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
gap: 100px;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
border: 2px solid gray;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
.card-img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
.card-title {
|
||||
position: relative;
|
||||
bottom: 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* subject */
|
||||
table.comments th {
|
||||
height: 40px;
|
||||
}
|
||||
table.comments th:nth-child(1) {
|
||||
width: 40%;
|
||||
}
|
||||
table.comments td {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
table.comments td:nth-child(1){
|
||||
border: 3px solid lightskyblue;
|
||||
border-radius: 25px;
|
||||
|
||||
}
|
||||
table.comments tr {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#options {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
@ -116,4 +47,4 @@ table.comments tr {
|
||||
font-size: medium;
|
||||
margin-left: 10px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,110 +1,87 @@
|
||||
.channel-node-panel {
|
||||
position: relative;
|
||||
bottom: 200px;
|
||||
margin-left: 200px;
|
||||
animation: fadein 0.5s;
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.file-section {
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* subject */
|
||||
table.channels th:nth-child(1) {
|
||||
width: 50%;
|
||||
text-align: start;
|
||||
}
|
||||
/* subject */
|
||||
table.channels td:nth-child(1) {
|
||||
text-align: start;
|
||||
/* Truncate text with '...' */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
.comments-section {
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
&__menu {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
&-id {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.channels tr:hover {
|
||||
background-color: #eef3f6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table.channels tr.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#searchchannel {
|
||||
position: relative;
|
||||
margin-left: 250px;
|
||||
/* top: px; */
|
||||
}
|
||||
|
||||
img.channelpic {
|
||||
float: left;
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
padding: 25px;
|
||||
}
|
||||
#channeldetails {
|
||||
position: relative;
|
||||
margin-left: 150px;
|
||||
padding: 10px;
|
||||
}
|
||||
.p {
|
||||
margin: 0;
|
||||
}
|
||||
#toggleunsub {
|
||||
position: relative;
|
||||
background: gray;
|
||||
}
|
||||
|
||||
#grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
|
||||
gap: 100px;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
border: 2px solid gray;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
.card-img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
.card-title {
|
||||
position: relative;
|
||||
bottom: 0px;
|
||||
overflow: auto;
|
||||
/* subject */
|
||||
table.channels {
|
||||
& th:nth-child(1) {
|
||||
width: 50%;
|
||||
text-align: start;
|
||||
}
|
||||
/* subject */
|
||||
& td:nth-child(1) {
|
||||
text-align: start;
|
||||
/* Truncate text with '...' */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
& tr:hover {
|
||||
background-color: $light-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
& tr.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* subject */
|
||||
table.comments th {
|
||||
height: 40px;
|
||||
}
|
||||
table.comments th:nth-child(1) {
|
||||
width: 2%;
|
||||
}
|
||||
table.comments th:nth-child(2) {
|
||||
width: 40%;
|
||||
}
|
||||
table.comments td {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
table.comments td:nth-child(2) {
|
||||
text-align: start;
|
||||
border: 3px solid lightskyblue;
|
||||
border-radius: 25px;
|
||||
}
|
||||
table.comments tr {
|
||||
height: 40px;
|
||||
}
|
||||
table.files th:nth-child(1) {
|
||||
width: 40%;
|
||||
}
|
||||
table.files th:nth-child(3) {
|
||||
width: 50%;
|
||||
}
|
||||
table.files td {
|
||||
word-wrap: break-word;
|
||||
table {
|
||||
padding: 0.5rem;
|
||||
&.comments {
|
||||
border: 1px solid #eee;
|
||||
& th {
|
||||
height: 40px;
|
||||
&:nth-child(1) {
|
||||
width: 2%;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
& td {
|
||||
word-wrap: break-word;
|
||||
&:nth-child(2) {
|
||||
text-align: start;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.files {
|
||||
& th:first-child {
|
||||
text-align: start;
|
||||
width: 60%;
|
||||
}
|
||||
& tr td:first-child {
|
||||
text-align: start;
|
||||
}
|
||||
& td {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* #options{
|
||||
width: 100px;
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
.lobbies {
|
||||
position: absolute;
|
||||
width: 185px;
|
||||
left: 138px;
|
||||
left: 165px;
|
||||
bottom: 15px;
|
||||
top: 130px;
|
||||
overflow: auto;
|
||||
@ -92,7 +92,7 @@
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
top: 130px;
|
||||
left: 328px;
|
||||
left: 360px;
|
||||
right: 215px;
|
||||
overflow: auto;
|
||||
}
|
||||
@ -121,7 +121,7 @@
|
||||
height: 85px;
|
||||
bottom: 15px;
|
||||
right: 215px;
|
||||
left: 323px;
|
||||
left: 360px;
|
||||
}
|
||||
|
||||
textarea.chatMsg {
|
||||
|
||||
@ -1,29 +1,15 @@
|
||||
@use '../abstracts/variables' as *;
|
||||
|
||||
.config-node-panel {
|
||||
position: relative;
|
||||
bottom: 320px;
|
||||
margin-left: 200px;
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.mail {
|
||||
.permission-flag {
|
||||
margin-bottom: 1rem;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
&-tags {
|
||||
padding: 8px;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid transparentize($dark-color, 0.8);
|
||||
border-radius: 6px;
|
||||
&__heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
& button {
|
||||
height: max-content;
|
||||
}
|
||||
}
|
||||
&__container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -38,12 +24,12 @@
|
||||
border: none;
|
||||
}
|
||||
&__color {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
&__name {
|
||||
font-size: 1.25rem;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
&__modify {
|
||||
margin-left: auto;
|
||||
@ -54,6 +40,10 @@
|
||||
&:hover {
|
||||
background-color: $light-color;
|
||||
}
|
||||
& button,
|
||||
& button.red {
|
||||
padding: 0.25rem 0.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,7 +60,7 @@
|
||||
margin: 0;
|
||||
padding-left: 1rem;
|
||||
height: 100px;
|
||||
overflow: hidden scroll;
|
||||
overflow: hidden auto;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
@ -102,3 +92,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.config-files {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@ -1,56 +1,47 @@
|
||||
@use '../abstracts/variables' as *;
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.file-view {
|
||||
width: 90%;
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ccc;
|
||||
margin-top: 2em;
|
||||
padding: 1em;
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
.file-view > p {
|
||||
margin: 0.5em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.file-view > span {
|
||||
margin: 0 1em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.file-view > .progressbar {
|
||||
width: 70%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.file-view button {
|
||||
float: right;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.file-view select {
|
||||
float: right;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.file-view label {
|
||||
float: right;
|
||||
margin-left: 15px;
|
||||
}
|
||||
span > i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.filestat {
|
||||
min-width: 7em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.searchbar {
|
||||
margin: 5px;
|
||||
width: 40%;
|
||||
box-shadow: 0 0 3px #aaa;
|
||||
}
|
||||
.file-node-panel {
|
||||
position: relative;
|
||||
bottom: 200px;
|
||||
margin-left: 200px;
|
||||
animation: fadein 0.5s;
|
||||
&__heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
&-chunk {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
&__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
&-details {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&-stat {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
& span > i {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
&-action {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
gap: 1rem;
|
||||
& button,
|
||||
& button.red {
|
||||
padding: 0.25rem 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.myfiles td {
|
||||
@ -89,10 +80,8 @@ table.friendsfiles td:nth-child(2) {
|
||||
gap: 8px;
|
||||
border: 1px solid transparentize($dark-color, 0.8);
|
||||
border-radius: 6px;
|
||||
|
||||
h4 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
&__keywords {
|
||||
flex-basis: 15%;
|
||||
@ -116,6 +105,8 @@ table.friendsfiles td:nth-child(2) {
|
||||
|
||||
&__results {
|
||||
flex-basis: 85%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
& .results-container {
|
||||
& .results-header {
|
||||
@ -144,6 +135,8 @@ table.friendsfiles td:nth-child(2) {
|
||||
}
|
||||
}
|
||||
& .results {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
& tr {
|
||||
display: flex;
|
||||
& .results {
|
||||
@ -171,9 +164,17 @@ table.friendsfiles td:nth-child(2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
& button {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
width: 40%;
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,10 +70,3 @@ table.threadreply tr:hover {
|
||||
background-color: #eef3f6;
|
||||
cursor: pointer;
|
||||
}
|
||||
#idtags{
|
||||
width: 160px;
|
||||
text-align: center;
|
||||
font-size: medium;
|
||||
margin-left: 10px;
|
||||
height: 40px;
|
||||
}
|
||||
@ -1,52 +1,124 @@
|
||||
.certificate {
|
||||
margin: auto;
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.homepage {
|
||||
margin: 2rem auto 0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.textArea {
|
||||
box-sizing: none;
|
||||
background: transparent;
|
||||
font-size: 1.1rem;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
resize: none;
|
||||
}
|
||||
.logo {
|
||||
display: flex;
|
||||
max-width: 500px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.retroshareText > h3 {
|
||||
margin-right: 3px;
|
||||
}
|
||||
.webhelp {
|
||||
background: whitesmoke;
|
||||
font-size: 0.8rem;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: black;
|
||||
border-radius: 5px;
|
||||
border: 1px solid black;
|
||||
padding: 10px 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.webhelp > i {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.webhelp > p {
|
||||
font-weight: 600;
|
||||
}
|
||||
.retroshareID {
|
||||
display: flex;
|
||||
justify-self: start;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: monospace;
|
||||
gap: 4rem;
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
& img {
|
||||
width: 90px;
|
||||
}
|
||||
.retroshareText {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
& .retrotext {
|
||||
font-size: 36px;
|
||||
line-height: 1.125;
|
||||
font-weight: 500;
|
||||
|
||||
& > span {
|
||||
color: $primary-retro-color;
|
||||
}
|
||||
}
|
||||
& > b {
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.certificate {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rem;
|
||||
|
||||
&__heading {
|
||||
text-align: center;
|
||||
& > h1 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
border: 1.5px solid transparentize($primary-retro-color, 0.8);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0px 0px 8px 2px transparentize($dark-color, 0.95);
|
||||
|
||||
.rsId > p {
|
||||
margin-bottom: 0.5rem;
|
||||
color: $primary-retro-color;
|
||||
}
|
||||
|
||||
.retroshareID {
|
||||
padding: 0.5rem;
|
||||
display: flex;
|
||||
justify-self: start;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 4px;
|
||||
background: transparentize($dark-color, 0.95);
|
||||
& .textArea {
|
||||
padding: 0;
|
||||
font-size: 1rem;
|
||||
font-family: monospace;
|
||||
box-sizing: none;
|
||||
background: transparent;
|
||||
font-size: 1.1rem;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
resize: none;
|
||||
}
|
||||
& i {
|
||||
color: $primary-retro-color;
|
||||
}
|
||||
& > i {
|
||||
margin: 0 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.webhelp {
|
||||
&-container {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
background: whitesmoke;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 5px;
|
||||
border: 1px solid transparentize($dark-color, 0.5);
|
||||
padding: 0.5rem;
|
||||
width: fit-content;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: $light-color;
|
||||
border: 1px solid $dark-color;
|
||||
}
|
||||
& > i {
|
||||
font-size: 1.2rem;
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
.add-friend > h6,
|
||||
.webhelp-container > h6 {
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,89 @@
|
||||
@use '../abstracts' as *;
|
||||
@use '../abstracts/colors' as *;
|
||||
|
||||
.side-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: white;
|
||||
.mail-compose-btn {
|
||||
width: 96%;
|
||||
margin: 0.25rem;
|
||||
padding: 0.75rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-view {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
overflow: auto;
|
||||
&-nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
&__action {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
&__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
& > h3 {
|
||||
line-height: 1;
|
||||
}
|
||||
& .msg-details {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
&__avatar {
|
||||
height: max-content;
|
||||
}
|
||||
&__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&-item {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&__body {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 98%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
&__attachment {
|
||||
height: 50%;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&-items {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iframe.msg {
|
||||
border: 0;
|
||||
}
|
||||
.mail-tag {
|
||||
width: 8rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
.msgHeader {
|
||||
display: flex;
|
||||
}
|
||||
.msgHeaderDetails {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
table.mails {
|
||||
& th {
|
||||
@ -74,73 +159,22 @@ input.star-check {
|
||||
}
|
||||
|
||||
/* mail_util.js styles */
|
||||
.truncate {
|
||||
display: flex;
|
||||
width: 65vw;
|
||||
height: 22px;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
#truncate {
|
||||
height: 1.75rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
#show-more,
|
||||
#show-less {
|
||||
font-size: 0.8em;
|
||||
width: 100px;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
iframe.msg {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
#composebtn {
|
||||
text-align: center;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
/* float: left; */
|
||||
}
|
||||
#searchmail {
|
||||
float: right;
|
||||
position: relative;
|
||||
margin-right: 20px;
|
||||
}
|
||||
#tags {
|
||||
width: 200px;
|
||||
text-align: center;
|
||||
font-size: medium;
|
||||
margin-left: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
#composepopup {
|
||||
height: 80%;
|
||||
width: 70%;
|
||||
bottom: 50%;
|
||||
right: 58%;
|
||||
}
|
||||
.mail-node-panel {
|
||||
position: relative;
|
||||
bottom: 755px;
|
||||
margin-left: 200px;
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
|
||||
.msgHeader {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.msgHeaderDetails {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 0.75rem;
|
||||
padding: 0 0.25rem;
|
||||
background: #999;
|
||||
color: $dark-color;
|
||||
box-shadow: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
// Normal mail attachment view
|
||||
table.attachment-container {
|
||||
height: auto;
|
||||
overflow-y: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 0;
|
||||
|
||||
& > tr {
|
||||
@ -153,17 +187,20 @@ table.attachment-container {
|
||||
justify-content: space-between;
|
||||
|
||||
th {
|
||||
font-size: 1.5rem;
|
||||
text-align: start;
|
||||
|
||||
&:nth-child(1) {
|
||||
flex-basis: 45%;
|
||||
}
|
||||
&:nth-child(2),
|
||||
&:nth-child(3),
|
||||
&:nth-child(4) {
|
||||
&:nth-child(2) {
|
||||
flex-basis: 15%;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
flex-basis: 10%;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
flex-basis: 20%;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
text-align: center;
|
||||
flex-basis: 10%;
|
||||
@ -188,11 +225,15 @@ table.attachment-container {
|
||||
}
|
||||
}
|
||||
|
||||
&__from,
|
||||
&__size,
|
||||
&__date {
|
||||
&__from {
|
||||
flex-basis: 15%;
|
||||
}
|
||||
&__size {
|
||||
flex-basis: 10%;
|
||||
}
|
||||
&__date {
|
||||
flex-basis: 20%;
|
||||
}
|
||||
& td:nth-child(5) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -200,28 +241,21 @@ table.attachment-container {
|
||||
flex-basis: 10%;
|
||||
|
||||
& button {
|
||||
font-size: inherit;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attachment Section attachment view
|
||||
.msg-attachment-container {
|
||||
.view-toggle {
|
||||
height: max-content;
|
||||
border: 1px solid $primary-color;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
& .view-toggle {
|
||||
height: max-content;
|
||||
border: 1px solid $primary-color;
|
||||
& * {
|
||||
padding: 4px 12px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
|
||||
& * {
|
||||
padding: 4px 12px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,48 +1,45 @@
|
||||
.friend {
|
||||
color: #444;
|
||||
font-size: 1.2em;
|
||||
margin: 1em;
|
||||
padding: 20px;
|
||||
margin: 1rem 0.5rem;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.friend i {
|
||||
float: left;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.friend h4 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.friend p {
|
||||
margin: 0;
|
||||
}
|
||||
.friend button {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.friend.hidden {
|
||||
display: none;
|
||||
}
|
||||
.friend .brief-info.online {
|
||||
color: green;
|
||||
}
|
||||
& i {
|
||||
float: left;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
& h4 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
& button {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
& .brief-info.online {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.friend .location {
|
||||
margin: 5px;
|
||||
border-top: 1px solid #bbb;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
justify-content: start;
|
||||
}
|
||||
.friend .brief-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-self: start;
|
||||
}
|
||||
& .location {
|
||||
margin: 5px;
|
||||
border-top: 1px solid #bbb;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
justify-content: start;
|
||||
}
|
||||
& .brief-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.friend .fa-times-circle {
|
||||
color: #555;
|
||||
}
|
||||
.friend .fa-check-circle {
|
||||
color: green;
|
||||
& .fa-times-circle {
|
||||
color: #555;
|
||||
}
|
||||
& .fa-check-circle {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,16 +5,19 @@
|
||||
padding: 10px;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.identity > h4 {
|
||||
margin: 5px;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.identity p {
|
||||
margin: 0;
|
||||
}
|
||||
.identity button {
|
||||
font-size: 0.9em;
|
||||
& > h4 {
|
||||
margin: 5px;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
& button {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
& .details {
|
||||
display: grid;
|
||||
grid-template-columns: 140px auto;
|
||||
grid-row-gap: 5px;
|
||||
justify-content: left;
|
||||
}
|
||||
}
|
||||
|
||||
.defaultAvatar {
|
||||
@ -25,35 +28,29 @@
|
||||
border-radius: 50%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.defaultAvatar p {
|
||||
font-weight: 900;
|
||||
color: #666F7F;
|
||||
transform: translateY(1px);
|
||||
& p {
|
||||
font-weight: 900;
|
||||
color: #666f7f;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
}
|
||||
img.avatar {
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: max-content;
|
||||
aspect-ratio: 1;
|
||||
margin-right: 0.3em;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.identity .details {
|
||||
display: grid;
|
||||
grid-template-columns: 140px auto;
|
||||
grid-row-gap: 5px;
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
.counter {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.counter:before {
|
||||
content: '(';
|
||||
}
|
||||
.counter:after {
|
||||
content: ')';
|
||||
&:before {
|
||||
content: '(';
|
||||
}
|
||||
&:after {
|
||||
content: ')';
|
||||
}
|
||||
}
|
||||
|
||||
.chatInit {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user