@@ -38,6 +38,9 @@ Space::Space(SpacesManager *spacesManager, const OpenAPI::OAIDrive &drive, const
38
38
, _image(new SpaceImage(this ))
39
39
, _hasManyPersonalSpaces(hasManyPersonalSpaces)
40
40
{
41
+ // todo future refactoring: get this setDrive out of the ctr since it potentially kicks off a job for the SpaceImage before the Space is fully constructed
42
+ // propose removing the drive arg from the ctr completely, and moving the call to setDrive to the spacesmanager such that any call to
43
+ // "new" space is immediately followed by setDrive.
41
44
setDrive (drive);
42
45
connect (_image, &SpaceImage::imageChanged, this , &Space::imageChanged);
43
46
}
@@ -49,51 +52,21 @@ OpenAPI::OAIDrive Space::drive() const
49
52
50
53
void Space::setDrive (const OpenAPI::OAIDrive &drive)
51
54
{
52
- _drive = drive;
53
- _image->update ();
54
- }
55
55
56
- SpaceImage::SpaceImage (Space *space)
57
- : QObject(space)
58
- , _space(space)
59
- {
60
- update ();
61
- }
56
+ // first config naturally has an empty drive - reality check that updated drives are always valid
57
+ Q_ASSERT (drive.isValid ());
62
58
63
- QIcon SpaceImage::image () const
64
- {
65
- if (_image.isNull ()) {
66
- return Resources::getCoreIcon (QStringLiteral (" space" ));
67
- }
68
- return _image;
69
- }
59
+ QString curTag = _drive.getRoot ().getETag ();
60
+ QString newTag = drive.getRoot ().getETag ();
61
+ Q_ASSERT (!newTag.isEmpty ());
62
+ // the tag should change when the space is edited on the server. I verified that it changes on space rename as well
63
+ // as on changing the space image so we may have further wrinkles if there is an error in logic server side, but for now
64
+ // we want to reduce updates to "only when something changed" else everything is auto-refreshed periodically (eg every 30s)
65
+ if (curTag == newTag)
66
+ return ;
70
67
71
- QUrl SpaceImage::qmlImageUrl () const
72
- {
73
- if (!_image.isNull ()) {
74
- return QUrl (QStringLiteral (" image://space/%1/%2" ).arg (etag (), _space->id ()));
75
- } else {
76
- // invalid space id to display the placeholder
77
- return QUrl (QStringLiteral (" image://space/placeholder" ));
78
- }
79
- }
80
-
81
- void SpaceImage::update ()
82
- {
83
- const auto &special = _space->drive ().getSpecial ();
84
- const auto img = std::find_if (special.cbegin (), special.cend (), [](const auto &it) { return it.getSpecialFolder ().getName () == QLatin1String (" image" ); });
85
- if (img != special.cend ()) {
86
- _url = QUrl (img->getWebDavUrl ());
87
- _etag = Utility::normalizeEtag (img->getETag ());
88
- auto job = _space->_spaceManager ->account ()->resourcesCache ()->makeGetJob (_url, {}, _space);
89
- QObject::connect (job, &SimpleNetworkJob::finishedSignal, _space, [job, this ] {
90
- if (job->httpStatusCode () == 200 ) {
91
- _image = job->asIcon ();
92
- Q_EMIT imageChanged ();
93
- }
94
- });
95
- job->start ();
96
- }
68
+ _drive = drive;
69
+ _image->update ();
97
70
}
98
71
99
72
QString Space::displayName () const
@@ -143,3 +116,61 @@ QUrl Space::webdavUrl() const
143
116
{
144
117
return QUrl (_drive.getRoot ().getWebDavUrl ());
145
118
}
119
+
120
+ SpaceImage::SpaceImage (Space *space)
121
+ : QObject(space)
122
+ , _space(space)
123
+ {
124
+ }
125
+
126
+ QIcon SpaceImage::image () const
127
+ {
128
+ if (_image.isNull ()) {
129
+ return Resources::getCoreIcon (QStringLiteral (" space" ));
130
+ }
131
+ return _image;
132
+ }
133
+
134
+ QUrl SpaceImage::qmlImageUrl () const
135
+ {
136
+ if (!_image.isNull ()) {
137
+ return QUrl (QStringLiteral (" image://space/%1/%2" ).arg (etag (), _space->id ()));
138
+ } else {
139
+ // invalid space id to display the placeholder
140
+ return QUrl (QStringLiteral (" image://space/placeholder" ));
141
+ }
142
+ }
143
+
144
+ void SpaceImage::update ()
145
+ {
146
+ const auto &special = _space->drive ().getSpecial ();
147
+ const auto img = std::find_if (special.cbegin (), special.cend (), [](const auto &it) { return it.getSpecialFolder ().getName () == QLatin1String (" image" ); });
148
+ if (img != special.cend ())
149
+ {
150
+ // ssue 12057: verified the image etag does change when the space's icon has been updated via the web interface
151
+ // check the etag before updating the members and creating the job. This should eliminate *many* pointless resource jobs which
152
+ // will exacerbate whatever is making the app crash when the space tries to clean up it's child jobs and one is already gone
153
+ QString newEtag = Utility::normalizeEtag (img->getETag ());
154
+ if (_etag == newEtag)
155
+ return ;
156
+
157
+ _etag = newEtag;
158
+ _url = QUrl (img->getWebDavUrl ());
159
+ // issue 12057: I am leaving the space as the parent of the job just to avoid having confusion about "new" destructor crashes. At least
160
+ // we'll get any future crashes on the space still. I don't think that changing the parent is going to eliminate the associate crash - save
161
+ // this for a future refactoring
162
+ auto job = _space->_spaceManager ->account ()->resourcesCache ()->makeGetJob (_url, {}, _space);
163
+
164
+ // TODO: next problem = this routine is correctly run when the icon has changed on the server, but the icon in the gui does not get refreshed!
165
+ // The icon IS in the app cache, so it seems to have been brought back from the server correctly, but it is not shown until restart
166
+ // I did have a quick look at Resources::getCoreIcon - that is used in the SpaceImage::image function. Also sus is that I can't find any slot
167
+ // for the imageChanged signal but I think this may be connected in qml via the associated space image property.
168
+ QObject::connect (job, &SimpleNetworkJob::finishedSignal, _space, [job, this ] {
169
+ if (job->httpStatusCode () == 200 ) {
170
+ _image = job->asIcon ();
171
+ Q_EMIT imageChanged ();
172
+ }
173
+ });
174
+ job->start ();
175
+ }
176
+ }
0 commit comments