Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chat thread with proof #550

Merged
merged 71 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f57eb86
Had to drop node to 16 for tests to work. See https://github.com/node…
timbl Feb 21, 2023
99d93f1
tests work only node 16. starting thread stuff
timbl Feb 22, 2023
a3df52b
Ass new icon for Reply
timbl Feb 24, 2023
ef62741
Thread display is basically working
timbl Feb 28, 2023
24320e3
Make new messages on thread etc
timbl Feb 28, 2023
372f872
async
timbl Mar 2, 2023
d577e51
lint issues
bourgeoa Mar 9, 2023
78404ed
merge main
bourgeoa Mar 9, 2023
a27cf0c
update messageTools.test.ts
bourgeoa Mar 9, 2023
86be5ab
skip test : complains if you have multiple bookmark docs
bourgeoa Mar 9, 2023
029ae1f
update package-lock.json
bourgeoa Mar 9, 2023
047d5bd
working on sentiments
timbl Mar 9, 2023
8415fae
hand merged
timbl Mar 9, 2023
7fe156e
limit srollback on thread
timbl Mar 9, 2023
ca09f65
initially load thread at the right place in timeline
timbl Mar 13, 2023
ff562b6
remove jss in acl
timea-solid Mar 20, 2023
90e6fe9
remove jss in header and footer, move stlys of acl in main style.js
timea-solid Mar 20, 2023
3369248
cleaned buttons from jss
timea-solid Mar 20, 2023
ed5d859
improved styles
timea-solid Mar 20, 2023
d980bb0
working on removing jss
timea-solid Mar 26, 2023
9daf358
fixing some more styles
timea-solid Mar 27, 2023
76bcd5f
updated snapshots accordingly
timea-solid Mar 27, 2023
53b74ba
avoid bing caught in loops
timbl Apr 4, 2023
8e5e7ac
added transform and test options to jest config
SharonStrats Apr 8, 2023
068520e
fixed lint errors
SharonStrats Apr 8, 2023
f9e2277
Merge branch 'main' into chat-threads
SharonStrats Apr 8, 2023
2dcc5e4
fixed broken styles
timea-solid Apr 9, 2023
36cc321
Update src/chat/bookmarks.js
bourgeoa Apr 10, 2023
d81bf22
Merge branch 'style' into chat-threads
timea-solid Apr 11, 2023
99dd2a8
Update src/chat/infinite.js
timea-solid Apr 11, 2023
eb85c49
Update src/chat/bookmarks.js
timea-solid Apr 11, 2023
ce90c57
Update src/chat/bookmarks.js
timea-solid Apr 11, 2023
f3028bd
Update src/chat/messageTools.js
timea-solid Apr 11, 2023
95bf305
Update src/chat/chatLogic.js
timea-solid Apr 11, 2023
e1d1a02
Update src/chat/messageTools.js
timea-solid Apr 11, 2023
c79215f
Update src/chat/thread.js
timea-solid Apr 11, 2023
ac08160
timbl code
timbl Apr 12, 2023
265a274
merged with sharon debug()
timbl Apr 12, 2023
efb1491
unblock initial load
timbl Apr 14, 2023
c6bf02e
merge main
bourgeoa Apr 16, 2023
b8d3fd1
Merge branch 'main' into chat-threads
bourgeoa May 26, 2023
f314621
merged thread & proof main
bourgeoa May 28, 2023
cf683a6
update to chat-threads commits
bourgeoa May 29, 2023
21f105c
lint
bourgeoa May 29, 2023
7b224a5
appendCurrentMesage() in thread
bourgeoa May 30, 2023
89c74e3
find thread
bourgeoa May 30, 2023
d7f5d53
edit comment
bourgeoa May 31, 2023
82276a6
updateMany
bourgeoa May 31, 2023
99da6a0
typing error
bourgeoa May 31, 2023
97b9e30
dist
bourgeoa May 31, 2023
1a4db38
moved root logic to own file
SharonStrats Jun 1, 2023
539c802
key tests
SharonStrats Jun 1, 2023
e5cde85
Merge branch 'main' into chat-thread-proof
timea-solid Jul 5, 2023
dd1547e
Merge branch 'chat-thread-proof' of https://github.com/solidos/solid-…
bourgeoa Dec 2, 2023
5744d91
Merge branch 'main' into chat-thread-proof
bourgeoa Dec 2, 2023
7c0461b
package-locj.json
bourgeoa Dec 2, 2023
6155852
Uint8Array issue
bourgeoa Dec 2, 2023
7e77c89
add jest-environment-jsdom.js
bourgeoa Dec 2, 2023
08d2a11
package-lock.json
bourgeoa Dec 3, 2023
8e703dc
privateKey Url
bourgeoa Feb 12, 2024
adfbed2
remove duplicate entries and cleanings
bourgeoa Feb 18, 2024
8d90d95
missing package-lock.json
bourgeoa Feb 18, 2024
74410c5
update minor dependencies
bourgeoa Mar 24, 2024
642b62a
nvmrc node v18.19.0
bourgeoa Mar 24, 2024
d1f9ae5
solid-dependencies
bourgeoa Mar 24, 2024
449dd33
2.4.33-beta
bourgeoa Mar 24, 2024
b5940ed
solidos dependencies
bourgeoa Mar 28, 2024
6e93e6b
2.4.33-beta3
bourgeoa Mar 28, 2024
b5bcb9e
solidos dependencies
bourgeoa Mar 28, 2024
4497ebd
2.4.33-beta4
bourgeoa Mar 28, 2024
17f11db
update dependencies
bourgeoa Apr 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,273 changes: 1,994 additions & 1,279 deletions dist/solid-ui.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/solid-ui.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/solid-ui.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/solid-ui.min.js.map

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ module.exports = {
'**/?(*.)+(spec|test).[tj]s?(x)' ],
setupFilesAfterEnv: [
'./test/helpers/setup.ts'
]
],
transformIgnorePatterns: ["/node_modules/(?!lit-html).+\\.js"],
testEnvironmentOptions: {
customExportConditions: ['node']
}
}
19,124 changes: 9,769 additions & 9,355 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
},
"homepage": "https://github.com/solidos/solid-ui",
"dependencies": {
"16": "^0.0.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is by mistake here?

"@noble/curves": "^1.0.0",
"acorn": "^7.4.1",
"escape-html": "^1.0.3",
Expand Down Expand Up @@ -108,7 +109,7 @@
"husky": "^7.0.4",
"isomorphic-fetch": "^3.0.0",
"jest": "^27.5.1",
"jsdom": "^19.0.0",
"jsdom": "^16.7.0",
"lint-staged": "^12.5.0",
"nock": "^13.3.0",
"react": "^17.0.2",
Expand Down
12 changes: 6 additions & 6 deletions src/chat/bookmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* @packageDocumentation
*/

/* global alert confirm */
import * as debug from '../debug'
import { icons } from '../iconBase'
import { media } from '../media/index'
Expand Down Expand Up @@ -99,7 +98,8 @@ export async function findBookmarkDocument (userContext) {
if (userContext.instances && userContext.instances.length > 0) {
userContext.bookmarkDocument = userContext.instances[0]
if (userContext.instances.length > 1) {
alert('More than one bookmark file! ' + userContext.instances)
debug.warn('More than one bookmark file! ' + userContext.instances) // @@ todo - deal with > 1
// Note: should pick up community bookmarks as well
}
} else {
if (userContext.publicProfile) {
Expand All @@ -111,7 +111,7 @@ export async function findBookmarkDocument (userContext) {
debug.log('Creating new bookmark file ' + newBookmarkFile)
await createIfNotExists(newBookmarkFile)
} catch (e) {
alert.error("Can't make fresh bookmark file:" + e)
debug.warn("Can't make fresh bookmark file:" + e)
return userContext
}
await registerInTypeIndex(
Expand All @@ -121,7 +121,7 @@ export async function findBookmarkDocument (userContext) {
)
userContext.bookmarkDocument = newBookmarkFile
} else {
alert('You seem to have no bookmark file and not even a profile file.')
debug.warn('You seem to have no bookmark file, nor even a profile file!')
}
}
return userContext
Expand Down Expand Up @@ -164,7 +164,7 @@ async function addBookmark (context, target) {
await updatePromise([], ins) // 20190118A
} catch (e) {
const msg = 'Making bookmark: ' + e
alert.error(msg)
debug.warn(msg)
return null
}
return bookmark
Expand All @@ -188,7 +188,7 @@ export async function toggleBookmark (userContext, target, bookmarkButton) {
debug.log('Bookmark deleted: ' + bookmarks[i])
} catch (e) {
debug.error('Cant delete bookmark:' + e)
alert('Cant delete bookmark:' + e)
debug.warn('Cannot delete bookmark:' + e)
}
}
} else {
Expand Down
81 changes: 76 additions & 5 deletions src/chat/chatLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class ChatChannel {
as a replacement for an existing one.
The old one iis left, and the two are linked
*/
async updateMessage (text, oldMsg = null, deleteIt) {
async updateMessage (text, oldMsg = null, deleteIt, thread = null) {
const sts = []
const now = new Date()
const timestamp = '' + now.getTime()
Expand All @@ -58,7 +58,13 @@ export class ChatChannel {
if (oldMsg) { // edit message replaces old one
const oldMsgMaker = store.any(oldMsg, ns.foaf('maker')) // may not be needed here, but needed on READ
if (oldMsgMaker.uri === me.uri) {
sts.push($rdf.st(mostRecentVersion(oldMsg), ns.dct('isReplacedBy'), message, chatDocument))
const oldMsgMostRecentVersion = await mostRecentVersion(oldMsg)
sts.push($rdf.st(oldMsgMostRecentVersion, ns.dct('isReplacedBy'), message, chatDocument))
// if oldMsg has_reply => add has_reply to message
const oldMsgThread = store.any(oldMsgMostRecentVersion, ns.sioc('has_reply'))
if (oldMsgThread) {
sts.push($rdf.st(message, ns.sioc('has_reply'), oldMsgThread, chatDocument))
}
if (deleteIt) { // we need to add a specific signature, else anyone can delete a msg ?
sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument))
}
Expand Down Expand Up @@ -89,8 +95,14 @@ export class ChatChannel {
const sig = signMsg(msg, privateKey)
sts.push($rdf.st(message, $rdf.sym(`${SEC}proofValue`), $rdf.lit(sig), chatDocument))
}
if (thread) {
sts.push($rdf.st(thread, ns.sioc('has_member'), message, chatDocument))
if (!thread.doc().sameTerm(message.doc())) {
sts.push($rdf.st(thread, ns.sioc('has_member'), message, thread.doc()))
}
}
try {
await store.updater.update([], sts)
await store.updater.updateMany([], sts)
} catch (err) {
const errMsg = 'Error saving chat message: ' + err
debug.warn(errMsg)
Expand All @@ -107,21 +119,80 @@ export class ChatChannel {
async deleteMessage (message) {
return this.updateMessage('(message deleted)', message, true)
}

// Create a new thread of replies to the thread root message
// or return one which already exists

async createThread (threadRoot) {
const already = store.each(threadRoot, ns.sioc('has_reply'), null, threadRoot.doc())
.filter(thread => store.holds(thread, ns.rdf('type'), ns.sioc('Thread'), thread.doc()))
if (already.length > 0) return already[0]

const thread = $rdf.sym(threadRoot.uri + '-thread')
const insert = [
$rdf.st(thread, ns.rdf('type'), ns.sioc('Thread'), thread.doc()),
$rdf.st(threadRoot, ns.sioc('has_reply'), thread, thread.doc())
]
await store.updater.update([], insert)
return thread
}
} // class ChatChannel

export function originalVersion (message) {
// ////////// Utility functions

// Have to not loop forever if fed loops
export async function allVersions (message) {
const versions = [message]
const done = {}
done[message.uri] = true
let m = message
while (true) { // earlier?
const prev = store.any(null, ns.dct('isReplacedBy'), m, m.doc())
if (!prev || done[prev.uri]) break
await store.fetcher.load(prev)
versions.unshift(prev)
done[prev.uri] = true
m = prev
}
m = message
while (true) { // later?
const next = store.any(m, ns.dct('isReplacedBy'), null, m.doc())
if (!next || done[next.uri]) break
versions.push(next)
done[next.uri] = true
m = next
}
return versions
}

export async function originalVersion (message) {
let msg = message
const done = {}
// done[message.uri] = true
while (msg) {
if (done[msg.uri]) {
debug.error('originalVersion: verion loop' + message)
return message
}
done[msg.uri] = true
message = msg
await store.fetcher.load(message)
msg = store.any(null, ns.dct('isReplacedBy'), message, message.doc())
}
return message
}

export function mostRecentVersion (message) {
export async function mostRecentVersion (message) {
let msg = message
const done = {}
while (msg) {
if (done[msg.uri]) {
debug.error('mostRecentVersion: verion loop' + message)
return message
}
done[msg.uri] = true
message = msg
await store.fetcher.load(message)
msg = store.any(message, ns.dct('isReplacedBy'), null, message.doc())
}
return message
Expand Down
71 changes: 42 additions & 29 deletions src/chat/dateFolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
* This tracks data stored in dated folders and sub-folders
*
*/

import * as debug from '../debug'
import { store } from 'solid-logic'

import * as ns from '../ns'
import * as $rdf from 'rdflib' // pull in first avoid cross-refs

export async function emptyLeaf (leafDocument) {
await store.fetcher.load(leafDocument)
// files can have seealso links. skip ones with no leafObjects with a date
return !(
store.statementsMatching(null, ns.dct('created'), null, leafDocument)
.length > 0
)
}

/**
* Track back through the YYYY/MM/DD tree to find the previous/next day
*/
Expand Down Expand Up @@ -45,7 +52,6 @@ export class DateFolder {
}

async loadPrevious (date, backwards) {
const thisDateFolder = this
async function previousPeriod (file, level) {
function younger (x) {
if (backwards ? x.uri >= file.uri : x.uri <= file.uri) return false // later than we want or same -- looking for different
Expand All @@ -60,33 +66,21 @@ export class DateFolder {
return true
}

async function lastNonEmpty (siblings) {
function lastOrFirst (siblings) {
siblings = siblings.filter(suitable)
siblings.sort() // chronological order
if (!backwards) siblings.reverse()
if (level !== 3) return siblings.pop() // only length chck final leverl
while (siblings.length) {
const folder = siblings.pop()
const leafDocument = store.sym(folder.uri + thisDateFolder.leafFileName)
await store.fetcher.load(leafDocument)
// files can have seealso links. skip ones with no leafObjects with a date
if (
store.statementsMatching(null, ns.dct('created'), null, leafDocument)
.length > 0
) {
return folder
}
}
return null
return siblings.pop() // date folder
}
// debug.log(' previousPeriod level' + level + ' file ' + file)
const parent = file.dir()
try {
await store.fetcher.load(parent)
let siblings = store.each(parent, ns.ldp('contains'))
siblings = siblings.filter(younger)
const folder = await lastNonEmpty(siblings)
const folder = lastOrFirst(siblings)
if (folder) return folder
debug.log(' parent no suitable offspring ' + parent)
} catch (err) {
if (err.response && err.response.status && err.response.status === 404) {
debug.log('Error 404 for chat parent file ' + parent)
Expand All @@ -96,24 +90,43 @@ export class DateFolder {
throw (new Error(`*** ${err.message} for chat folder ${parent}`))
}
}

if (level === 0) return null // 3:day, 2:month, 1: year 0: no
if (level === 0) {
debug.log('loadPrevious: returning as level is zero')
return null // 3:day, 2:month, 1: year 0: no
}

const uncle = await previousPeriod(parent, level - 1)
if (!uncle) return null // reached first ever
if (!uncle) {
debug.log(' previousPeriod: nothing left before. ', parent)
return null // reached first ever
}
await store.fetcher.load(uncle)
const cousins = store.each(uncle, ns.ldp('contains'))
const result = await lastNonEmpty(cousins)
const result = lastOrFirst(cousins)
debug.log(' previousPeriod: returning cousins at level ' + level, cousins)
debug.log(' previousPeriod: returning result at level ' + level, result)

return result
} // previousPeriod

const folder = this.leafDocumentFromDate(date).dir()
const found = await previousPeriod(folder, 3)
if (found) {
const doc = store.sym(found.uri + this.leafFileName)
return this.dateFromLeafDocument(doc)
let folder = this.leafDocumentFromDate(date).dir()
while (true) {
const found = await previousPeriod(folder, 3)
if (found) {
const leafDocument = store.sym(found.uri + this.leafFileName)
const nextDate = this.dateFromLeafDocument(leafDocument)
if (!await emptyLeaf(leafDocument)) {
return nextDate
} else {
debug.log(' loadPrevious: skipping empty ' + leafDocument)
date = nextDate
folder = this.leafDocumentFromDate(date).dir()
debug.log(' loadPrevious: moved back to ' + folder)
}
} else {
return null // no more left
}
}
return null
} // loadPrevious

async firstLeaf (backwards) {
Expand Down
Loading