Skip to content
Next
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Minds Frontend
Project
Project
Details
Activity
Releases
Dependency List
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
828
Issues
828
List
Boards
Labels
Service Desk
Milestones
Merge Requests
71
Merge Requests
71
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Frontend
Commits
94ed6cc6
Commit
94ed6cc6
authored
1 hour ago
by
Mark Harding
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(refactor): re-implement boost and block
parent
9dc4d33a
refactor/es-feeds
1 merge request
!373
Refactor/es feeds
Pipeline
#67936714
failed with stage
in 8 minutes and 11 seconds
Changes
22
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
255 additions
and
308 deletions
+255
-308
app.component.ts
src/app/app.component.ts
+0
-4
common.module.ts
src/app/common/common.module.ts
+2
-1
featured-content.service.ts
...n/components/featured-content/featured-content.service.ts
+22
-3
block-list.service.ts
src/app/common/services/block-list.service.ts
+30
-56
boosted-content.service.ts
src/app/common/services/boosted-content.service.ts
+7
-43
entities.service.ts
src/app/common/services/entities.service.ts
+80
-19
feeds.service.ts
src/app/common/services/feeds.service.ts
+22
-22
sorted.component.html
src/app/modules/channels/sorted/sorted.component.html
+1
-1
sorted.component.ts
src/app/modules/channels/sorted/sorted.component.ts
+3
-3
sorted.component.html
src/app/modules/groups/profile/feed/sorted.component.html
+1
-1
sorted.component.ts
src/app/modules/groups/profile/feed/sorted.component.ts
+1
-1
boost-rotator.component.html
...dules/newsfeed/boost-rotator/boost-rotator.component.html
+2
-2
boost-rotator.component.ts
...modules/newsfeed/boost-rotator/boost-rotator.component.ts
+31
-91
sorted.component.html
src/app/modules/newsfeed/feeds/sorted.component.html
+1
-1
sorted.component.ts
src/app/modules/newsfeed/feeds/sorted.component.ts
+1
-1
subscribed.component.html
src/app/modules/newsfeed/feeds/subscribed.component.html
+1
-1
subscribed.component.ts
src/app/modules/newsfeed/feeds/subscribed.component.ts
+1
-1
tiles.component.html
src/app/modules/newsfeed/feeds/tiles.component.html
+3
-1
single.component.ts
src/app/modules/newsfeed/single/single.component.ts
+20
-15
blocked-channels.component.html
...settings/blocked-channels/blocked-channels.component.html
+2
-2
blocked-channels.component.ts
...s/settings/blocked-channels/blocked-channels.component.ts
+22
-37
providers.ts
src/app/services/providers.ts
+2
-2
No files found.
src/app/app.component.ts
View file @
94ed6cc6
...
...
@@ -96,10 +96,6 @@ export class Minds {
this
.
webtorrent
.
setUp
();
this
.
themeService
.
setUp
();
if
(
this
.
session
.
isLoggedIn
())
{
this
.
blockListService
.
sync
();
}
}
ngOnDestroy
()
{
...
...
This diff is collapsed.
Click to expand it.
src/app/common/common.module.ts
View file @
94ed6cc6
...
...
@@ -94,6 +94,7 @@ import { UserMenuComponent } from "./layout/v2-topbar/user-menu.component";
import
{
FeaturedContentComponent
}
from
"./components/featured-content/featured-content.component"
;
import
{
FeaturedContentService
}
from
"./components/featured-content/featured-content.service"
;
import
{
BoostedContentService
}
from
"./services/boosted-content.service"
;
import
{
FeedsService
}
from
'./services/feeds.service'
;
import
{
EntitiesService
}
from
"./services/entities.service"
;
import
{
BlockListService
}
from
"./services/block-list.service"
;
import
{
SettingsService
}
from
"../modules/settings/settings.service"
;
...
...
@@ -310,7 +311,7 @@ import { HorizontalInfiniteScroll } from "./components/infinite-scroll/horizonta
{
provide
:
FeaturedContentService
,
useFactory
:
boostedContentService
=>
new
FeaturedContentService
(
boostedContentService
),
deps
:
[
BoostedContent
Service
],
deps
:
[
Feeds
Service
],
}
],
entryComponents
:
[
...
...
This diff is collapsed.
Click to expand it.
src/app/common/components/featured-content/featured-content.service.ts
View file @
94ed6cc6
import
{
Injectable
}
from
"@angular/core"
;
import
{
BoostedContentService
}
from
"../../services/boosted-content.service"
;
import
{
filter
,
first
,
map
,
switchMap
}
from
'rxjs/operators'
;
import
{
FeedsService
}
from
"../../services/feeds.service"
;
@
Injectable
()
export
class
FeaturedContentService
{
offset
:
number
=
-
1
;
constructor
(
protected
boostedContentService
:
BoostedContent
Service
,
protected
feedsService
:
Feeds
Service
,
)
{
this
.
feedsService
.
setLimit
(
50
)
.
setOffset
(
0
)
.
setEndpoint
(
'api/v2/boost/feed'
)
.
fetch
();
}
async
fetch
()
{
return
await
this
.
boostedContentService
.
fetch
();
return
await
this
.
feedsService
.
feed
.
pipe
(
filter
(
feed
=>
feed
.
length
>
0
),
first
(),
map
(
feed
=>
feed
[
this
.
offset
++
]),
switchMap
(
async
entity
=>
{
if
(
!
entity
)
return
false
;
return
await
entity
.
pipe
(
first
()).
toPromise
();
}),
).
toPromise
();
}
}
This diff is collapsed.
Click to expand it.
src/app/common/services/block-list.service.ts
View file @
94ed6cc6
import
{
Injectable
}
from
"@angular/core"
;
import
{
BehaviorSubject
}
from
'rxjs'
;
import
{
Client
}
from
"../../services/api/client"
;
import
{
Session
}
from
"../../services/session"
;
import
{
Storage
}
from
'../../services/storage'
;
import
AsyncLock
from
"../../helpers/async-lock"
;
...
...
@@ -12,88 +14,60 @@ import AsyncStatus from "../../helpers/async-status";
@
Injectable
()
export
class
BlockListService
{
protected
blockListSync
:
BlockListSync
;
protected
syncLock
=
new
AsyncLock
();
protected
status
=
new
AsyncStatus
();
blocked
:
BehaviorSubject
<
string
[]
>
;
constructor
(
protected
client
:
Client
,
protected
session
:
Session
,
protected
storage
:
Storage
)
{
this
.
setUp
();
this
.
blocked
=
new
BehaviorSubject
(
JSON
.
parse
(
this
.
storage
.
get
(
'blocked'
)));
this
.
fetch
();
}
async
setUp
()
{
this
.
blockListSync
=
new
BlockListSync
(
new
MindsClientHttpAdapter
(
this
.
client
),
await
browserStorageAdapterFactory
(
'minds-block-190314'
),
);
this
.
blockListSync
.
setUp
();
//
fetch
()
{
this
.
client
.
get
(
'api/v1/block'
,
{
sync
:
1
,
limit
:
10000
})
.
then
((
response
:
any
)
=>
{
if
(
response
.
guids
!==
this
.
blocked
.
getValue
())
this
.
blocked
.
next
(
response
.
guids
);
// re-emit as we have a change
this
.
status
.
done
();
// Prune on session changes
this
.
session
.
isLoggedIn
((
is
:
boolean
)
=>
{
if
(
is
)
{
this
.
sync
();
}
else
{
this
.
prune
();
}
});
this
.
storage
.
set
(
'blocked'
,
JSON
.
stringify
(
response
.
guids
));
// save to storage
});
return
this
;
}
async
sync
()
{
await
this
.
status
.
untilReady
();
if
(
this
.
syncLock
.
isLocked
())
{
return
false
;
}
this
.
syncLock
.
lock
();
this
.
blockListSync
.
sync
();
this
.
syncLock
.
unlock
();
}
async
prune
()
{
await
this
.
status
.
untilReady
();
if
(
this
.
syncLock
.
isLocked
())
{
return
false
;
}
}
this
.
syncLock
.
lock
();
this
.
blockListSync
.
prune
();
this
.
syncLock
.
unlock
();
async
get
()
{
}
async
getList
()
{
await
this
.
status
.
untilReady
();
await
this
.
syncLock
.
untilUnlocked
();
return
await
this
.
blockListSync
.
getList
();
return
this
.
blocked
.
getValue
();
}
async
add
(
guid
:
string
)
{
await
this
.
status
.
untilReady
();
await
this
.
syncLock
.
untilUnlocked
();
return
await
this
.
blockListSync
.
add
(
guid
);
const
guids
=
this
.
blocked
.
getValue
();
if
(
guids
.
indexOf
(
guid
)
<
0
)
this
.
blocked
.
next
([...
guids
,
...[
guid
]]);
this
.
storage
.
set
(
'blocked'
,
JSON
.
stringify
(
this
.
blocked
.
getValue
())
);
}
async
remove
(
guid
:
string
)
{
await
this
.
status
.
untilReady
();
await
this
.
syncLock
.
untilUnlocked
();
const
guids
=
this
.
blocked
.
getValue
();
const
index
=
guids
.
indexOf
(
guid
);
if
(
index
>
-
1
)
{
guids
.
splice
(
index
,
1
);
}
return
await
this
.
blockListSync
.
remove
(
guid
);
this
.
blocked
.
next
(
guids
);
this
.
storage
.
set
(
'blocked'
,
JSON
.
stringify
(
this
.
blocked
.
getValue
()));
}
static
_
(
client
:
Client
,
session
:
Session
)
{
return
new
BlockListService
(
client
,
session
);
static
_
(
client
:
Client
,
session
:
Session
,
storage
:
Storage
)
{
return
new
BlockListService
(
client
,
session
,
storage
);
}
}
This diff is collapsed.
Click to expand it.
src/app/common/services/boosted-content.service.ts
View file @
94ed6cc6
...
...
@@ -16,10 +16,6 @@ import AsyncStatus from "../../helpers/async-status";
@
Injectable
()
export
class
BoostedContentService
{
protected
boostedContentSync
:
BoostedContentSync
;
protected
status
=
new
AsyncStatus
();
constructor
(
protected
client
:
Client
,
protected
session
:
Session
,
...
...
@@ -31,59 +27,27 @@ export class BoostedContentService {
}
async
setUp
()
{
this
.
boostedContentSync
=
new
BoostedContentSync
(
new
MindsClientHttpAdapter
(
this
.
client
),
await
browserStorageAdapterFactory
(
'minds-boosted-content-190314'
),
5
*
60
,
// Stale after 5 minutes
15
*
60
,
// Cooldown of 15 minutes
500
,
);
this
.
boostedContentSync
.
setResolvers
({
currentUser
:
()
=>
this
.
session
.
getLoggedInUser
()
&&
this
.
session
.
getLoggedInUser
().
guid
,
blockedUserGuids
:
async
()
=>
await
this
.
blockListService
.
getList
(),
fetchEntities
:
async
guids
=>
await
this
.
entitiesService
.
fetch
(
guids
),
});
//
this
.
boostedContentSync
.
setUp
();
//
this
.
status
.
done
();
// User session / rating handlers
if
(
this
.
session
.
isLoggedIn
())
{
this
.
boostedContentSync
.
setRating
(
this
.
session
.
getLoggedInUser
().
boost_rating
||
null
);
//
this.boostedContentSync.setRating(this.session.getLoggedInUser().boost_rating || null);
}
this
.
session
.
isLoggedIn
((
is
:
boolean
)
=>
{
if
(
is
)
{
this
.
boostedContentSync
.
setRating
(
this
.
session
.
getLoggedInUser
().
boost_rating
||
null
);
}
else
{
this
.
boostedContentSync
.
destroy
();
// this.boostedContentSync.setRating(this.session.getLoggedInUser().boost_rating || null);
}
});
// Garbage collection
this
.
boostedContentSync
.
gc
();
setTimeout
(()
=>
this
.
boostedContentSync
.
gc
(),
5
*
60
*
1000
);
// Every 5 minutes
// Rating changes hook
this
.
settingsService
.
ratingChanged
.
subscribe
(
rating
=>
this
.
boostedContentSync
.
changeRating
(
rating
));
//
this.settingsService.ratingChanged.subscribe(rating => this.boostedContentSync.changeRating(rating));
}
async
get
(
opts
=
{})
{
await
this
.
status
.
untilReady
();
return
await
this
.
boostedContentSync
.
get
(
opts
);
setEndpoint
(
endpoint
:
string
)
{
}
async
fetch
(
opts
=
{})
{
await
this
.
status
.
untilReady
();
return
await
this
.
boostedContentSync
.
fetch
(
opts
);
fetch
(
opts
=
{}):
BoostedContentService
{
return
this
;
}
}
This diff is collapsed.
Click to expand it.
src/app/common/services/entities.service.ts
View file @
94ed6cc6
import
{
Injectable
}
from
"@angular/core"
;
import
{
BehaviorSubject
,
Observable
}
from
'rxjs'
;
import
{
first
}
from
'rxjs/operators'
;
import
{
Client
}
from
"../../services/api"
;
import
{
BlockListService
}
from
'./block-list.service'
;
import
MindsClientHttpAdapter
from
'../../lib/minds-sync/adapters/MindsClientHttpAdapter.js'
;
import
browserStorageAdapterFactory
from
"../../helpers/browser-storage-adapter-factory"
;
...
...
@@ -7,44 +10,61 @@ import EntitiesSync from '../../lib/minds-sync/services/EntitiesSync.js';
import
AsyncStatus
from
"../../helpers/async-status"
;
import
normalizeUrn
from
"../../helpers/normalize-urn"
;
@
Injectable
()
export
class
EntitiesService
{
type
EntityObservable
=
BehaviorSubject
<
Object
>
;
protected
entitiesSync
:
EntitiesSync
;
interface
EntityObservables
{
[
key
:
string
]:
EntityObservable
}
protected
status
=
new
AsyncStatus
();
@
Injectable
()
export
class
EntitiesService
{
entities
:
Object
=
{};
entities
:
EntityObservables
=
{};
constructor
(
protected
client
:
Client
protected
client
:
Client
,
protected
blockListService
:
BlockListService
,
)
{
}
async
getFromFeed
(
feed
):
Promise
<
Object
[]
>
{
async
getFromFeed
(
feed
):
Promise
<
EntityObservable
[]
>
{
if
(
!
feed
||
!
feed
.
length
)
{
return
[];
}
const
blockedGuids
=
await
this
.
blockListService
.
blocked
.
pipe
(
first
()).
toPromise
();
const
urnsToFetch
=
[];
const
urnsToResync
=
[];
const
entities
=
[];
for
(
const
feedItem
of
feed
)
{
if
(
feedItem
.
entity
)
{
this
.
entities
[
feedItem
.
urn
]
=
feedItem
.
entity
;
this
.
addEntity
(
feedItem
.
entity
)
;
}
if
(
!
this
.
entities
[
feedItem
.
urn
])
{
urnsToFetch
.
push
(
feedItem
.
urn
);
}
if
(
this
.
entities
[
feedItem
.
urn
]
&&
!
feedItem
.
entity
)
{
urnsToResync
.
push
(
feedItem
.
urn
);
}
}
// Fetch entities we don't have
if
(
urnsToFetch
.
length
)
{
await
this
.
fetch
(
urnsToFetch
);
}
// Fetch entities, asynchronously, with no need to wait
if
(
urnsToResync
.
length
)
{
this
.
fetch
(
urnsToResync
);
}
for
(
const
feedItem
of
feed
)
{
entities
.
push
(
this
.
entities
[
feedItem
.
urn
]);
if
(
blockedGuids
.
indexOf
(
feedItem
.
owner_guid
)
<
0
)
entities
.
push
(
this
.
entities
[
feedItem
.
urn
]);
}
return
entities
;
...
...
@@ -55,29 +75,70 @@ export class EntitiesService {
* @param urn string
* @return Object
*/
async
single
(
urn
:
string
):
Promise
<
Object
|
false
>
{
single
(
urn
:
string
):
EntityObservable
{
if
(
urn
.
indexOf
(
'urn:'
)
<
0
)
{
// not a urn, so treat as a guid
urn
=
`urn:activity:
${
urn
}
`
;
// and assume activity
}
if
(
!
this
.
entities
[
urn
])
{
await
this
.
fetch
([
urn
]);
}
this
.
entities
[
urn
]
=
new
BehaviorSubject
(
null
);
this
.
fetch
([
urn
]);
// Update in the background
return
this
.
entities
[
urn
];
}
/**
* Fetch entities
* @param urns string[]
* @return []
*/
async
fetch
(
urns
:
string
[]):
Promise
<
Array
<
Object
>>
{
const
response
:
any
=
await
this
.
client
.
get
(
'api/v2/entities/'
,
{
urns
});
try
{
const
response
:
any
=
await
this
.
client
.
get
(
'api/v2/entities/'
,
{
urns
});
for
(
const
entity
of
response
.
entities
)
{
this
.
entities
[
entity
.
urn
]
=
entity
;
if
(
!
response
.
entities
.
length
)
{
for
(
const
urn
of
urns
)
{
this
.
addNotFoundEntity
(
urn
);
}
}
for
(
const
entity
of
response
.
entities
)
{
this
.
addEntity
(
entity
);
}
return
response
;
}
catch
(
err
)
{
// TODO: find a good way of sending server errors to subscribers
}
}
return
response
.
entities
;
/**
* Add or resync an entity
* @param entity
* @return void
*/
addEntity
(
entity
):
void
{
if
(
this
.
entities
[
entity
.
urn
])
{
this
.
entities
[
entity
.
urn
].
next
(
entity
);
}
else
{
this
.
entities
[
entity
.
urn
]
=
new
BehaviorSubject
(
entity
);
}
}
/**
* Register a urn as not found
* @param urn string
* @return void
*/
addNotFoundEntity
(
urn
):
void
{
if
(
!
this
.
entities
[
urn
])
{
this
.
entities
[
urn
]
=
new
BehaviorSubject
(
null
);
}
this
.
entities
[
urn
].
error
(
"Not found"
);
}
static
_
(
client
:
Client
)
{
return
new
EntitiesService
(
client
);
static
_
(
client
:
Client
,
blockListService
:
BlockListService
)
{
return
new
EntitiesService
(
client
,
blockListService
);
}
}
This diff is collapsed.
Click to expand it.
src/app/common/services/feeds.service.ts
View file @
94ed6cc6
...
...
@@ -13,7 +13,7 @@ import FeedsSync from '../../lib/minds-sync/services/FeedsSync.js';
import
hashCode
from
"../../helpers/hash-code"
;
import
AsyncStatus
from
"../../helpers/async-status"
;
import
{
BehaviorSubject
,
Observable
,
of
,
forkJoin
,
combineLatest
}
from
"rxjs"
;
import
{
take
,
switchMap
,
map
,
tap
}
from
"rxjs/operators"
;
import
{
take
,
switchMap
,
map
,
tap
,
skipWhile
,
first
,
filter
}
from
"rxjs/operators"
;
export
type
FeedsServiceGetParameters
=
{
endpoint
:
string
;
...
...
@@ -36,17 +36,14 @@ export type FeedsServiceGetResponse = {
@
Injectable
()
export
class
FeedsService
{
protected
feedsSync
:
FeedsSync
;
protected
status
=
new
AsyncStatus
();
limit
:
BehaviorSubject
<
number
>
=
new
BehaviorSubject
(
12
);
offset
:
BehaviorSubject
<
number
>
=
new
BehaviorSubject
(
0
);
pageSize
:
Observable
<
number
>
;
endpoint
:
string
=
''
;
params
:
any
=
{
sync
:
1
};
rawFeed
:
BehaviorSubject
<
Object
[]
>
=
new
BehaviorSubject
([]);
feed
:
Observable
<
Object
[]
>
;
feed
:
Observable
<
BehaviorSubject
<
Object
>
[]
>
;
inProgress
:
BehaviorSubject
<
boolean
>
=
new
BehaviorSubject
(
true
);
hasMore
:
Observable
<
boolean
>
;
...
...
@@ -56,26 +53,29 @@ export class FeedsService {
protected
entitiesService
:
EntitiesService
,
protected
blockListService
:
BlockListService
,
)
{
this
.
pageSize
=
this
.
offset
.
pipe
(
map
(
offset
=>
this
.
limit
.
getValue
()
+
offset
)
);
this
.
feed
=
this
.
rawFeed
.
pipe
(
tap
(()
=>
{
this
.
inProgress
.
next
(
true
);
tap
(
feed
=>
{
if
(
feed
.
length
)
this
.
inProgress
.
next
(
true
);
}),
switchMap
(
async
feed
=>
{
return
feed
.
slice
(
0
,
await
this
.
pageSize
.
pipe
(
first
()).
toPromise
())
}),
map
(
feed
=>
feed
.
slice
(
0
,
this
.
limit
.
getValue
()
+
this
.
offset
.
getValue
())),
switchMap
(
feed
=>
this
.
entitiesService
.
getFromFeed
(
feed
)),
tap
(
()
=>
{
if
(
this
.
offset
.
getValue
()
>
0
)
{
tap
(
feed
=>
{
if
(
feed
.
length
)
// We should have skipped but..
this
.
inProgress
.
next
(
false
);
}
}),
);
this
.
hasMore
=
combineLatest
(
this
.
rawFeed
,
this
.
inProgress
,
this
.
limit
,
this
.
offset
).
pipe
(
this
.
hasMore
=
combineLatest
(
this
.
rawFeed
,
this
.
inProgress
,
this
.
offset
).
pipe
(
map
(
values
=>
{
const
feed
=
values
[
0
];
const
inProgress
=
values
[
1
];
const
limit
=
values
[
2
];
const
offset
=
values
[
3
];
return
inProgress
?
true
:
(
limit
+
offset
)
<=
feed
.
length
;
const
offset
=
values
[
2
];
return
inProgress
||
feed
.
length
>
offset
;
}),
);
}
...
...
@@ -107,6 +107,7 @@ export class FeedsService {
this
.
inProgress
.
next
(
true
);
this
.
client
.
get
(
this
.
endpoint
,
{...
this
.
params
,
...{
limit
:
150
}})
// Over 12 scrolls
.
then
((
response
:
any
)
=>
{
this
.
inProgress
.
next
(
false
);
this
.
rawFeed
.
next
(
response
.
entities
);
})
.
catch
(
err
=>
{
...
...
@@ -115,14 +116,15 @@ export class FeedsService {
}
loadMore
():
FeedsService
{
this
.
setOffset
(
this
.
limit
.
getValue
()
+
this
.
offset
.
getValue
());
this
.
rawFeed
.
next
(
this
.
rawFeed
.
getValue
());
if
(
!
this
.
inProgress
.
getValue
())
{
this
.
setOffset
(
this
.
limit
.
getValue
()
+
this
.
offset
.
getValue
());
this
.
rawFeed
.
next
(
this
.
rawFeed
.
getValue
());
}
return
this
;
}
clear
():
FeedsService
{
this
.
offset
.
next
(
0
);
this
.
inProgress
.
next
(
true
);
this
.
rawFeed
.
next
([]);
return
this
;
}
...
...
@@ -132,8 +134,6 @@ export class FeedsService {
}
async
destroy
()
{
await
this
.
status
.
untilReady
();
return
await
this
.
feedsSync
.
destroy
();
}
static
_
(
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/channels/sorted/sorted.component.html
View file @
94ed6cc6
...
...
@@ -27,7 +27,7 @@
<ng-template
#
entityListView
>
<m-newsfeed
__entity
*
ngFor=
"let entity of (feedsService.feed | async); let i = index"
[
entity
]="
entity
"
[
entity
]="
entity
|
async
"
[
slot
]="
i
+
1
"
></m-newsfeed
__entity
>
</ng-template>
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/channels/sorted/sorted.component.ts
View file @
94ed6cc6
...
...
@@ -68,7 +68,7 @@ export class ChannelSortedComponent implements OnInit {
@
ViewChild
(
'poster'
)
protected
poster
:
PosterComponent
;
constructor
(
p
rotected
feedsService
:
FeedsService
,
p
ublic
feedsService
:
FeedsService
,
protected
service
:
SortedService
,
protected
session
:
Session
,
protected
clientMetaService
:
ClientMetaService
,
...
...
@@ -111,8 +111,8 @@ export class ChannelSortedComponent implements OnInit {
this
.
detectChanges
();
}
load
More
()
{
this
.
feedsService
.
setOffset
(
this
.
feedsService
.
offset
.
getValue
()
+
12
);
load
Next
()
{
this
.
feedsService
.
loadMore
(
);
}
setFilter
(
type
:
string
)
{
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/groups/profile/feed/sorted.component.html
View file @
94ed6cc6
...
...
@@ -38,7 +38,7 @@
<minds-activity
*
ngFor=
"let entity of (feedsService.feed | async); let i = index"
class=
"mdl-card item"
[
object
]="
entity
"
[
object
]="
entity
|
async
"
[
canDelete
]="
group
['
is:owner
']
||
group
['
is:moderator
']"
(
delete
)="
delete
(
entity
)"
[
slot
]="
i
+
1
"
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/groups/profile/feed/sorted.component.ts
View file @
94ed6cc6
...
...
@@ -65,7 +65,7 @@ export class GroupProfileFeedSortedComponent {
constructor
(
protected
service
:
GroupsService
,
p
rotected
feedsService
:
FeedsService
,
p
ublic
feedsService
:
FeedsService
,
protected
sortedService
:
SortedService
,
protected
session
:
Session
,
protected
router
:
Router
,
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/boost-rotator/boost-rotator.component.html
View file @
94ed6cc6
...
...
@@ -23,9 +23,9 @@
<ng-container
*
ngIf=
"!disabled"
>
<minds-activity
*
ngFor=
"let boost of boosts; let i = index"
*
ngFor=
"let boost of boosts; let i = index"
[
object
]="
boost
"
[
boostToggle
]="
boost
.
boostToggl
e
"
[
boostToggle
]="
tru
e
"
[
class
]="'
mdl-card
m-border
item
m-boost-rotator-item
m-boost-rotator-item-
'
+
i
"
visible=
"true"
[
hidden
]="
i
!=
currentPosition
"
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/boost-rotator/boost-rotator.component.ts
View file @
94ed6cc6
import
{
ChangeDetectorRef
,
Component
,
ElementRef
,
Injector
,
QueryList
,
SkipSelf
,
ViewChildren
}
from
'@angular/core'
;
import
{
first
}
from
'rxjs/operators'
;
import
{
ScrollService
}
from
'../../../services/ux/scroll'
;
import
{
Client
}
from
'../../../services/api'
;
...
...
@@ -12,6 +13,7 @@ import { NewsfeedBoostService } from '../newsfeed-boost.service';
import
{
SettingsService
}
from
'../../settings/settings.service'
;
import
{
FeaturesService
}
from
"../../../services/features.service"
;
import
{
BoostedContentService
}
from
"../../../common/services/boosted-content.service"
;
import
{
FeedsService
}
from
"../../../common/services/feeds.service"
;
import
{
ClientMetaService
}
from
"../../../common/services/client-meta.service"
;
@
Component
({
...
...
@@ -24,7 +26,10 @@ import { ClientMetaService } from "../../../common/services/client-meta.service"
'(mouseout)'
:
'mouseOut()'
},
inputs
:
[
'interval'
,
'channel'
],
providers
:
[
ClientMetaService
],
providers
:
[
ClientMetaService
,
FeedsService
,
],
templateUrl
:
'boost-rotator.component.html'
,
})
...
...
@@ -66,7 +71,7 @@ export class NewsfeedBoostRotatorComponent {
public
service
:
NewsfeedBoostService
,
private
cd
:
ChangeDetectorRef
,
protected
featuresService
:
FeaturesService
,
p
rotected
boostedContentService
:
BoostedContent
Service
,
p
ublic
feedsService
:
Feeds
Service
,
protected
clientMetaService
:
ClientMetaService
,
@
SkipSelf
()
injector
:
Injector
,
)
{
...
...
@@ -91,43 +96,32 @@ export class NewsfeedBoostRotatorComponent {
this
.
scroll_listener
=
this
.
scroll
.
listenForView
().
subscribe
(()
=>
this
.
isVisible
());
this
.
paused
=
this
.
service
.
isBoostPaused
();
}
async
load
()
{
if
(
this
.
featuresService
.
has
(
'es-feeds'
))
{
return
await
this
.
loadFromService
();
}
else
{
return
await
this
.
loadLegacy
();
}
this
.
feedsService
.
feed
.
subscribe
(
async
boosts
=>
{
if
(
!
boosts
.
length
)
return
;
for
(
const
boost
of
boosts
)
{
if
(
boost
)
this
.
boosts
.
push
(
await
boost
.
pipe
(
first
()).
toPromise
());
}
if
(
this
.
currentPosition
===
0
)
{
this
.
recordImpression
(
this
.
currentPosition
,
true
);
}
});
}
async
loadFromService
()
{
load
()
{
try
{
const
boosts
=
await
this
.
boostedContentService
.
get
({
limit
:
10
,
offset
:
8
,
exclude
:
this
.
boosts
.
map
(
boost
=>
boost
.
urn
),
passive
:
true
,
});
if
(
!
boosts
||
!
boosts
.
length
)
{
throw
new
Error
(
''
);
// Legacy behavior
}
this
.
boosts
.
push
(...
boosts
);
if
(
this
.
boosts
.
length
>=
40
)
{
this
.
boosts
.
splice
(
0
,
20
);
this
.
currentPosition
=
0
;
}
if
(
!
this
.
running
)
{
if
(
this
.
currentPosition
===
0
)
{
this
.
recordImpression
(
this
.
currentPosition
,
true
);
}
this
.
start
();
this
.
isVisible
();
}
this
.
feedsService
.
setEndpoint
(
'api/v2/boost/feed'
)
.
setParams
({
rating
:
this
.
rating
,
})
.
setLimit
(
10
)
.
setOffset
(
0
)
.
fetch
();
}
catch
(
e
)
{
if
(
e
&&
e
.
message
)
{
console
.
warn
(
e
);
...
...
@@ -139,61 +133,7 @@ export class NewsfeedBoostRotatorComponent {
this
.
inProgress
=
false
;
return
true
;
}
/**
* Load newsfeed
*/
loadLegacy
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
this
.
inProgress
)
{
return
reject
(
false
);
}
this
.
inProgress
=
true
;
if
(
this
.
storage
.
get
(
'boost:offset:rotator'
))
{
this
.
offset
=
this
.
storage
.
get
(
'boost:offset:rotator'
);
}
let
show
=
'all'
;
if
(
!
this
.
channel
||
!
this
.
channel
.
merchant
)
{
show
=
'points'
;
}
this
.
client
.
get
(
'api/v1/boost/fetch/newsfeed'
,
{
limit
:
10
,
rating
:
this
.
rating
,
offset
:
this
.
offset
,
show
:
show
})
.
then
((
response
:
any
)
=>
{
if
(
!
response
.
boosts
)
{
this
.
inProgress
=
false
;
return
reject
(
false
);
}
this
.
boosts
=
this
.
boosts
.
concat
(
response
.
boosts
);
if
(
this
.
boosts
.
length
>=
40
)
{
this
.
boosts
.
splice
(
0
,
20
);
this
.
currentPosition
=
0
;
}
if
(
!
this
.
running
)
{
if
(
this
.
currentPosition
===
0
)
{
this
.
recordImpression
(
this
.
currentPosition
,
true
);
}
this
.
start
();
this
.
isVisible
();
}
this
.
offset
=
response
[
'load-next'
];
this
.
storage
.
set
(
'boost:offset:rotator'
,
this
.
offset
);
this
.
inProgress
=
false
;
return
resolve
(
true
);
})
.
catch
((
e
)
=>
{
this
.
inProgress
=
false
;
return
reject
();
});
});
}
onExplicitChanged
(
value
:
boolean
)
{
this
.
load
();
}
...
...
@@ -292,11 +232,11 @@ export class NewsfeedBoostRotatorComponent {
}
async
next
()
{
this
.
activities
.
toArray
()[
this
.
currentPosition
].
hide
();
//
this.activities.toArray()[this.currentPosition].hide();
if
(
this
.
currentPosition
+
1
>
this
.
boosts
.
length
-
1
)
{
//this.currentPosition = 0;
try
{
await
this
.
load
();
this
.
feedsService
.
loadMore
();
this
.
currentPosition
++
;
}
catch
(
e
)
{
this
.
currentPosition
=
0
;
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/feeds/sorted.component.html
View file @
94ed6cc6
...
...
@@ -30,7 +30,7 @@
</ng-container>
<m-newsfeed
__entity
[
entity
]="
entity
"
[
entity
]="
entity
|
async
"
[
slot
]="
i
+
1
"
></m-newsfeed
__entity
>
</ng-container>
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/feeds/sorted.component.ts
View file @
94ed6cc6
...
...
@@ -66,7 +66,7 @@ export class NewsfeedSortedComponent implements OnInit, OnDestroy {
protected
newsfeedService
:
NewsfeedService
,
protected
topbarHashtagsService
:
TopbarHashtagsService
,
protected
newsfeedHashtagSelectorService
:
NewsfeedHashtagSelectorService
,
p
rotected
feedsService
:
FeedsService
,
p
ublic
feedsService
:
FeedsService
,
protected
featuresService
:
FeaturesService
,
protected
clientMetaService
:
ClientMetaService
,
@
SkipSelf
()
injector
:
Injector
,
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/feeds/subscribed.component.html
View file @
94ed6cc6
...
...
@@ -18,7 +18,7 @@
<minds-activity
class=
"mdl-card m-border item"
[
object
]="
activity
"
[
object
]="
activity
|
async
"
[
boostToggle
]="
activity
.
boostToggle
"
(
delete
)="
delete
(
activity
)"
[
showRatingToggle
]="
true
"
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/feeds/subscribed.component.ts
View file @
94ed6cc6
...
...
@@ -65,7 +65,7 @@ export class NewsfeedSubscribedComponent {
private
storage
:
Storage
,
private
context
:
ContextService
,
protected
featuresService
:
FeaturesService
,
p
rotected
feedsService
:
FeedsService
,
p
ublic
feedsService
:
FeedsService
,
protected
newsfeedService
:
NewsfeedService
,
protected
clientMetaService
:
ClientMetaService
,
@
SkipSelf
()
injector
:
Injector
,
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/feeds/tiles.component.html
View file @
94ed6cc6
...
...
@@ -2,8 +2,9 @@
[
class
.
m-border
]="
entities
&&
entities
.
length
"
[
class
.
m-newsfeed__tiles--has-elements
]="
entities
&&
entities
.
length
"
>
<ng-container
*
ngFor=
"let entity$ of entities"
>
<a
*
ng
For=
"let entity of entities
"
*
ng
If=
"(entity$ | async) as entity
"
class=
"m-newsfeed-tiles__Tile"
[
ngClass
]="{
'
m-newsfeed-tiles__Tile--is-mature
'
:
attachment
.
shouldBeBlurred
(
entity
)
}"
[
routerLink
]="['/
newsfeed
',
entity
.
guid
]"
...
...
@@ -12,4 +13,5 @@
<i
*
ngIf=
"attachment.shouldBeBlurred(entity)"
class=
"material-icons mature-icon"
>
explicit
</i>
<i
*
ngIf=
"isUnlisted(entity)"
class=
"material-icons unlisted-icon"
>
visibility_off
</i>
</a>
</ng-container>
</div>
This diff is collapsed.
Click to expand it.
src/app/modules/newsfeed/single/single.component.ts
View file @
94ed6cc6
import
{
Component
,
Injector
,
SkipSelf
}
from
'@angular/core'
;
import
{
Component
,
Injector
,
SkipSelf
,
EventEmitter
}
from
'@angular/core'
;
import
{
Router
,
ActivatedRoute
}
from
'@angular/router'
;
import
{
Subscription
}
from
'rxjs'
;
import
{
first
}
from
'rxjs/operators'
;
import
{
Session
}
from
'../../../services/session'
;
import
{
ContextService
}
from
'../../../services/context.service'
;
...
...
@@ -74,7 +75,11 @@ export class NewsfeedSingleComponent {
this
.
loadFromFeedsService
(
guid
)
:
this
.
loadLegacy
(
guid
);
fetchSingleGuid
.
then
((
activity
:
any
)
=>
{
fetchSingleGuid
.
subscribe
((
activity
:
any
)
=>
{
if
(
activity
===
null
)
{
return
;
// Not yet loaded
}
this
.
activity
=
activity
;
switch
(
this
.
activity
.
subtype
)
{
...
...
@@ -104,30 +109,30 @@ export class NewsfeedSingleComponent {
}
else
{
this
.
context
.
reset
();
}
})
.
catch
(
e
=>
{
},
err
=>
{
this
.
inProgress
=
false
;
if
(
e
.
status
===
0
)
{
if
(
e
rr
.
status
===
0
)
{
this
.
error
=
'Sorry, there was a timeout error.'
;
}
else
{
this
.
error
=
'Sorry, we couldn
\'
t load the activity'
;
}
});
});
}
async
loadFromFeedsService
(
guid
:
string
)
{
const
activity
=
await
this
.
entitiesService
.
single
(
guid
);
loadFromFeedsService
(
guid
:
string
)
{
return
this
.
entitiesService
.
single
(
guid
);
}
if
(
!
activity
)
{
throw
new
Error
(
'Activity not found'
);
}
loadLegacy
(
guid
:
string
)
{
const
fakeEmitter
=
new
EventEmitter
();
return
activity
;
}
this
.
client
.
get
(
'api/v1/newsfeed/single/'
+
guid
,
{},
{
cache
:
true
})
.
then
((
response
:
any
)
=>
{
fakeEmitter
.
next
(
response
.
activity
);
});
async
loadLegacy
(
guid
:
string
)
{
return
(
<
any
>
await
this
.
client
.
get
(
'api/v1/newsfeed/single/'
+
guid
,
{},
{
cache
:
true
})).
activity
;
return
fakeEmitter
;
}
delete
(
activity
)
{
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/settings/blocked-channels/blocked-channels.component.html
View file @
94ed6cc6
...
...
@@ -2,7 +2,7 @@
<h4
i18n
>
Blocked Channels
</h4>
<div
class=
"m-settingsBlockedChannels__List"
>
<div
*
ngFor=
"let channel of channels"
class=
"m-settingsBlockedChannels__Channel m-border"
>
<div
*
ngFor=
"let channel of channels
| async
"
class=
"m-settingsBlockedChannels__Channel m-border"
>
<div
class=
"m-settingsBlockedChannelsChannel__Avatar"
>
<a
[
routerLink
]="['/',
channel
.
username
]"
>
<img
[
src
]="
getChannelIcon
(
channel
)"
/>
...
...
@@ -33,7 +33,7 @@
<infinite-scroll
distance=
"25%"
(
load
)="
load
()"
(
load
)="
load
More
()"
[
moreData
]="
moreData
"
[
inProgress
]="
inProgress
"
>
</infinite-scroll>
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/settings/blocked-channels/blocked-channels.component.ts
View file @
94ed6cc6
import
{
ChangeDetectionStrategy
,
ChangeDetectorRef
,
Component
,
OnInit
}
from
"@angular/core"
;
import
{
tap
,
filter
,
switchMap
}
from
'rxjs/operators'
;
import
{
BlockListService
}
from
"../../../common/services/block-list.service"
;
import
{
EntitiesService
}
from
"../../../common/services/entities.service"
;
import
{
Client
}
from
"../../../services/api/client"
;
...
...
@@ -11,7 +12,7 @@ import { Client } from "../../../services/api/client";
export
class
SettingsBlockedChannelsComponent
implements
OnInit
{
blockedGuids
:
any
[]
=
[];
channels
:
any
[]
=
[]
;
channels
;
offset
:
number
=
0
;
...
...
@@ -30,46 +31,30 @@ export class SettingsBlockedChannelsComponent implements OnInit {
ngOnInit
()
{
this
.
load
(
true
);
this
.
channels
=
this
.
blockListService
.
blocked
.
pipe
(
tap
(()
=>
{
this
.
inProgress
=
true
;
this
.
moreData
=
false
;
// Support pagination in the future
}),
filter
(
list
=>
list
.
length
>
0
),
switchMap
(
async
guids
=>
{
const
response
:
any
=
await
this
.
entitiesService
.
fetch
(
guids
);
return
response
.
entities
;
}),
tap
((
blocked
)
=>
{
this
.
inProgress
=
false
;
})
);
}
async
load
(
refresh
:
boolean
=
false
)
{
const
limit
=
24
;
if
(
!
refresh
&&
this
.
inProgress
)
{
return
false
;
}
try
{
this
.
inProgress
=
true
;
if
(
refresh
)
{
this
.
blockedGuids
=
[];
this
.
channels
=
[];
this
.
offset
=
0
;
this
.
moreData
=
true
;
}
if
(
!
this
.
offset
)
{
this
.
blockedGuids
=
(
await
this
.
blockListService
.
getList
())
||
[];
}
const
next
=
this
.
offset
+
limit
;
const
guids
=
this
.
blockedGuids
.
slice
(
this
.
offset
,
next
);
const
channels
=
(
await
this
.
entitiesService
.
fetch
(
guids
))
||
[];
if
(
!
channels
.
length
)
{
this
.
moreData
=
false
;
}
this
.
channels
.
push
(...
channels
);
this
.
offset
=
next
;
}
catch
(
e
)
{
this
.
moreData
=
false
;
}
if
(
this
.
inProgress
)
return
;
this
.
blockListService
.
fetch
();
// Get latest
}
this
.
inProgress
=
false
;
this
.
detectChanges
();
loadMore
()
{
// Implement soon
}
getChannelIcon
(
channel
)
{
...
...
This diff is collapsed.
Click to expand it.
src/app/services/providers.ts
View file @
94ed6cc6
...
...
@@ -201,12 +201,12 @@ export const MINDS_PROVIDERS : any[] = [
{
provide
:
BlockListService
,
useFactory
:
BlockListService
.
_
,
deps
:
[
Client
,
Session
],
deps
:
[
Client
,
Session
,
Storage
],
},
{
provide
:
EntitiesService
,
useFactory
:
EntitiesService
.
_
,
deps
:
[
Client
],
deps
:
[
Client
,
BlockListService
],
},
{
provide
:
FeedsService
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment